X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=skyquake%2Fplugins%2Flogging%2Fsrc%2FloggingGeneral.jsx;fp=skyquake%2Fplugins%2Flogging%2Fsrc%2FloggingGeneral.jsx;h=dd04a57a70a9aeabe3892e88e98a992bc8ba4af0;hb=e29efc315df33d546237e270470916e26df391d6;hp=0000000000000000000000000000000000000000;hpb=9c5e457509ba5a1822c316635c6308874e61b4b9;p=osm%2FUI.git diff --git a/skyquake/plugins/logging/src/loggingGeneral.jsx b/skyquake/plugins/logging/src/loggingGeneral.jsx new file mode 100644 index 000000000..dd04a57a7 --- /dev/null +++ b/skyquake/plugins/logging/src/loggingGeneral.jsx @@ -0,0 +1,397 @@ + /* + * + * Copyright 2016 RIFT.IO Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import React from 'react'; +import _ from 'lodash'; +import './logging.scss'; + +import Button from 'widgets/button/rw.button.js'; +import DashboardCard from 'widgets/dashboard_card/dashboard_card.jsx'; +import ScreenLoader from 'widgets/screen-loader/screenLoader.jsx'; + +import LoggingActions from './loggingActions.js'; +import LoggingStore from './loggingStore.js'; +import LoggingNav from './loggingNav.jsx'; + +import CategorySeverityGrid from './categorySeverityGrid.jsx'; +import DenyEventsEditGroup from './denyEventsEditGroup.jsx'; +import {DropList, RadioButtonGroup, CardSection } from './loggingWidgets.jsx'; + +import Crouton from 'react-crouton'; +import 'style/common.scss'; + + +class DefaultCategorySeverityPanel extends React.Component { + + render() { + const {defaultSeverities, severities, ...props } = this.props; + return ( + + + + ); + } +} + + +class LoggingEventsPanel extends React.Component { + + handleChangeAllowDuplicateEvents(e) { + console.log("LoggingEventsPanel.handleChangeAllowDuplicateEvents:"); + console.log("- e.currentTarget.value=", e.currentTarget.value); + console.log("- e.currentTarget=", e.currentTarget); + + // NOTE, we may want to generalize our string to boolean convert/compare + let allowFlag = (e.currentTarget.value == 'true'); + LoggingStore.updateAllowDuplicateEvents(allowFlag); + } + + handleAddDenyEvent(e) { + LoggingStore.addDenyEvent(null); + } + + render() { + const {allowDuplicateEvents, eventIDs, radioItems, ...props} = this.props; + let self = this; + let selectedIndex = allowDuplicateEvents ? 0 :1; + + return ( + + +
Allow duplicate events
+ +
+ + +
+ +
+
+
+ ); + } +} +LoggingEventsPanel.defaultProps = { + radioItems: [ + { label: "Allow", value: true }, + { label: "Deny", value: false } + ], + allowDuplicateEvents: false, + eventIDs: [] +} + +/** + * + */ +class LoggingGeneralDetailsPanel extends React.Component { + constructor(props) { + super(props); + this.state = { + syslogViewerURL: props.syslogViewerURL + }; + } + + componentWillReceiveProps(props) { + this.setState({ + syslogViewerURL: props.syslogViewerURL + }); + } + + handleUpdateDetailTextField(fieldName) { + let self = this; + return function(e) { + let state = {}; + state[fieldName] = e.target.value; + self.setState(state); + } + } + + handleUpdateSyslogViewerURL(e) { + LoggingStore.updateSyslogViewerURL(e.target.value); + } + handleOpenSysLogViewerURL(e) { + e.preventDefault(); + window.open(this.state.syslogViewerURL); + } + + render() { + return ( + +
+ +
+ +
+ Go + +
+
+
+
+ ); + } +} +LoggingGeneralDetailsPanel.defaultProps = { + syslogViewerURL: "" +} + + + +/** + * Page level class renders the general logging config page of three panels: + * 1. Default severity per category + * 2. Events configuration + * 3. Syslog viewer setting, launch + */ +export default class LoggingGeneral extends React.Component { + + constructor(props) { + super(props); + this.state = LoggingStore.getState(); + LoggingStore.listen(this.storeListener); + this.state.validateErrorEvent = 0; + this.state.validateErrorMsg = ''; + this.state.isLoading = true; + this.state.showDumpStateButton = false; + } + + storeListener = (state) => { + this.setState(state); + } + + getData() { + LoggingStore.getLoggingConfig(); + this.setState({ + isLoading: _.isEmpty(this.state.loggingConfig) + }); + } + componentWillUnmount = () => { + LoggingStore.unlisten(this.storeListener); + } + + componentDidMount() { + //console.log("LoggingGeneral.componentDidMount called"); + this.getData(); + } + + componentDidUpdate() { + //console.log("LoggingGeneral.componentDidUpdate called"); + } + + handleSave = (formData, e) => { + e.preventDefault(); + + if (this.validateData()) { + this.setState({ + isLoading: true + }); + LoggingStore.updateLoggingConfig( + this.collectNulledCategories( + this.state.initialLoggingConfig, + this.state.loggingConfig), + this.removeCategoryNulls( + this.state.loggingConfig + ) + ); + } else { + console.log("LoggingGeneral.handleSave failed validation"); + } + this.context.router.push({pathname: ''}); + } + removeCategoryNulls(config) { + let cleanConfig = _.cloneDeep(config); + let cleanSeverities = []; + config.defaultSeverities.map(function(d) { + if (d.severity) { + cleanSeverities.push(d); + } + }); + cleanConfig.defaultSeverities = cleanSeverities; + return cleanConfig; + } + collectNulledCategories(oldCat, newCat) { + let nulledCategories = []; + let newSeverities = newCat.defaultSeverities; + let oldSeverities = oldCat.defaultSeverities; + newSeverities.map(function(c, i) { + if(!c.severity) { + if(oldSeverities[i].severity) { + //verify that categories are the same + if(oldSeverities[i].category == c.category) { + nulledCategories.push({category: c.category}) + } + } + } + }); + return nulledCategories; + } + validateData() { + + function isEventIdValid(eventID) { + // Return true if null, empty string or a number, else return false + if (!eventID || eventID.length == 0) { + return true; + } else { + return (isNaN(+eventID)) ? false : true; + } + } + + let invalidEventIDs = []; + this.state.loggingConfig.denyEventIDs.forEach( + function(eventID, index) { + if (!isEventIdValid(eventID)) { + invalidEventIDs.push({ eventID: eventID, index: index}); + } + }) + if (invalidEventIDs.length > 0) { + console.log("invalidEvents = ", invalidEventIDs); + if (invalidEventIDs.length == 1) { + let msg = 'There is ' + invalidEventIDs.length + ' invalid event ID'; + this.validateError(msg); + } else { + let msg = 'There are ' + invalidEventIDs.length + ' invalid event IDs'; + this.validateError(msg); + } + // How should we identify each invalid value? + + return false; + } else { + return true; + } + } + handleCancel = (e) => { + console.log("LoggingGeneral.handleCancel clicked"); + e.preventDefault(); + // TODO: restore original state + LoggingStore.resetLoggingConfigData(); + this.context.router.push({pathname: ''}); + + } + + validateError = (msg) => { + this.setState({ + validateErrorEvent: true, + validateErrorMsg: msg + }); + } + validateReset = () => { + this.setState({ + validateErrorEvent: false + }); + } + returnCrouton = () => { + return