diff --git a/package-lock.json b/package-lock.json index b1fb78b..e66ec73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4178,12 +4178,20 @@ "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.3.1", + "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.5.0" + }, + "dependencies": { + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + } } }, "chownr": { @@ -7883,9 +7891,9 @@ "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==" }, "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, "hpack.js": { "version": "2.1.6", @@ -10608,9 +10616,9 @@ }, "dependencies": { "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", + "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==" } } }, @@ -14077,14 +14085,6 @@ "react-display-name": "^0.2.0" } }, - "react-grid-system": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/react-grid-system/-/react-grid-system-7.1.2.tgz", - "integrity": "sha512-5XKVkevZWDITlpivmK8iQcmdfj7cuIzPlcejOmhRK9FGdNsFsRHXO2H7zaKfssJ2CymQXOTvU0ZN8TX9BPBr+g==", - "requires": { - "prop-types": "^15.7.2" - } - }, "react-immutable-proptypes": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", @@ -14122,39 +14122,6 @@ "react-base16-styling": "^0.6.0", "react-lifecycles-compat": "^3.0.4", "react-textarea-autosize": "^8.3.2" - }, - "dependencies": { - "fbemitter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-3.0.0.tgz", - "integrity": "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==", - "requires": { - "fbjs": "^3.0.0" - } - }, - "fbjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.0.tgz", - "integrity": "sha512-dJd4PiDOFuhe7vk4F80Mba83Vr2QuK86FoxtgPmzBqEJahncp+13YCmfoa53KHCo6OnlXLG7eeMWPfB5CrpVKg==", - "requires": { - "cross-fetch": "^3.0.4", - "fbjs-css-vars": "^1.0.0", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - } - }, - "flux": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flux/-/flux-4.0.1.tgz", - "integrity": "sha512-emk4RCvJ8RzNP2lNpphKnG7r18q8elDYNAPx7xn+bDeOIo9FFfxEfIQ2y6YbQNmnsGD3nH1noxtLE64Puz1bRQ==", - "requires": { - "fbemitter": "^3.0.0", - "fbjs": "^3.0.0" - } - } } }, "react-lifecycles-compat": { @@ -14403,9 +14370,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", - "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", + "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -16226,11 +16193,6 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, "style-loader": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", @@ -16934,11 +16896,6 @@ } } }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "tsutils": { "version": "3.20.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz", @@ -17872,8 +17829,7 @@ }, "ssri": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "resolved": "", "requires": { "figgy-pudding": "^3.5.1" } diff --git a/package.json b/package.json index c0a5d39..3b53434 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@fortawesome/fontawesome-svg-core": "^1.2.35", "@fortawesome/free-solid-svg-icons": "^5.15.3", "@fortawesome/react-fontawesome": "^0.1.14", + "@rjsf/core": "^2.5.1", "babel-runtime": "^6.26.0", "bootstrap": "^4.6.0", "classnames": "^2.3.1", @@ -42,7 +43,6 @@ "react-dnd-html5-backend": "^14.0.0", "react-dom": "^17.0.2", "react-fullscreenable": "^2.5.1-0", - "react-grid-system": "^7.1.2", "react-json-view": "^1.21.3", "react-notification-system": "^0.4.0", "react-rnd": "^10.2.4", diff --git a/src/common/dialogs/new-dialog.js b/src/common/dialogs/new-dialog.js index 8c7b44f..461f9ac 100644 --- a/src/common/dialogs/new-dialog.js +++ b/src/common/dialogs/new-dialog.js @@ -38,8 +38,6 @@ class NewDialog extends React.Component { } handleChange(e) { - console.log(e) - this.setState({ [e.target.id]: e.target.value }); } diff --git a/src/componentconfig/edit-config.js b/src/componentconfig/edit-config.js index 2ee19ec..63d9ded 100644 --- a/src/componentconfig/edit-config.js +++ b/src/componentconfig/edit-config.js @@ -16,11 +16,14 @@ ******************************************************************************/ import React from 'react'; -import { Form } from 'react-bootstrap'; +import Form from "@rjsf/core"; + +import { Form as BForm } from 'react-bootstrap'; import { Multiselect } from 'multiselect-react-dropdown' import Dialog from '../common/dialogs/dialog'; import ParametersEditor from '../common/parameters-editor'; + class EditConfigDialog extends React.Component { valid = false; @@ -30,6 +33,8 @@ class EditConfigDialog extends React.Component { name: '', icID: '', startParameters: {}, + formData: {}, + startparamTemplate: null, selectedFiles: [] // list of selected files {name, id}, this is not the fileIDs list of the config! }; } @@ -44,21 +49,21 @@ class EditConfigDialog extends React.Component { if (this.state.icID !== '' && this.props.config.icID !== parseInt(this.state.icID)) { data.icID = parseInt(this.state.icID, 10); } - if(this.state.startParameters !== {} && - JSON.stringify(this.props.config.startParameters) !== JSON.stringify(this.state.startParameters)){ + if (this.state.startParameters !== {} && + JSON.stringify(this.props.config.startParameters) !== JSON.stringify(this.state.startParameters)) { data.startParameters = this.state.startParameters; } let IDs = [] - for(let e of this.state.selectedFiles){ + for (let e of this.state.selectedFiles) { IDs.push(e.id) } - if(this.props.config.fileIDs !== null && this.props.config.fileIDs !== undefined) { + if (this.props.config.fileIDs !== null && this.props.config.fileIDs !== undefined) { if (JSON.stringify(IDs) !== JSON.stringify(this.props.config.fileIDs)) { data.fileIDs = IDs; } } - else{ + else { data.fileIDs = IDs } @@ -68,6 +73,9 @@ class EditConfigDialog extends React.Component { } else { this.props.onClose(); } + + this.setState({ startparamTemplate: null }) + this.valid = false } handleChange(e) { @@ -75,9 +83,28 @@ class EditConfigDialog extends React.Component { this.valid = this.isValid() } + changeIC(id) { + let schema = null; + if (this.props.ics) { + let currentIC = this.props.ics.find(ic => ic.id === parseInt(id, 10)); + if (currentIC) { + if (currentIC.startparameterschema.hasOwnProperty('type')) { + schema = currentIC.startparameterschema; + } + } + } + + this.setState({ + icID: id, + startparamTemplate: schema, + }); + + this.valid = this.isValid() + } + handleParameterChange(data) { if (data) { - this.setState({startParameters: data}); + this.setState({ startParameters: data }); } this.valid = this.isValid() } @@ -101,24 +128,39 @@ class EditConfigDialog extends React.Component { // determine list of selected files incl id and filename let selectedFiles = [] - if(this.props.config.fileIDs !== null && this.props.config.fileIDs !== undefined) { + if (this.props.config.fileIDs !== null && this.props.config.fileIDs !== undefined) { for (let selectedFileID of this.props.config.fileIDs) { for (let file of this.props.files) { if (file.id === selectedFileID) { - selectedFiles.push({name: file.name, id: file.id}) + selectedFiles.push({ name: file.name, id: file.id }) } } } } + let schema = null; + if (this.props.ics && this.props.config.icID) { + let currentIC = this.props.ics.find(ic => ic.id === parseInt(this.props.config.icID, 10)); + if (currentIC) { + if (currentIC.startparameterschema.hasOwnProperty('type')) { + schema = currentIC.startparameterschema; + } + } + } + this.setState({ name: this.props.config.name, icID: this.props.config.icID, startParameters: this.props.config.startParameters, selectedFiles: selectedFiles, + startparamTemplate: schema, }); } + handleFormChange({formData}) { + this.setState({formData: formData, startParameters: formData}) + this.valid = this.isValid() + } render() { const ICOptions = this.props.ics.map(s => @@ -126,9 +168,9 @@ class EditConfigDialog extends React.Component { ); let configFileOptions = []; - for(let file of this.props.files) { + for (let file of this.props.files) { configFileOptions.push( - {name: file.name, id: file.id} + { name: file.name, id: file.id } ); } @@ -141,29 +183,29 @@ class EditConfigDialog extends React.Component { onReset={() => this.resetState()} valid={this.valid} > -
- - Name - + + Name + this.handleChange(e)} /> - - + + - - Infrastructure Component - + Infrastructure Component + this.handleChange(e)} + onChange={(e) => this.changeIC(e.target.value)} > {ICOptions} - - + + - - Start Parameters +
+ Start Parameters + + {!this.state.startparamTemplate ? this.handleParameterChange(data)} - /> -
- + content={this.state.startParameters} + onChange={(data) => this.handleParameterChange(data)} + /> + : <>} + + {this.state.startparamTemplate ? +
this.handleFormChange({formData})} + children={true} // hides submit button + /> + : <> } ); } diff --git a/src/componentconfig/import-config.js b/src/componentconfig/import-config.js index 2b69d9a..c034198 100644 --- a/src/componentconfig/import-config.js +++ b/src/componentconfig/import-config.js @@ -55,7 +55,7 @@ class ImportConfigDialog extends React.Component { loadFile = event => { // get file const file = event.target.files[0]; - if (file.type.match('application/json') === false) { + if (!file.type.match('application/json')) { return; } diff --git a/src/ic/edit-ic.js b/src/ic/edit-ic.js index be77e27..68707bd 100644 --- a/src/ic/edit-ic.js +++ b/src/ic/edit-ic.js @@ -16,8 +16,7 @@ ******************************************************************************/ import React from 'react'; -import { Form } from 'react-bootstrap'; -import _ from 'lodash'; +import { Form, Col, Row } from 'react-bootstrap'; import Dialog from '../common/dialogs/dialog'; import ParametersEditor from '../common/parameters-editor'; @@ -36,15 +35,15 @@ class EditICDialog extends React.Component { type: '', category: '', managedexternally: false, - startParameterSchema: {}, - properties: {} + startparameterschema: {} }; } + onClose(canceled) { if (canceled === false) { if (this.valid) { - let data = this.props.ic; + let data = JSON.parse(JSON.stringify(this.props.ic)); if (this.state.name != null && this.state.name !== "" && this.state.name !== this.props.ic.name) { data.name = this.state.name; @@ -69,12 +68,8 @@ class EditICDialog extends React.Component { data.category = this.state.category; } - if (this.state.startParameterSchema !== {}) { - data.startParameterSchema = this.state.startParameterSchema; - } - - if (this.state.properties !== {}) { - data.properties = this.state.properties; + if (this.state.startparameterschema !== {}) { + data.startparameterschema = this.state.startparameterschema; } data.managedexternally = this.state.managedexternally; @@ -98,11 +93,7 @@ class EditICDialog extends React.Component { } handleStartParameterSchemaChange(data) { - this.setState({ startParameterSchema: data }); - } - - handlePropertiesChange(data) { - this.setState({ properties: data }); + this.setState({ startparameterschema: data }); } resetState() { @@ -115,11 +106,27 @@ class EditICDialog extends React.Component { description: this.props.ic.description, category: this.props.ic.category, managedexternally: false, - startParameterSchema: this.props.ic.startParameterSchema, - properties: this.props.ic.properties, + startparameterschema: this.props.ic.startparameterschema || {}, }); } + selectStartParamsFile(event) { + const file = event.target.files[0]; + + if (!file.type.match('application/json')) { + console.error("Not a json file. Will not process file '" + file.name + "'.") + return; + } + + let reader = new FileReader(); + reader.readAsText(file); + + reader.onload = event => { + const params = JSON.parse(reader.result); + this.setState({ startparameterschema: params}) + } + }; + render() { let typeOptions = []; switch(this.state.category){ @@ -196,22 +203,23 @@ class EditICDialog extends React.Component { this.handleChange(e)} /> +
- Start parameter schema of IC + + + Start parameter schema of IC + + + this.selectStartParamsFile(event)} /> + + this.handleStartParameterSchemaChange(data)} + disabled={false} /> - - Properties - this.handlePropertiesChange(data)} - /> - + ); diff --git a/src/ic/ic-pages/gateway-villas-node.js b/src/ic/ic-pages/gateway-villas-node.js index 3e09d0f..65baadb 100644 --- a/src/ic/ic-pages/gateway-villas-node.js +++ b/src/ic/ic-pages/gateway-villas-node.js @@ -69,8 +69,6 @@ class GatewayVillasNode extends React.Component { graphURL = this.props.ic.apiurl + "/graph.svg" } - console.log("Villasnode Gateway: ", this.props.ic) - return (
diff --git a/src/ic/ics.js b/src/ic/ics.js index f78b568..0a5b7bc 100644 --- a/src/ic/ics.js +++ b/src/ic/ics.js @@ -100,7 +100,7 @@ class InfrastructureComponents extends Component { services: services, equipment: equipment, numberOfExternalICs, - modalIC: {}, + modalIC: prevState.modalIC || {}, deleteModal: false, icModal: false, selectedICs: prevState.selectedICs || [], @@ -125,6 +125,7 @@ class InfrastructureComponents extends Component { refresh() { if (this.state.editModal || this.state.deleteModal || this.state.icModal){ // do nothing since a dialog is open at the moment + return } else { AppDispatcher.dispatch({ @@ -186,13 +187,9 @@ class InfrastructureComponents extends Component { } closeEditModal(data) { - this.setState({ editModal : false }); + this.setState({ editModal : false, modalIC: {} }); if (data) { - //let ic = this.state.ics[this.state.modalIndex]; - //ic = data; - //this.setState({ ic: ic }); - AppDispatcher.dispatch({ type: 'ics/start-edit', data: data, @@ -203,8 +200,6 @@ class InfrastructureComponents extends Component { closeDeleteModal(confirmDelete){ - this.setState({ deleteModal: false }); - if (confirmDelete === false) { return; } @@ -214,6 +209,8 @@ class InfrastructureComponents extends Component { data: this.state.modalIC, token: this.state.sessionToken, }); + + this.setState({ deleteModal: false, modalIC: {} }); } exportIC(index) { diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 4a3ecbb..a07f3f4 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -22,10 +22,11 @@ import AppDispatcher from '../common/app-dispatcher'; import ScenarioStore from './scenario-store'; import DashboardStore from '../dashboard/dashboard-store'; import WidgetStore from "../widget/widget-store"; -import ConfigStore from '../componentconfig/config-store'; +import ComponentConfigStore from '../componentconfig/config-store'; import SignalStore from '../signal/signal-store' import ResultStore from '../result/result-store' import FileStore from '../file/file-store' +import LoginStore from '../user/login-store' import Table from '../common/table'; import TableColumn from '../common/table-column'; import NewScenarioDialog from './new-scenario'; @@ -38,7 +39,7 @@ import IconButton from '../common/icon-button'; class Scenarios extends Component { static getStores() { - return [ScenarioStore, DashboardStore, WidgetStore, ConfigStore, SignalStore, ResultStore, FileStore]; + return [ScenarioStore, DashboardStore, WidgetStore, ComponentConfigStore, SignalStore, ResultStore, FileStore,LoginStore]; } static calculateState(prevState, props) { @@ -49,7 +50,7 @@ class Scenarios extends Component { return { scenarios: ScenarioStore.getState(), dashboards: DashboardStore.getState(), - configs: ConfigStore.getState(), + configs: ComponentConfigStore.getState(), sessionToken: localStorage.getItem("token"), newModal: false,