Create wt-odlux directory
[ccsdk/features.git] / sdnr / wt-odlux / odlux / apps / configurationApp / src / pluginConfiguration.tsx
1 /**
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt odlux
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18
19 import React from 'react';
20 import { withRouter, RouteComponentProps, Route, Switch, Redirect } from 'react-router-dom';
21
22 import { connect, Connect, IDispatcher } from '../../../framework/src/flux/connect';
23 import applicationManager from '../../../framework/src/services/applicationManager';
24
25 import { configurationAppRootHandler } from './handlers/configurationAppRootHandler';
26 import { NetworkElementSelector } from './views/networkElementSelector';
27
28 import ConfigurationApplication from './views/configurationApplication';
29 import { updateNodeIdAsyncActionCreator, updateViewActionAsyncCreator } from './actions/deviceActions';
30 import { DisplayModeType } from './handlers/viewDescriptionHandler';
31 import { ViewSpecification } from './models/uiModels';
32
33 const appIcon = require('./assets/icons/configurationAppIcon.svg');  // select app icon
34
35 let currentNodeId: string | null | undefined = undefined;
36 let currentVirtualPath: string | null | undefined = undefined;
37 let lastUrl: string | undefined = undefined;
38
39 const mapDispatch = (dispatcher: IDispatcher) => ({
40   updateNodeId: (nodeId: string) => dispatcher.dispatch(updateNodeIdAsyncActionCreator(nodeId)),
41   updateView: (vPath: string) => dispatcher.dispatch(updateViewActionAsyncCreator(vPath)),
42 });
43
44 // eslint-disable-next-line @typescript-eslint/naming-convention
45 const ConfigurationApplicationRouteAdapter = connect(undefined, mapDispatch)((props: RouteComponentProps<{ nodeId?: string; 0: string }> & Connect<undefined, typeof mapDispatch>) => {
46   React.useEffect(() => {
47     return () => {
48       lastUrl = undefined;
49       currentNodeId = undefined;
50       currentVirtualPath = undefined;
51     };
52   }, []);
53   if (props.location.pathname !== lastUrl) {
54     // ensure the asynchronous update will only be called once per path
55     lastUrl = props.location.pathname;
56     window.setTimeout(async () => {
57
58       // check if the nodeId has changed
59       let enableDump = false;
60       if (currentNodeId !== props.match.params.nodeId) {
61         currentNodeId = props.match.params.nodeId || undefined;
62         if (currentNodeId && currentNodeId.endsWith('|dump')) {
63           enableDump = true;
64           currentNodeId = currentNodeId.replace(/\|dump$/i, '');
65         }
66         currentVirtualPath = null;
67         if (currentNodeId) {
68           await props.updateNodeId(currentNodeId);
69         }
70       }
71
72       if (currentVirtualPath !== props.match.params[0]) {
73         currentVirtualPath = props.match.params[0];
74         if (currentVirtualPath && currentVirtualPath.endsWith('|dump')) {
75           enableDump = true;
76           currentVirtualPath = currentVirtualPath.replace(/\|dump$/i, '');
77         }
78         await props.updateView(currentVirtualPath);
79       }
80
81       if (enableDump) {
82         const device = props.state.configuration.deviceDescription;
83         const ds = props.state.configuration.viewDescription.displaySpecification;
84
85         const createDump = (view: ViewSpecification | null, level: number = 0) => {
86           if (view === null) return 'Empty';
87           const indention = Array(level * 4).fill(' ').join('');
88           let result = '';
89
90           if (!view) debugger;
91           // result += `${indention}  [${view.canEdit ? 'rw' : 'ro'}] ${view.ns}:${view.name} ${ds.displayMode === DisplayModeType.displayAsList ? '[LIST]' : ''}\r\n`;
92           result += Object.keys(view.elements).reduce((acc, cur) => {
93             const elm = view.elements[cur];
94             acc += `${indention}  [${elm.uiType === 'rpc' ? 'x' : elm.config ? 'rw' : 'ro'}:${elm.id}] (${elm.module}:${elm.label}) {${elm.uiType}} ${elm.uiType === 'object' && elm.isList ? `as LIST with KEY [${elm.key}]` : ''}\r\n`;
95             // acc += `${indention}    +${elm.mandatory ? "mandatory" : "none"} - ${elm.path} \r\n`;
96             
97             switch (elm.uiType) {
98               case 'object':
99                 acc += createDump(device.views[(elm as any).viewId], level + 1);
100                 break;
101               default:
102             }
103             return acc;
104           }, '');
105           return `${result}`;
106         };
107
108         const dump = createDump(ds.displayMode === DisplayModeType.displayAsObject || ds.displayMode === DisplayModeType.displayAsList ? ds.viewSpecification : null, 0);
109         const element = document.createElement('a');
110         element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(dump));
111         element.setAttribute('download', currentNodeId + '.txt');
112
113         element.style.display = 'none';
114         document.body.appendChild(element);
115
116         element.click();
117
118         document.body.removeChild(element);
119       }
120
121     });
122   }
123   return (
124     <ConfigurationApplication />
125   );
126 });
127
128 const App = withRouter((props: RouteComponentProps) => (
129   <Switch>
130     <Route path={`${props.match.url}/:nodeId/*`} component={ConfigurationApplicationRouteAdapter} />
131     <Route path={`${props.match.url}/:nodeId`} component={ConfigurationApplicationRouteAdapter} />
132     <Route path={`${props.match.url}`} component={NetworkElementSelector} />
133     <Redirect to={`${props.match.url}`} />
134   </Switch>
135 ));
136
137 export function register() {
138   applicationManager.registerApplication({
139     name: 'configuration',
140     icon: appIcon,
141     rootComponent: App,
142     rootActionHandler: configurationAppRootHandler,
143     menuEntry: 'Configuration',
144   });
145 }