From: sebdet Date: Wed, 10 Jul 2019 10:32:36 +0000 (+0200) Subject: Introduce modal X-Git-Tag: 4.1.0~17 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=4946e5b7d80fa1a7baa1c6042100fa1dee24ee31;p=clamp.git Introduce modal Test Modal for Operational policy and use react-router to show it Issue-ID: CLAMP-415 Change-Id: Ie0df5f1085925224076062c7d331dc2f4c72d032 Signed-off-by: sebdet --- diff --git a/ui-react/package.json b/ui-react/package.json index 791ab9df..c6369a3a 100644 --- a/ui-react/package.json +++ b/ui-react/package.json @@ -3,6 +3,7 @@ "version": "0.0.1", "description": "ONAP Clamp Designer UI", "main": "index.js", + "proxy": "http://localhost:8080", "scripts": { "start": "react-scripts start", "build": "react-scripts build", diff --git a/ui-react/src/components/app/LoopUI.js b/ui-react/src/components/app/LoopUI.js index 7de6ad01..d058543a 100644 --- a/ui-react/src/components/app/LoopUI.js +++ b/ui-react/src/components/app/LoopUI.js @@ -31,14 +31,15 @@ import { GlobalClampStyle } from '../../theme/globalStyle.js'; import ClosedLoopSvg from '../loop_viewer/svg/ClosedLoopSvg'; import ClosedLoopLogs from '../loop_viewer/logs/ClosedLoopLogs'; import ClosedLoopStatus from '../loop_viewer/status/ClosedLoopStatus'; +import UserService from '../backend_communication/UserService'; -const ProjectNameStyle = styled.a` +const ProjectNameStyled = styled.a` vertical-align: middle; padding-left: 30px; font-size: 30px; ` -const LoopViewDivStyle = styled.div` +const LoopViewDivStyled = styled.div` height: 90vh; overflow: hidden; margin-left: 10px; @@ -50,52 +51,69 @@ const LoopViewDivStyle = styled.div` border-color: ${props => props.theme.loopViewerHeaderBackgroundColor}; ` -const LoopViewHeaderDivStyle = styled.div` +const LoopViewHeaderDivStyled = styled.div` background-color: ${props => props.theme.loopViewerHeaderBackgroundColor}; padding: 10px 10px; color: ${props => props.theme.loopViewerHeaderFontColor}; ` -const LoopViewBodyDivStyle = styled.div` +const LoopViewBodyDivStyled = styled.div` background-color: ${props => (props.theme.loopViewerBackgroundColor)}; padding: 10px 10px; color: ${props => (props.theme.loopViewerHeaderFontColor)}; height: 95%; ` -const LoopViewLoopNameSpanStyle = styled.span` +const LoopViewLoopNameSpanStyled = styled.span` font-weight: bold; color: ${props => (props.theme.loopViewerHeaderFontColor)}; background-color: ${props => (props.theme.loopViewerHeaderBackgroundColor)}; ` export default class LoopUI extends React.Component { + state = { + userName: null, + loopName: "Empty (NO loop loaded yet)", + }; - loopName="Empty (NO loop loaded yet)"; + constructor() { + super(); + this.getUser = this.getUser.bind(this); + } + + componentDidMount() { + this.getUser(); + } + + getUser() { + UserService.LOGIN().then(user => { + this.setState({userName:user}) + }); + } renderMenuNavBar() { return ( ); } - + renderUserLoggedNavBar() { return ( - Signed in as: {localStorage.getItem('user')} + Signed in as: {this.state.userName} ); } - + renderLogoNavBar() { return ( - CLAMP + CLAMP ); } - + renderNavBar() { return ( @@ -108,34 +126,34 @@ export default class LoopUI extends React.Component { renderLoopViewHeader() { return ( - - Loop Viewer - {this.loopName} - + + Loop Viewer - {this.state.loopName} + ); } renderLoopViewBody() { return ( - + - + ); } renderLoopViewer() { return ( - + {this.renderLoopViewHeader()} {this.renderLoopViewBody()} - + ); } render() { return ( -
+
{this.renderNavBar()} {this.renderLoopViewer()} diff --git a/ui-react/src/components/app/login/BasicAuthLogin.js b/ui-react/src/components/app/login/BasicAuthLogin.js deleted file mode 100644 index 994255cd..00000000 --- a/ui-react/src/components/app/login/BasicAuthLogin.js +++ /dev/null @@ -1,117 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * 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. - * ============LICENSE_END============================================ - * =================================================================== - * - */ -import React from 'react'; -import styled from 'styled-components'; -import LoopService from '../../backend_communication/LoopService'; - -const LoginHeaderStyle = styled.span` - font-size: 20px; - font-weight: bold; - padding-left: 10px; - color: ${props => props.theme.loopViewerHeaderFontColor}; -` -const LoginDivStyle = styled.div` - font-size: 12px; - background-color: ${props => props.theme.loopViewerHeaderBackgroundColor}; - padding: 10px 10px; - color: ${props => props.theme.loopViewerHeaderFontColor}; -` -const LoginSubmitButtonStyle = styled.button` - font-size: 12px; - padding: 5px 10px; - color: ${props => props.theme.loopViewerHeaderFontColor}; - border: 2px solid; - border-radius: 8px; -` -const LoginTextInputStyle = styled.input` - padding: 10px 10px; - margin-left: 20px; - border: 1px solid #ced4da; - border-radius: 3px; - color: ${props => props.theme.loopViewerHeaderFontColor}; -` - -export default class BasicAuthLogin extends React.Component { - constructor(props) { - super(props); - this.handleSubmit = this.handleSubmit.bind(this); - this.handleChange = this.handleChange.bind(this); - console.log('BasicAuthLogin'); - this.state = { - username: '', - password: '', - submitted: 'false' - }; - } - - handleChange(e) { - const { name, value } = e.target; - this.setState({ [name]: value }); - } - - handleSubmit(e) { - e.preventDefault(); - this.setState({ submitted: true }); - const { username, password } = this.state; - LoopService.login(username, password) - .then( - user => { - const { from } = { from: { pathname: "/" } }; - this.props.history.push(from); - }, - error => { - const { from } = { from: { pathname: "/loginFailed" } }; - this.props.history.push(from); - console.log ("Basic login failed"); - } - ); - } - - render() { - const { username, password, submitted} = this.state; - return ( -
- Login -
- - - - {submitted && !username && -
Username is required
- } -
- - - - {submitted && !password && -
Password is required
- } -
- - Login - -
-
- ); - } -} diff --git a/ui-react/src/components/app/login/LoginPage.js b/ui-react/src/components/app/login/LoginPage.js deleted file mode 100644 index 5169435c..00000000 --- a/ui-react/src/components/app/login/LoginPage.js +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * 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. - * ============LICENSE_END============================================ - * =================================================================== - * - */ -import React from 'react'; - -import LoopService from '../../backend_communication/LoopService'; - -export default class LoginPage extends React.Component { - constructor(props) { - super(props); - console.log('LoginPage') - LoopService.login().then( - user => { - const { from } = { from: { pathname: "/" } }; - this.props.history.push(from); - }, - error => { - const { from } = { from: { pathname: "/" } }; - this.props.history.push(from); - console.log ("Certification login failed"); - } - ); - } - render() { - return ( -
-
); -} -} diff --git a/ui-react/src/components/backend_communication/LoopActionService.js b/ui-react/src/components/backend_communication/LoopActionService.js index 027243be..9ce8ff0a 100644 --- a/ui-react/src/components/backend_communication/LoopActionService.js +++ b/ui-react/src/components/backend_communication/LoopActionService.js @@ -20,37 +20,35 @@ * =================================================================== * */ -const clActionService = { - submit +const loopActionService = { + submit }; + function submit(uiAction) { - const cl_name = ""; - console.log("clActionServices perform action: " + uiAction + " closedloopName=" - + cl_name); - const svcAction = uiAction.toLowerCase(); - const svcUrl = "/restservices/clds/v2/loop/" + svcAction + "/" + cl_name; + const cl_name = ""; + console.log("clActionServices perform action: " + uiAction + " closedloopName=" + + cl_name); + const svcAction = uiAction.toLowerCase(); + const svcUrl = "/restservices/clds/v2/loop/" + svcAction + "/" + cl_name; - let options = { - method: 'GET' - }; - return sendRequest (svcUrl, svcAction, options); + let options = { + method: 'GET' + }; + return sendRequest(svcUrl, svcAction, options); } +function sendRequest(svcUrl, svcAction) { + fetch(svcUrl, options) + .then( + response => { + alertService.alertMessage("Action Successful: " + svcAction, 1) + }).error(error => { + alertService.alertMessage("Action Failure: " + svcAction, 2); + return Promise.reject(error); + }); + return response.json(); +}; -function sendRequest (svcUrl, svcAction) { - fetch(svcUrl, options) - .then( - response => { - alertService.alertMessage("Action Successful: " + svcAction, 1) - }).error( error => { - alertService.alertMessage("Action Failure: " + svcAction, 2); - return Promise.reject(error); - }); - - return response.json(); - }); -} - -export default clActionService; +export default loopActionService; \ No newline at end of file diff --git a/ui-react/src/components/backend_communication/LoopCache.js b/ui-react/src/components/backend_communication/LoopCache.js index 7fd20596..2ef83962 100644 --- a/ui-react/src/components/backend_communication/LoopCache.js +++ b/ui-react/src/components/backend_communication/LoopCache.js @@ -20,95 +20,95 @@ * =================================================================== * */ -class LoopCache -{ - constructor(loopJson) { - this.loopJsonCache=loopJson; +class LoopCache { + constructor() { + //this.loopJsonCache=loopJson; + this.loopJsonCache = require('./example.json'); //(with path) } - + updateMsProperties(type, newMsProperties) { - if (newMsProperties["name"] == type) { - for (p in this.loopJsonCache["microServicePolicies"]) { - if (this.loopJsonCache["microServicePolicies"][p]["name"] == type) { - this.loopJsonCache["microServicePolicies"][p] = newMsProperties; - } - } - } - } - - updateGlobalProperties(newGlobalProperties) { - this.loopJsonCache["globalPropertiesJson"] = newGlobalProperties; - } - - updateOpPolicyProperties(newOpProperties) { - this.loopJsonCache["operationalPolicies"] = newOpProperties; - } - - getLoopName() { - return this.loopJsonCache["name"]; - } - - getOperationalPolicyProperty() { - return JSON.parse(JSON.stringify(this.loopJsonCache["operationalPolicies"]["0"]["configurationsJson"])); - } - - getOperationalPolicies() { - return JSON.parse(JSON.stringify(this.loopJsonCache["operationalPolicies"])); - } - - getGlobalProperty() { - return JSON.parse(JSON.stringify(this.loopJsonCache["globalPropertiesJson"])); - } - - getDeploymentProperties() { - return JSON.parse(JSON.stringify(this.loopJsonCache["globalPropertiesJson"]["dcaeDeployParameters"])); - } - - getMsJson(type) { - var msProperties = this.loopJsonCache["microServicePolicies"]; - for (p in msProperties) { - if (msProperties[p]["name"] == type) { - return JSON.parse(JSON.stringify(msProperties[p])); - } - } - return null; - } - - getMsProperty(type) { - var msProperties = this.loopJsonCache["microServicePolicies"]; - for (p in msProperties) { - if (msProperties[p]["name"] == type) { - if (msProperties[p]["properties"] !== null && msProperties[p]["properties"] !== undefined) { - return JSON.parse(JSON.stringify(msProperties[p]["properties"])); - } - } - } - return null; - } - - getMsUI(type) { - var msProperties = this.loopJsonCache["microServicePolicies"]; - for (p in msProperties) { - if (msProperties[p]["name"] == type) { - return JSON.parse(JSON.stringify(msProperties[p]["jsonRepresentation"])); - } - } - return null; - } - - getResourceDetailsVfProperty() { + if (newMsProperties["name"] == type) { + for (var policy in this.loopJsonCache["microServicePolicies"]) { + if (this.loopJsonCache["microServicePolicies"][policy]["name"] == type) { + this.loopJsonCache["microServicePolicies"][policy] = newMsProperties; + } + } + } + } + + updateGlobalProperties(newGlobalProperties) { + this.loopJsonCache["globalPropertiesJson"] = newGlobalProperties; + } + + updateOpPolicyProperties(newOpProperties) { + this.loopJsonCache["operationalPolicies"] = newOpProperties; + } + + getLoopName() { + return this.loopJsonCache["name"]; + } + + getOperationalPolicyProperty() { + return JSON.parse(JSON.stringify(this.loopJsonCache["operationalPolicies"]["0"]["configurationsJson"])); + } + + getOperationalPolicies() { + return JSON.parse(JSON.stringify(this.loopJsonCache["operationalPolicies"])); + } + + getGlobalProperty() { + return JSON.parse(JSON.stringify(this.loopJsonCache["globalPropertiesJson"])); + } + + getDeploymentProperties() { + return JSON.parse(JSON.stringify(this.loopJsonCache["globalPropertiesJson"]["dcaeDeployParameters"])); + } + + getMsJson(type) { + var msProperties = this.loopJsonCache["microServicePolicies"]; + for (var policy in msProperties) { + if (msProperties[policy]["name"] == type) { + return JSON.parse(JSON.stringify(msProperties[policy])); + } + } + return null; + } + + getMsProperty(type) { + var msProperties = this.loopJsonCache["microServicePolicies"]; + for (var policy in msProperties) { + if (msProperties[policy]["name"] == type) { + if (msProperties[policy]["properties"] !== null && msProperties[policy]["properties"] !== undefined) { + return JSON.parse(JSON.stringify(msProperties[policy]["properties"])); + } + } + } + return null; + } + + getMsUI(type) { + var msProperties = this.loopJsonCache["microServicePolicies"]; + for (var policy in msProperties) { + if (msProperties[policy]["name"] == type) { + return JSON.parse(JSON.stringify(msProperties[policy]["jsonRepresentation"])); + } + } + return null; + } + + getResourceDetailsVfProperty() { return this.loopJsonCache["modelPropertiesJson"]["resourceDetails"]["VF"]; } - - getResourceDetailsVfModuleProperty() { + + getResourceDetailsVfModuleProperty() { return this.loopJsonCache["modelPropertiesJson"]["resourceDetails"]["VFModule"]; } - - getLoopLogsArray() { + + getLoopLogsArray() { return this.loopJsonCache.loopLogs; } - - getComponentStates() { + + getComponentStates() { return this.loopJsonCache.components; } diff --git a/ui-react/src/components/backend_communication/LoopService.js b/ui-react/src/components/backend_communication/LoopService.js deleted file mode 100644 index 982180df..00000000 --- a/ui-react/src/components/backend_communication/LoopService.js +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * 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. - * ============LICENSE_END============================================ - * =================================================================== - * - */ - -const LoopService = { - login -}; - -function login(username, password) { - let options = { - method: 'GET' - }; - if (username && password) { - options = { - method: 'GET', - credentials: 'include', - headers: { - 'Authorization': "Basic " + new Buffer(username + ":" + password).toString("base64") - } - }; - } - - return fetch(`/restservices/clds/v1/user/getUser`, options) - .then(response => handleResponse(response)) - .then(function(data) { - localStorage.setItem('user', data); - console.log(data); -}); -} - -function handleResponse(response) { - if (!response.ok || response.redirected === true) { - if (response.status === 401 || response.status === 500 || response.redirected === true) { - if (localStorage.getItem('tryBasicAuth')) { - // login failed, go to invalud login page - localStorage.removeItem('user'); - } else { - // try to login with username and password - localStorage.setItem('tryBasicAuth', true); - } - } - const error = response.statusText; - return Promise.reject(error); - } - return response.text(); -} -export default LoopService; diff --git a/ui-react/src/components/app/login/LoginFailedPage.js b/ui-react/src/components/backend_communication/UserService.js similarity index 63% rename from ui-react/src/components/app/login/LoginFailedPage.js rename to ui-react/src/components/backend_communication/UserService.js index fb398efd..81453955 100644 --- a/ui-react/src/components/app/login/LoginFailedPage.js +++ b/ui-react/src/components/backend_communication/UserService.js @@ -20,16 +20,31 @@ * =================================================================== * */ -import React from 'react' +export default class UserService { -export default class LoginFailedPage extends React.Component { - render () { - return ( -
-
Login Failed!
-
Please cick here to go back to the main page.
-
- ); + static LOGIN() { + return fetch('/restservices/clds/v1/user/getUser', { + method: 'GET', + credentials: 'include', + }) + .then(function (response) { + if (response.ok) { + console.log("getUser response received: ", response.status); + return response.text(); + } else { + console.error("getUser failed with status code: ",response.status); + return "Anonymous"; + } + }) + .then(function (data) { + console.log ("User connected:",data) + return data; + }) + .catch(function(error) { + console.error("getUser error received",error); + return "Anonymous"; + }); } } + diff --git a/ui-react/src/components/backend_communication/example.json b/ui-react/src/components/backend_communication/example.json new file mode 100644 index 00000000..f3cc9e18 --- /dev/null +++ b/ui-react/src/components/backend_communication/example.json @@ -0,0 +1,417 @@ +{ + "name": "LOOP_h2NMX_v1_0_ResourceInstanceName1_tca", + "dcaeBlueprintId": "typeId-3a942643-a8f7-4e54-b2c1-eea8daba2b17", + "globalPropertiesJson": { + "dcaeDeployParameters": { + "location_id": "", + "service_id": "", + "policy_id": "TCA_h2NMX_v1_0_ResourceInstanceName1_tca" + } + }, + "modelPropertiesJson": { + "serviceDetails": { + "serviceType": "", + "namingPolicy": "", + "environmentContext": "General_Revenue-Bearing", + "serviceEcompNaming": "true", + "serviceRole": "", + "name": "vLoadBalancerMS", + "description": "vLBMS", + "invariantUUID": "30ec5b59-4799-48d8-ac5f-1058a6b0e48f", + "ecompGeneratedNaming": "true", + "category": "Network L4+", + "type": "Service", + "UUID": "63cac700-ab9a-4115-a74f-7eac85e3fce0", + "instantiationType": "A-la-carte" + }, + "resourceDetails": { + "CP": {}, + "VL": {}, + "VF": { + "vLoadBalancerMS 0": { + "resourceVendor": "Test", + "resourceVendorModelNumber": "", + "name": "vLoadBalancerMS", + "description": "vLBMS", + "invariantUUID": "1a31b9f2-e50d-43b7-89b3-a040250cf506", + "subcategory": "Load Balancer", + "category": "Application L4+", + "type": "VF", + "UUID": "b4c4f3d7-929e-4b6d-a1cd-57e952ddc3e6", + "version": "1.0", + "resourceVendorRelease": "1.0", + "customizationUUID": "465246dc-7748-45f4-a013-308d92922552" + } + }, + "CR": {}, + "VFC": {}, + "PNF": {}, + "Service": {}, + "CVFC": {}, + "Service Proxy": {}, + "Configuration": {}, + "AllottedResource": {}, + "VFModule": { + "Vloadbalancerms..vpkg..module-1": { + "vfModuleModelInvariantUUID": "ca052563-eb92-4b5b-ad41-9111768ce043", + "vfModuleModelVersion": "1", + "vfModuleModelName": "Vloadbalancerms..vpkg..module-1", + "vfModuleModelUUID": "1e725ccc-b823-4f67-82b9-4f4367070dbc", + "vfModuleModelCustomizationUUID": "1bffdc31-a37d-4dee-b65c-dde623a76e52", + "min_vf_module_instances": 0, + "vf_module_label": "vpkg", + "max_vf_module_instances": 1, + "vf_module_type": "Expansion", + "isBase": false, + "initial_count": 0, + "volume_group": false + }, + "Vloadbalancerms..vdns..module-3": { + "vfModuleModelInvariantUUID": "4c10ba9b-f88f-415e-9de3-5d33336047fa", + "vfModuleModelVersion": "1", + "vfModuleModelName": "Vloadbalancerms..vdns..module-3", + "vfModuleModelUUID": "4fa73b49-8a6c-493e-816b-eb401567b720", + "vfModuleModelCustomizationUUID": "bafcdab0-801d-4d81-9ead-f464640a38b1", + "min_vf_module_instances": 0, + "vf_module_label": "vdns", + "max_vf_module_instances": 50, + "vf_module_type": "Expansion", + "isBase": false, + "initial_count": 0, + "volume_group": false + }, + "Vloadbalancerms..base_template..module-0": { + "vfModuleModelInvariantUUID": "921f7c96-ebdd-42e6-81b9-1cfc0c9796f3", + "vfModuleModelVersion": "1", + "vfModuleModelName": "Vloadbalancerms..base_template..module-0", + "vfModuleModelUUID": "63734409-f745-4e4d-a38b-131638a0edce", + "vfModuleModelCustomizationUUID": "86baddea-c730-4fb8-9410-cd2e17fd7f27", + "min_vf_module_instances": 1, + "vf_module_label": "base_template", + "max_vf_module_instances": 1, + "vf_module_type": "Base", + "isBase": true, + "initial_count": 1, + "volume_group": false + }, + "Vloadbalancerms..vlb..module-2": { + "vfModuleModelInvariantUUID": "a772a1f4-0064-412c-833d-4749b15828dd", + "vfModuleModelVersion": "1", + "vfModuleModelName": "Vloadbalancerms..vlb..module-2", + "vfModuleModelUUID": "0f5c3f6a-650a-4303-abb6-fff3e573a07a", + "vfModuleModelCustomizationUUID": "96a78aad-4ffb-4ef0-9c4f-deb03bf1d806", + "min_vf_module_instances": 0, + "vf_module_label": "vlb", + "max_vf_module_instances": 1, + "vf_module_type": "Expansion", + "isBase": false, + "initial_count": 0, + "volume_group": false + } + } + } + }, + "lastComputedState": "DESIGN", + "components": { + "POLICY": { + "componentState": { + "stateName": "NOT_SENT", + "description": "The policies defined have NOT yet been created on the policy engine" + } + }, + "DCAE": { + "componentState": { + "stateName": "BLUEPRINT_DEPLOYED", + "description": "The DCAE blueprint has been found in the DCAE inventory but not yet instancianted for this loop" + } + } + }, + "operationalPolicies": [ + { + "name": "OPERATIONAL_h2NMX_v1_0_ResourceInstanceName1_tca", + "configurationsJson": { + "guard_policies": { + "guard.minmax.new": { + "recipe": "", + "clname": "LOOP_h2NMX_v1_0_ResourceInstanceName1_tca", + "actor": "", + "targets": "", + "min": "gg", + "max": "gg", + "limit": "", + "timeUnits": "", + "timeWindow": "", + "guardActiveStart": "00:00:00Z", + "guardActiveEnd": "00:00:01Z" + } + }, + "operational_policy": { + "controlLoop": { + "trigger_policy": "new", + "timeout": "0", + "abatement": "false", + "controlLoopName": "LOOP_h2NMX_v1_0_ResourceInstanceName1_tca" + }, + "policies": [ + { + "id": "new", + "recipe": "", + "retry": "0", + "timeout": "0", + "actor": "", + "payload": "", + "success": "", + "failure": "", + "failure_timeout": "", + "failure_retries": "", + "failure_exception": "", + "failure_guard": "", + "target": { + "type": "VM", + "resourceID": "" + } + } + ] + } + } + } + ], + "microServicePolicies": [ + { + "name": "TCA_h2NMX_v1_0_ResourceInstanceName1_tca", + "modelType": "onap.policies.monitoring.cdap.tca.hi.lo.app", + "properties": { + "domain": "measurementsForVfScaling", + "metricsPerEventName": [ + { + "policyVersion": "ff", + "thresholds": [ + { + "severity": "CRITICAL", + "fieldPath": "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedTotalPacketsDelta", + "thresholdValue": 0, + "closedLoopEventStatus": "ONSET", + "closedLoopControlName": "ff", + "version": "ff", + "direction": "LESS" + } + ], + "policyName": "ff", + "controlLoopSchemaType": "VM", + "policyScope": "ff", + "eventName": "ff" + } + ] + }, + "shared": false, + "jsonRepresentation": { + "schema": { + "uniqueItems": "true", + "format": "tabs-top", + "type": "array", + "title": "TCA Policy JSON", + "items": { + "type": "object", + "title": "TCA Policy JSON", + "required": [ + "domain", + "metricsPerEventName" + ], + "properties": { + "domain": { + "propertyOrder": 1001, + "default": "measurementsForVfScaling", + "title": "Domain name to which TCA needs to be applied", + "type": "string" + }, + "metricsPerEventName": { + "propertyOrder": 1002, + "uniqueItems": "true", + "format": "tabs-top", + "title": "Contains eventName and threshold details that need to be applied to given eventName", + "type": "array", + "items": { + "type": "object", + "required": [ + "controlLoopSchemaType", + "eventName", + "policyName", + "policyScope", + "policyVersion", + "thresholds" + ], + "properties": { + "policyVersion": { + "propertyOrder": 1007, + "title": "TCA Policy Scope Version", + "type": "string" + }, + "thresholds": { + "propertyOrder": 1008, + "uniqueItems": "true", + "format": "tabs-top", + "title": "Thresholds associated with eventName", + "type": "array", + "items": { + "type": "object", + "required": [ + "closedLoopControlName", + "closedLoopEventStatus", + "direction", + "fieldPath", + "severity", + "thresholdValue", + "version" + ], + "properties": { + "severity": { + "propertyOrder": 1013, + "title": "Threshold Event Severity", + "type": "string", + "enum": [ + "CRITICAL", + "MAJOR", + "MINOR", + "WARNING", + "NORMAL" + ] + }, + "fieldPath": { + "propertyOrder": 1012, + "title": "Json field Path as per CEF message which needs to be analyzed for TCA", + "type": "string", + "enum": [ + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedTotalPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedOctetsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedUnicastPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedMulticastPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedDiscardedPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedErrorPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedTotalPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedOctetsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedUnicastPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedMulticastPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedBroadcastPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedDiscardedPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].receivedErrorPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedTotalPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedOctetsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedUnicastPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedMulticastPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedBroadcastPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedDiscardedPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedErrorPacketsDelta", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedTotalPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedOctetsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedUnicastPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedMulticastPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedBroadcastPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedDiscardedPacketsAccumulated", + "$.event.measurementsForVfScalingFields.vNicPerformanceArray[*].transmittedErrorPacketsAccumulated", + "$.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuIdle", + "$.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageInterrupt", + "$.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageNice", + "$.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSoftIrq", + "$.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSteal", + "$.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuUsageSystem", + "$.event.measurementsForVfScalingFields.cpuUsageArray[*].cpuWait", + "$.event.measurementsForVfScalingFields.cpuUsageArray[*].percentUsage", + "$.event.measurementsForVfScalingFields.meanRequestLatency", + "$.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryBuffered", + "$.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryCached", + "$.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryConfigured", + "$.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryFree", + "$.event.measurementsForVfScalingFields.memoryUsageArray[*].memoryUsed", + "$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value" + ] + }, + "thresholdValue": { + "propertyOrder": 1014, + "title": "Threshold value for the field Path inside CEF message", + "type": "integer" + }, + "closedLoopEventStatus": { + "propertyOrder": 1010, + "title": "Closed Loop Event Status of the threshold", + "type": "string", + "enum": [ + "ONSET", + "ABATED" + ] + }, + "closedLoopControlName": { + "propertyOrder": 1009, + "title": "Closed Loop Control Name associated with the threshold", + "type": "string" + }, + "version": { + "propertyOrder": 1015, + "title": "Version number associated with the threshold", + "type": "string" + }, + "direction": { + "propertyOrder": 1011, + "title": "Direction of the threshold", + "type": "string", + "enum": [ + "LESS", + "LESS_OR_EQUAL", + "GREATER", + "GREATER_OR_EQUAL", + "EQUAL" + ] + } + } + } + }, + "policyName": { + "propertyOrder": 1005, + "title": "TCA Policy Scope Name", + "type": "string" + }, + "controlLoopSchemaType": { + "propertyOrder": 1003, + "title": "Specifies Control Loop Schema Type for the event Name e.g. VNF, VM", + "type": "string", + "enum": [ + "VM", + "VNF" + ] + }, + "policyScope": { + "propertyOrder": 1006, + "title": "TCA Policy Scope", + "type": "string" + }, + "eventName": { + "propertyOrder": 1004, + "title": "Event name to which thresholds need to be applied", + "type": "string" + } + } + } + } + } + } + } + } + } + ], + "loopLogs": [ + { + "id": 2, + "logType": "INFO", + "logComponent": "CLAMP", + "message": "Micro Service policies UPDATED", + "logInstant": "2019-07-08T09:44:53Z" + }, + { + "id": 1, + "logType": "INFO", + "logComponent": "CLAMP", + "message": "Operational and Guard policies UPDATED", + "logInstant": "2019-07-08T09:44:37Z" + } + ] +} diff --git a/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicy.js b/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicy.js deleted file mode 100644 index 7b4ed0f8..00000000 --- a/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicy.js +++ /dev/null @@ -1,486 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * 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. - * ============LICENSE_END============================================ - * =================================================================== - * - */ - -import React from 'react' -import Button from 'react-bootstrap/Button'; -import Modal from 'react-bootstrap/Modal'; - -import './OperationalPolicy.css' - -class OperationalPolicy extends React.Component { - - constructor(props, context) { - super(props, context); - - this.handleShow = this.handleShow.bind(this); - this.handleClose = this.handleClose.bind(this); - this.initPolicySelect = this.initPolicySelect.bind(this); - - this.allPolicies=[]; - this.policy_ids=[]; - - this.state = { - show: false, - }; - } - - handleClose() { - this.setState({ show: false }); - } - - handleShow() { - this.setState({ show: true }); - } - - initPolicySelect() { - if (this.allPolicies['operational_policy'] === undefined || this.allPolicies['operational_policy'] === null) { - this.allPolicies = getOperationalPolicyProperty(); - } - // Provision all policies ID first - if (policy_ids.length == 0 && this.allPolicies['operational_policy'] != undefined) { - $.each(this.allPolicies['operational_policy']['policies'], function() { - policy_ids.push(this['id']); - }); - } - } - - render() { - return ( - <> - - - - - Modal heading - - -
-
- -

Operational Policy

-
- -
-
- -
-
-
- -
- -
- - -
- -
- - -
- -
-
-
- -
- -
-
-
-
- -
-
-
-
-
-
-
- - -
-
- -
- - ID must be unique -
-
-
- -
- -
-
-
- -
- - -
-
-
- -
- -
-
- -
- -
- -
- - -
- -
-
-
- -
- -
-
-
- -
- - -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
-
- -
- -
-
-
- -
- -
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
-
- -
- -
- -
- -
-
-
- -
- -
- -
-
-
- -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- - -
- -
-
- -
- -
- -
- -
- -
-
-
- -
- -
- -
- -
- -
- -
-
-
- -
- -
- -
- -
-
- -
- -
-
-
- -
- - -
- -
-
- - - - -
- - ); - } -} - -export default OperationalPolicy; \ No newline at end of file diff --git a/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicyModal.js b/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicyModal.js new file mode 100644 index 00000000..e52d930a --- /dev/null +++ b/ui-react/src/components/dialogs/OperationalPolicy/OperationalPolicyModal.js @@ -0,0 +1,555 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * 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. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +import React from 'react' +import Button from 'react-bootstrap/Button'; +import Modal from 'react-bootstrap/Modal'; +import LoopCache from '../../backend_communication/LoopCache' +import './OperationalPolicy.css' +import styled from 'styled-components'; + +const ModalStyled = styled(Modal)` + background-color: transparent; +` + +export default class OperationalPolicyModal extends React.Component { + + constructor(props, context) { + super(props, context); + + this.loopCache = new LoopCache(); + + this.handleClose = this.handleClose.bind(this); + this.initPolicySelect = this.initPolicySelect.bind(this); + + this.allPolicies = []; + this.policyIds = []; + + this.initPolicySelect(); + + this.state = { + show: true, + }; + + } + + handleClose() { + this.setState({ show: false }); + } + + initPolicySelect() { + if (this.allPolicies['operational_policy'] === undefined || this.allPolicies['operational_policy'] === null) { + this.allPolicies = this.loopCache.getOperationalPolicyProperty(); + } + // Provision all policies ID first + if (this.policyIds.length == 0 && this.allPolicies['operational_policy'] != undefined) { + + for (let i = 0; i < this.allPolicies['operational_policy']['policies'].length; i++) { + this.policyIds.push(this.allPolicies['operational_policy']['policies'][i]['id']); + } + } + } + + renderPolicyIdSelect() { + return ( + + ); + } + + serializeElement(element) { + var o = {}; + element.serializeArray().forEach(function () { + if (o[this.name]) { + if (!o[this.name].push) { + o[this.name] = [o[this.name]]; + } + o[this.name].push(this.value || ''); + } else { + o[this.name] = this.value || ''; + } + }); + return o; + } + + // When we change the name of a policy + isDuplicatedId (event) { + // update policy id structure + var formNum = document.getElementById(event.target).closest('.formId').attr('id').substring(6); + var policyId = document.getElementById(event.target).val(); + if (this.policyIds.includes(policyId)) { + console.log("Duplicated ID, cannot proceed"); + return true; + } else { + this.duplicated = false; + this.policyIds.splice(this.policyIds.indexOf(document.getElementById("#formId" + formNum + " #id").val()), 1); + this.policyIds.push(document.getElementById(event.target).val()); + // Update the tab now + document.getElementById("#go_properties_tab" + formNum).text(document.getElementById(event.target).val()); + } + } + + configureComponents() { + console.log("Load properties to op policy"); + // Set the header + document.getElementsByClassName('form-control').forEach(function() { + this.val(this.allPolicies['operational_policy']['controlLoop'][this.id]); + }); + // Set the sub-policies + this.allPolicies['operational_policy']['policies'].forEach(function(opPolicyElemIndex, opPolicyElemValue) { + +/* var formNum = add_one_more(); + forEach(document.getElementsByClassName('policyProperties').find('.form-control'), function(opPolicyPropIndex, opPolicyPropValue) { + + $("#formId" + formNum + " .policyProperties").find("#" + opPolicyPropValue.id).val( + allPolicies['operational_policy']['policies'][opPolicyElemIndex][opPolicyPropValue.id]); + }); + + // Initial TargetResourceId options + initTargetResourceIdOptions(allPolicies['operational_policy']['policies'][opPolicyElemIndex]['target']['type'], formNum); + $.each($('.policyTarget').find('.form-control'), function(opPolicyTargetPropIndex, opPolicyTargetPropValue) { + + $("#formId" + formNum + " .policyTarget").find("#" + opPolicyTargetPropValue.id).val( + allPolicies['operational_policy']['policies'][opPolicyElemIndex]['target'][opPolicyTargetPropValue.id]); + }); + + // update the current tab label + $("#go_properties_tab" + formNum).text( + allPolicies['operational_policy']['policies'][opPolicyElemIndex]['id']); + // Check if there is a guard set for it + $.each(allPolicies['guard_policies'], function(guardElemId, guardElemValue) { + + if (guardElemValue.recipe === $($("#formId" + formNum + " #recipe")[0]).val()) { + // Found one, set all guard prop + $.each($('.guardProperties').find('.form-control'), function(guardPropElemIndex, + guardPropElemValue) { + + guardElemValue['id'] = guardElemId; + $("#formId" + formNum + " .guardProperties").find("#" + guardPropElemValue.id).val( + guardElemValue[guardPropElemValue.id]); + }); + iniGuardPolicyType(guardElemId, formNum); + // And finally enable the flag + $("#formId" + formNum + " #enableGuardPolicy").prop("checked", true); + } + });*/ + }); + } + + render() { + return ( + + + Operational policies + + +
+
+
+
+
+ +
+ {this.renderPolicyIdSelect()} +
+ + +
+ +
+ + +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+ +
+ + ID must be unique +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+ +
+
+ +
+ +
+ +
+ + +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + +
+ +
+
+ +
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+ +
+ +
+ +
+ +
+
+ +
+ +
+
+
+ +
+ + + + +
+ + ); + } +} diff --git a/ui-react/src/components/dialogs/OperationalPolicy/template.json b/ui-react/src/components/dialogs/OperationalPolicy/template.json new file mode 100644 index 00000000..6b4477f8 --- /dev/null +++ b/ui-react/src/components/dialogs/OperationalPolicy/template.json @@ -0,0 +1,52 @@ +{ + "operationalPolicies": [ + { + "name": "OPERATIONAL_LOOP_NAME", + "configurationsJson": { + "guard_policies": { + "guard.minmax.new": { + "recipe": "", + "clname": "LOOP_NAME", + "actor": "", + "targets": "", + "min": "", + "max": "", + "limit": "", + "timeUnits": "", + "timeWindow": "", + "guardActiveStart": "00:00:00Z", + "guardActiveEnd": "00:00:01Z" + } + }, + "operational_policy": { + "controlLoop": { + "trigger_policy": "new", + "timeout": "0", + "abatement": "false", + "controlLoopName": "LOOP_h2NMX_v1_0_ResourceInstanceName1_tca" + }, + "policies": [ + { + "id": "new", + "recipe": "", + "retry": "0", + "timeout": "0", + "actor": "", + "payload": "", + "success": "", + "failure": "", + "failure_timeout": "", + "failure_retries": "", + "failure_exception": "", + "failure_guard": "", + "target": { + "type": "VM", + "resourceID": "" + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/ui-react/src/components/loop_viewer/svg/example.svg b/ui-react/src/components/loop_viewer/svg/example.svg index bb332704..2f5ebd03 100644 --- a/ui-react/src/components/loop_viewer/svg/example.svg +++ b/ui-react/src/components/loop_viewer/svg/example.svg @@ -1,13 +1,444 @@ - - - - - - - - - - SVG - - Sorry, your browser does not support inline SVG. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VES + + + + + + + + + + + + + + + + + + + + + + + + + tca_k8s + + + + + + + + + + + + + + + + + + + + + + + + + OperationalPolicy + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ui-react/src/components/menu/MenuBar.js b/ui-react/src/components/menu/MenuBar.js index 34854196..85d32c53 100644 --- a/ui-react/src/components/menu/MenuBar.js +++ b/ui-react/src/components/menu/MenuBar.js @@ -35,13 +35,6 @@ const StyledNavDropdownItem = styled(NavDropdown.Item)` `; export default class MenuBar extends React.Component { - - openEmailConsole() { - console.log("contactUs"); - var link = "mailto:onap-discuss@lists.onap.org?subject=CLAMP&body=Please " - + "send us suggestions or feature enhancements or defect. If possible, please send us the steps to replicate any defect."; - window.location.href = link; - }; render () { return ( @@ -52,7 +45,7 @@ export default class MenuBar extends React.Component { Close Model - Submit + Submit Stop Restart Delete @@ -63,14 +56,12 @@ export default class MenuBar extends React.Component { Refresh Status - window.open("https://wiki.onap.org/", "_blank")}>Wiki - this.openEmailConsole()}>Contact Us + Wiki + Contact Us User Info - - - ); + ); } } diff --git a/ui-react/src/components/route/LoginRoute.js b/ui-react/src/components/route/LoginRoute.js deleted file mode 100644 index f24e31b4..00000000 --- a/ui-react/src/components/route/LoginRoute.js +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP CLAMP - * ================================================================================ - * Copyright (C) 2019 AT&T Intellectual Property. All rights - * reserved. - * ================================================================================ - * 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. - * ============LICENSE_END============================================ - * =================================================================== - * - */ -import React from 'react'; -import { Route, Redirect } from 'react-router-dom'; - -const LoginRoute = ({ component: Component, ...rest }) => ( - ( - localStorage.getItem('user') - ? - : localStorage.getItem('tryBasicAuth') - ? - : - )} /> -) - -export default LoginRoute; diff --git a/ui-react/src/index.js b/ui-react/src/index.js index 8236eb15..1b2f2f59 100644 --- a/ui-react/src/index.js +++ b/ui-react/src/index.js @@ -22,28 +22,19 @@ */ import React from 'react'; import ReactDOM from 'react-dom'; - -import { Route, Switch, BrowserRouter } from 'react-router-dom' import OnapClamp from './OnapClamp'; -import NotFound from './components/app/NotFound'; -import LoginPage from './components/app/login/LoginPage'; -import LoginFailedPage from './components/app/login/LoginFailedPage'; -import BasicAuthLogin from './components/app/login/BasicAuthLogin'; -import LoginRoute from './components/route/LoginRoute'; +import { Route, BrowserRouter } from 'react-router-dom' +import OperationalPolicyModal from './components/dialogs/OperationalPolicy/OperationalPolicyModal'; const routing = ( - -
- - - - - - - -
- -) + + + } /> + +); -ReactDOM.render(routing, document.getElementById('root')) +ReactDOM.render( + routing, + document.getElementById('root') +)