summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sdnr/wt/odlux/apps/apiDemo/package.json12
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/policies.json14
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts33
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx9
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts11
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/handlers/viewDescriptionHandler.ts2
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts1
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/pluginConfiguration.tsx57
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts4
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx1452
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx2
-rw-r--r--sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts30
-rw-r--r--sdnr/wt/odlux/apps/connectApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/connectApp/policies.json12
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts70
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx36
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx73
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/refreshConnectionStatusLogDialog.tsx117
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/components/refreshNetworkElementsDialog.tsx117
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts2
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts17
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/index.html1
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts5
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts2
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx29
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts115
-rw-r--r--sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx15
-rw-r--r--sdnr/wt/odlux/apps/connectApp/webpack.config.js48
-rw-r--r--sdnr/wt/odlux/apps/demoApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/demoApp/src/index.html1
-rw-r--r--sdnr/wt/odlux/apps/eventLogApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/eventLogApp/src/components/refreshEventLogDialog.tsx117
-rw-r--r--sdnr/wt/odlux/apps/eventLogApp/src/views/eventLog.tsx60
-rw-r--r--sdnr/wt/odlux/apps/faultApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/components/refreshAlarmLogDialog.tsx117
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/components/refreshCurrentProblemsDialog.tsx117
-rw-r--r--sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx103
-rw-r--r--sdnr/wt/odlux/apps/helpApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/inventoryApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/inventoryApp/src/components/refreshInventoryDialog.tsx117
-rw-r--r--sdnr/wt/odlux/apps/inventoryApp/src/index.html3
-rw-r--r--sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx80
-rw-r--r--sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx17
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx86
-rw-r--r--sdnr/wt/odlux/apps/maintenanceApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/maintenanceApp/src/components/refreshMaintenanceEntries.tsx117
-rw-r--r--sdnr/wt/odlux/apps/maintenanceApp/src/views/maintenenceView.tsx77
-rw-r--r--sdnr/wt/odlux/apps/mediatorApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/mediatorApp/src/components/refreshMediatorDialog.tsx117
-rw-r--r--sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorServerSelection.tsx24
-rw-r--r--sdnr/wt/odlux/apps/minimumApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/package.json12
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx4
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/handlers/mapReducer.ts4
-rw-r--r--sdnr/wt/odlux/apps/networkMapApp/src/index.html4
-rw-r--r--sdnr/wt/odlux/apps/performanceHistoryApp/package.json12
-rw-r--r--sdnr/wt/odlux/framework/package.json12
-rw-r--r--sdnr/wt/odlux/framework/pom.xml4
-rw-r--r--sdnr/wt/odlux/framework/src/app.tsx8
-rw-r--r--sdnr/wt/odlux/framework/src/components/material-table/index.tsx44
-rw-r--r--sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx4
-rw-r--r--sdnr/wt/odlux/framework/src/components/material-table/utilities.ts64
-rw-r--r--sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts2
-rw-r--r--sdnr/wt/odlux/framework/src/services/notificationService.ts156
-rw-r--r--sdnr/wt/odlux/framework/src/services/restService.ts42
-rw-r--r--sdnr/wt/odlux/framework/src/views/about.tsx67
-rw-r--r--sdnr/wt/odlux/framework/tsconfig.json2
-rw-r--r--sdnr/wt/odlux/framework/webpack.config.js24
-rw-r--r--sdnr/wt/odlux/installer/pom.xml3
-rw-r--r--sdnr/wt/odlux/odlux.properties22
-rw-r--r--sdnr/wt/odlux/package.json24
-rw-r--r--sdnr/wt/odlux/yarn.lock1621
74 files changed, 3763 insertions, 1943 deletions
diff --git a/sdnr/wt/odlux/apps/apiDemo/package.json b/sdnr/wt/odlux/apps/apiDemo/package.json
index 230e86aea..3805c020e 100644
--- a/sdnr/wt/odlux/apps/apiDemo/package.json
+++ b/sdnr/wt/odlux/apps/apiDemo/package.json
@@ -24,17 +24,17 @@
"@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/configurationApp/package.json b/sdnr/wt/odlux/apps/configurationApp/package.json
index d1ab86da7..16588cd18 100644
--- a/sdnr/wt/odlux/apps/configurationApp/package.json
+++ b/sdnr/wt/odlux/apps/configurationApp/package.json
@@ -24,17 +24,17 @@
"@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/configurationApp/policies.json b/sdnr/wt/odlux/apps/configurationApp/policies.json
index cd9e9fc15..91a0abf96 100644
--- a/sdnr/wt/odlux/apps/configurationApp/policies.json
+++ b/sdnr/wt/odlux/apps/configurationApp/policies.json
@@ -1,12 +1,12 @@
[
{
- "path": "/**/operations/cluster-admin**",
- "actions": {
- "get": true,
- "post": true,
- "put": true,
- "patch": true,
- "delete": true
+ "path": "/rests/**/node=Sim2230**",
+ "methods": {
+ "get": false,
+ "post": false,
+ "put": false,
+ "delete": false,
+ "patch": false
}
}
] \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts b/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts
index d6283852c..f80fbfc4d 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/actions/deviceActions.ts
@@ -9,6 +9,7 @@ import { restService } from "../services/restServices";
import { YangParser } from "../yang/yangParser";
import { Module } from "../models/yang";
import { ViewSpecification, ViewElement, isViewElementReference, isViewElementList, isViewElementObjectOrList, isViewElementRpc, isViewElementChoise, ViewElementChoiseCase, ViewElementString } from "../models/uiModels";
+import { exception } from 'console';
export class EnableValueSelector extends Action {
constructor(public listSpecification: ViewSpecification, public listData: any[], public keyProperty: string, public onValueSelected : (value: any) => void ) {
@@ -333,6 +334,7 @@ export const updateViewActionAsyncCreator = (vPath: string) => async (dispatch:
const refView : ViewSpecification = {
id: "-1",
canEdit: false,
+ config: false,
language: "en-US",
elements: {
[viewElement.key!] : {
@@ -441,11 +443,13 @@ export const updateViewActionAsyncCreator = (vPath: string) => async (dispatch:
// create display specification
const ds: DisplaySpecification = viewElement! && viewElement!.uiType === "rpc"
? {
+ dataPath,
displayMode: DisplayModeType.displayAsRPC,
inputViewSpecification: inputViewSpecification && resolveViewDescription(defaultNS, vPath, inputViewSpecification),
outputViewSpecification: outputViewSpecification && resolveViewDescription(defaultNS, vPath, outputViewSpecification),
}
: {
+ dataPath,
displayMode: extractList ? DisplayModeType.displayAsList : DisplayModeType.displayAsObject,
viewSpecification: resolveViewDescription(defaultNS, vPath, viewSpecification),
keyProperty: isViewElementList(viewElement!) && viewElement.key || undefined,
@@ -517,6 +521,35 @@ export const updateDataActionAsyncCreator = (vPath: string, data: any) => async
}
}
+ // remove read-only elements
+ const removeReadOnlyElements = (viewSpecification: ViewSpecification, isList: boolean, data: any) => {
+ if (isList) {
+ return data.map((elm : any) => removeReadOnlyElements(viewSpecification, false, elm));
+ } else {
+ return Object.keys(data).reduce<{[key: string]: any}>((acc, cur)=>{
+ const [nsOrName, name] = cur.split(':',1);
+ const element = viewSpecification.elements[cur] || viewSpecification.elements[nsOrName] || viewSpecification.elements[name];
+ if (!element && process.env.NODE_ENV === "development" ) {
+ throw new Error("removeReadOnlyElements: Could not determine elment for data.");
+ }
+ if (element && element.config) {
+ if (element.uiType==="object") {
+ const view = views[+element.viewId];
+ if (!view) {
+ throw new Error("removeReadOnlyElements: Internal Error could not determine viewId: "+element.viewId);
+ }
+ acc[cur] = removeReadOnlyElements(view, element.isList != null && element.isList, data[cur]);
+ } else {
+ acc[cur] = data[cur];
+ }
+ }
+ return acc;
+ }, {});
+ }
+ };
+ data = removeReadOnlyElements(viewSpecification, embedList, data);
+
+
// embed the list -> key: list
data = embedList
? { [viewElement!.label]: data }
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx
index 223c4cb25..b7697c880 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx
+++ b/sdnr/wt/odlux/apps/configurationApp/src/components/uiElementReference.tsx
@@ -16,7 +16,7 @@
* ============LICENSE_END==========================================================================
*/
-import React from 'react';
+import React, { useState } from 'react';
import { Tooltip, Button, FormControl, Theme, createStyles, makeStyles } from '@material-ui/core';
import { ViewElement } from '../models/uiModels';
@@ -35,13 +35,14 @@ type UIElementReferenceProps = {
export const UIElementReference: React.FC<UIElementReferenceProps> = (props) => {
const classes = useStyles();
+ const [disabled, setDisabled] = useState(true);
const { element } = props;
return (
- <FormControl key={element.id} style={{ width: 485, marginLeft: 20, marginRight: 20 }}>
+ <FormControl key={element.id} style={{ width: 485, marginLeft: 20, marginRight: 20 }} onMouseDown={(ev) => { ev.preventDefault(); ev.stopPropagation(); ev.button === 1 && setDisabled(!disabled) }}>
<Tooltip title={element.description || element.path || ''}>
- <Button className={classes.button} aria-label={element.label+'-button'} color="secondary" disabled={props.disabled} onClick={() => {
+ <Button className={classes.button} aria-label={element.label+'-button'} color="secondary" disabled={props.disabled && disabled} onClick={() => {
props.onOpenReference(element);
- }}>{`${element.label}`}</Button>
+ }} >{`${element.label}`}</Button>
</Tooltip>
</FormControl>
);
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts b/sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts
index e6b808b80..02f2929cd 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/handlers/connectedNetworkElementsHandler.ts
@@ -18,8 +18,10 @@
import { createExternal, IExternalTableState } from '../../../../framework/src/components/material-table/utilities';
import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch';
+import { getAccessPolicyByUrl } from '../../../../framework/src/services/restService';
import { NetworkElementConnection } from '../models/networkElementConnection';
+import { restService } from '../services/restServices';
export interface IConnectedNetworkElementsState extends IExternalTableState<NetworkElementConnection> { }
@@ -33,4 +35,11 @@ export const {
reloadAction: connectedNetworkElementsReloadAction,
// set value action, to change a value
-} = createExternal<NetworkElementConnection>(connectedNetworkElementsSearchHandler, appState => appState.configuration.connectedNetworkElements);
+} = createExternal<NetworkElementConnection>(connectedNetworkElementsSearchHandler, appState => appState.configuration.connectedNetworkElements,
+ (ne) => {
+ if (!ne || !ne.id) return true;
+ const neUrl = restService.getNetworkElementUri(ne.id);
+ const policy = getAccessPolicyByUrl(neUrl);
+ return !(policy.GET && policy.POST);
+ }
+);
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/handlers/viewDescriptionHandler.ts b/sdnr/wt/odlux/apps/configurationApp/src/handlers/viewDescriptionHandler.ts
index ea2036415..7a9812bfd 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/handlers/viewDescriptionHandler.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/handlers/viewDescriptionHandler.ts
@@ -35,10 +35,12 @@ export type DisplaySpecification = {
viewSpecification: ViewSpecification;
keyProperty?: string;
apidocPath?: string;
+ dataPath?: string;
} | {
displayMode: DisplayModeType.displayAsRPC;
inputViewSpecification?: ViewSpecification;
outputViewSpecification?: ViewSpecification;
+ dataPath?: string;
}
export interface IViewDescriptionState {
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts b/sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts
index 9c03bdf9b..29484d812 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/models/uiModels.ts
@@ -220,6 +220,7 @@ export type ViewSpecification = {
"when"?: string;
"uses"?: (string[]) & { [ResolveFunction]?: (parent: string) => void };
"elements": { [name: string]: ViewElement };
+ "config": boolean;
readonly "canEdit": boolean;
}
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/pluginConfiguration.tsx b/sdnr/wt/odlux/apps/configurationApp/src/pluginConfiguration.tsx
index 0cab7b793..3bc0e3968 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/pluginConfiguration.tsx
+++ b/sdnr/wt/odlux/apps/configurationApp/src/pluginConfiguration.tsx
@@ -29,21 +29,19 @@ import { NetworkElementSelector } from "./views/networkElementSelector";
import ConfigurationApplication from "./views/configurationApplication";
import { updateNodeIdAsyncActionCreator, updateViewActionAsyncCreator } from "./actions/deviceActions";
+import { DisplayModeType } from "./handlers/viewDescriptionHandler";
+import { ViewSpecification } from "./models/uiModels";
let currentNodeId: string | null | undefined = undefined;
let currentVirtualPath: string | null | undefined = undefined;
let lastUrl: string | undefined = undefined;
-const mapProps = (state: IApplicationStoreState) => ({
- // currentProblemsProperties: createCurrentProblemsProperties(state),
-});
-
const mapDisp = (dispatcher: IDispatcher) => ({
updateNodeId: (nodeId: string) => dispatcher.dispatch(updateNodeIdAsyncActionCreator(nodeId)),
updateView: (vPath: string) => dispatcher.dispatch(updateViewActionAsyncCreator(vPath)),
});
-const ConfigurationApplicationRouteAdapter = connect(mapProps, mapDisp)((props: RouteComponentProps<{ nodeId?: string, 0: string }> & Connect<typeof mapProps, typeof mapDisp>) => {
+const ConfigurationApplicationRouteAdapter = connect(undefined, mapDisp)((props: RouteComponentProps<{ nodeId?: string, 0: string }> & Connect<undefined, typeof mapDisp>) => {
React.useEffect(() => {
return () => {
lastUrl = undefined;
@@ -57,17 +55,66 @@ const ConfigurationApplicationRouteAdapter = connect(mapProps, mapDisp)((props:
window.setTimeout(async () => {
// check if the nodeId has changed
+ let dump = false;
if (currentNodeId !== props.match.params.nodeId) {
currentNodeId = props.match.params.nodeId || undefined;
+ if (currentNodeId && currentNodeId.endsWith("|dump")) {
+ dump = true;
+ currentNodeId = currentNodeId.replace(/\|dump$/i, '');
+ }
currentVirtualPath = null;
currentNodeId && await props.updateNodeId(currentNodeId);
}
if (currentVirtualPath !== props.match.params[0]) {
currentVirtualPath = props.match.params[0];
+ if (currentVirtualPath && currentVirtualPath.endsWith("|dump")) {
+ dump = true;
+ currentVirtualPath = currentVirtualPath.replace(/\|dump$/i, '');
+ }
await props.updateView(currentVirtualPath);
}
+ if (dump) {
+ const device = props.state.configuration.deviceDescription;
+ const ds = props.state.configuration.viewDescription.displaySpecification;
+
+ const createDump = (view: ViewSpecification | null, level: number = 0) => {
+ if (view === null) return "Empty";
+ const indention = Array(level * 4).fill(' ').join('');
+ let result = '';
+
+ if (!view) debugger;
+ // result += `${indention} [${view.canEdit ? 'rw' : 'ro'}] ${view.ns}:${view.name} ${ds.displayMode === DisplayModeType.displayAsList ? '[LIST]' : ''}\r\n`;
+ result += Object.keys(view.elements).reduce((acc, cur) => {
+ const elm = view.elements[cur];
+ acc += `${indention} [${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`;
+ // acc += `${indention} +${elm.mandatory ? "mandetory" : "none"} - ${elm.path} \r\n`;
+
+ switch (elm.uiType) {
+ case "object":
+ acc += createDump(device.views[(elm as any).viewId], level + 1);
+ break;
+ default:
+ }
+ return acc;
+ }, "");
+ return `${result}`;
+ }
+
+ const dump = createDump(ds.displayMode === DisplayModeType.displayAsObject || ds.displayMode === DisplayModeType.displayAsList ? ds.viewSpecification : null, 0);
+ var element = document.createElement('a');
+ element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(dump));
+ element.setAttribute('download', currentNodeId + ".txt");
+
+ element.style.display = 'none';
+ document.body.appendChild(element);
+
+ element.click();
+
+ document.body.removeChild(element);
+ }
+
});
}
return (
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts b/sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts
index 239a8e448..bdef64cf2 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/services/restServices.ts
@@ -51,8 +51,10 @@ type CapabilityAnswer = {
}
class RestService {
+ public getNetworkElementUri = (nodeId: string) => '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId;
+
public async getCapabilitiesByMoutId(nodeId: string): Promise<CapabilityAnswer> {
- const path = `/rests/data/network-topology:network-topology/topology=topology-netconf/node=${nodeId}`;
+ const path = this.getNetworkElementUri(nodeId);
const capabilitiesResult = await requestRest<CapabilityResponse>(path, { method: "GET" });
const avaliableCapabilities = capabilitiesResult && capabilitiesResult["network-topology:node"] && capabilitiesResult["network-topology:node"].length > 0 &&
capabilitiesResult["network-topology:node"][0]["netconf-node-topology:available-capabilities"] &&
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx b/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx
index dbaa77874..e466dbacc 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx
+++ b/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx
@@ -16,7 +16,7 @@
* ============LICENSE_END==========================================================================
*/
-import React from 'react';
+import React, { useState } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { WithStyles, withStyles, createStyles, Theme } from '@material-ui/core/styles';
@@ -31,6 +31,8 @@ import { DisplayModeType } from '../handlers/viewDescriptionHandler';
import { SetSelectedValue, splitVPath, updateDataActionAsyncCreator, updateViewActionAsyncCreator, removeElementActionAsyncCreator, executeRpcActionAsyncCreator } from "../actions/deviceActions";
import { ViewSpecification, isViewElementString, isViewElementNumber, isViewElementBoolean, isViewElementObjectOrList, isViewElementSelection, isViewElementChoise, ViewElement, ViewElementChoise, isViewElementUnion, isViewElementRpc, ViewElementRpc, isViewElementEmpty, isViewElementDate } from "../models/uiModels";
+import { getAccessPolicyByUrl } from "../../../../framework/src/services/restService";
+
import Fab from '@material-ui/core/Fab';
import AddIcon from '@material-ui/icons/Add';
import PostAdd from '@material-ui/icons/PostAdd';
@@ -65,106 +67,107 @@ import { UIElementUnion } from '../components/uiElementUnion';
import { UiElementLeafList } from '../components/uiElementLeafList';
import { useConfirm } from 'material-ui-confirm';
+import restService from '../services/restServices';
const styles = (theme: Theme) => createStyles({
- header: {
- "display": "flex",
- "justifyContent": "space-between",
- },
- leftButton: {
- "justifyContent": "left"
- },
- outer: {
- "flex": "1",
- "height": "100%",
- "display": "flex",
- "alignItems": "center",
- "justifyContent": "center",
- },
- inner: {
-
- },
- container: {
- "height": "100%",
- "display": "flex",
- "flexDirection": "column",
- },
- "icon": {
- "marginRight": theme.spacing(0.5),
- "width": 20,
- "height": 20,
- },
- "fab": {
- "margin": theme.spacing(1),
+ header: {
+ "display": "flex",
+ "justifyContent": "space-between",
+ },
+ leftButton: {
+ "justifyContent": "left"
+ },
+ outer: {
+ "flex": "1",
+ "height": "100%",
+ "display": "flex",
+ "alignItems": "center",
+ "justifyContent": "center",
+ },
+ inner: {
+
+ },
+ container: {
+ "height": "100%",
+ "display": "flex",
+ "flexDirection": "column",
+ },
+ "icon": {
+ "marginRight": theme.spacing(0.5),
+ "width": 20,
+ "height": 20,
+ },
+ "fab": {
+ "margin": theme.spacing(1),
+ },
+ button: {
+ margin: 0,
+ padding: "6px 6px",
+ minWidth: 'unset'
+ },
+ readOnly: {
+ '& label.Mui-focused': {
+ color: 'green',
},
- button: {
- margin: 0,
- padding: "6px 6px",
- minWidth: 'unset'
+ '& .MuiInput-underline:after': {
+ borderBottomColor: 'green',
},
- readOnly: {
- '& label.Mui-focused': {
- color: 'green',
- },
- '& .MuiInput-underline:after': {
- borderBottomColor: 'green',
- },
- '& .MuiOutlinedInput-root': {
- '& fieldset': {
- borderColor: 'red',
- },
- '&:hover fieldset': {
- borderColor: 'yellow',
- },
- '&.Mui-focused fieldset': {
- borderColor: 'green',
- },
- },
+ '& .MuiOutlinedInput-root': {
+ '& fieldset': {
+ borderColor: 'red',
+ },
+ '&:hover fieldset': {
+ borderColor: 'yellow',
+ },
+ '&.Mui-focused fieldset': {
+ borderColor: 'green',
+ },
},
- uiView: {
- overflowY: "auto",
- },
- section: {
- padding: "15px",
- borderBottom: `2px solid ${theme.palette.divider}`,
- },
- viewElements: {
- width: 485, marginLeft: 20, marginRight: 20
- },
- verificationElements: {
- width: 485, marginLeft: 20, marginRight: 20
- },
- heading: {
- fontSize: theme.typography.pxToRem(15),
- fontWeight: theme.typography.fontWeightRegular,
- },
- moduleCollection: {
- marginTop: "16px",
- overflow: "auto",
- },
- objectReult: {
- overflow: "auto"
- }
+ },
+ uiView: {
+ overflowY: "auto",
+ },
+ section: {
+ padding: "15px",
+ borderBottom: `2px solid ${theme.palette.divider}`,
+ },
+ viewElements: {
+ width: 485, marginLeft: 20, marginRight: 20
+ },
+ verificationElements: {
+ width: 485, marginLeft: 20, marginRight: 20
+ },
+ heading: {
+ fontSize: theme.typography.pxToRem(15),
+ fontWeight: theme.typography.fontWeightRegular,
+ },
+ moduleCollection: {
+ marginTop: "16px",
+ overflow: "auto",
+ },
+ objectReult: {
+ overflow: "auto"
+ }
});
const mapProps = (state: IApplicationStoreState) => ({
- collectingData: state.configuration.valueSelector.collectingData,
- listKeyProperty: state.configuration.valueSelector.keyProperty,
- listSpecification: state.configuration.valueSelector.listSpecification,
- listData: state.configuration.valueSelector.listData,
- vPath: state.configuration.viewDescription.vPath,
- nodeId: state.configuration.deviceDescription.nodeId,
- viewData: state.configuration.viewDescription.viewData,
- outputData: state.configuration.viewDescription.outputData,
- displaySpecification: state.configuration.viewDescription.displaySpecification,
+ collectingData: state.configuration.valueSelector.collectingData,
+ listKeyProperty: state.configuration.valueSelector.keyProperty,
+ listSpecification: state.configuration.valueSelector.listSpecification,
+ listData: state.configuration.valueSelector.listData,
+ vPath: state.configuration.viewDescription.vPath,
+ nodeId: state.configuration.deviceDescription.nodeId,
+ viewData: state.configuration.viewDescription.viewData,
+ outputData: state.configuration.viewDescription.outputData,
+ displaySpecification: state.configuration.viewDescription.displaySpecification,
});
const mapDispatch = (dispatcher: IDispatcher) => ({
- onValueSelected: (value: any) => dispatcher.dispatch(new SetSelectedValue(value)),
- onUpdateData: (vPath: string, data: any) => dispatcher.dispatch(updateDataActionAsyncCreator(vPath, data)),
- reloadView: (vPath: string) => dispatcher.dispatch(updateViewActionAsyncCreator(vPath)),
- removeElement: (vPath: string) => dispatcher.dispatch(removeElementActionAsyncCreator(vPath)),
- executeRpc: (vPath: string, data: any) => dispatcher.dispatch(executeRpcActionAsyncCreator(vPath, data)),
+ onValueSelected: (value: any) => dispatcher.dispatch(new SetSelectedValue(value)),
+ onUpdateData: (vPath: string, data: any) => dispatcher.dispatch(updateDataActionAsyncCreator(vPath, data)),
+ reloadView: (vPath: string) => dispatcher.dispatch(updateViewActionAsyncCreator(vPath)),
+ removeElement: (vPath: string) => dispatcher.dispatch(removeElementActionAsyncCreator(vPath)),
+ executeRpc: (vPath: string, data: any) => dispatcher.dispatch(executeRpcActionAsyncCreator(vPath, data)),
});
const SelectElementTable = MaterialTable as MaterialTableCtorType<{ [key: string]: any }>;
@@ -172,661 +175,694 @@ const SelectElementTable = MaterialTable as MaterialTableCtorType<{ [key: string
type ConfigurationApplicationComponentProps = RouteComponentProps & Connect<typeof mapProps, typeof mapDispatch> & WithStyles<typeof styles>;
type ConfigurationApplicationComponentState = {
- isNew: boolean;
- editMode: boolean;
- canEdit: boolean;
- viewData: { [key: string]: any } | null;
- choises: { [path: string]: { selectedCase: string, data: { [property: string]: any } } };
+ isNew: boolean;
+ editMode: boolean;
+ canEdit: boolean;
+ viewData: { [key: string]: any } | null;
+ choises: { [path: string]: { selectedCase: string, data: { [property: string]: any } } };
}
+type GetStatelessComponentProps<T> = T extends (props: infer P & { children?: React.ReactNode }) => any ? P : any
+const AccordionSummaryExt: React.FC<GetStatelessComponentProps<typeof AccordionSummary>> = (props) => {
+ const [disabled, setDisabled] = useState(true);
+ const onMouseDown = (ev: React.MouseEvent<HTMLElement>) => {
+ if (ev.button === 1) {
+ setDisabled(!disabled);
+ ev.preventDefault();
+ }
+ };
+ return (
+ <div onMouseDown={onMouseDown} >
+ <AccordionSummary {...{ ...props, disabled: props.disabled && disabled }} />
+ </div>
+ );
+};
+
const OldProps = Symbol("OldProps");
class ConfigurationApplicationComponent extends React.Component<ConfigurationApplicationComponentProps, ConfigurationApplicationComponentState> {
- /**
- *
- */
- constructor(props: ConfigurationApplicationComponentProps) {
- super(props);
-
- this.state = {
- isNew: false,
- canEdit: false,
- editMode: false,
- viewData: null,
- choises: {},
- }
+ /**
+ *
+ */
+ constructor(props: ConfigurationApplicationComponentProps) {
+ super(props);
+
+ this.state = {
+ isNew: false,
+ canEdit: false,
+ editMode: false,
+ viewData: null,
+ choises: {},
}
-
- private static getChoisesFromElements = (elements: { [name: string]: ViewElement }, viewData: any) => {
- return Object.keys(elements).reduce((acc, cur) => {
- const elm = elements[cur];
- if (isViewElementChoise(elm)) {
- const caseKeys = Object.keys(elm.cases);
-
- // find the right case for this choise, use the first one with data, at least use index 0
- const selectedCase = caseKeys.find(key => {
- const caseElm = elm.cases[key];
- return Object.keys(caseElm.elements).some(caseElmKey => {
- const caseElmElm = caseElm.elements[caseElmKey];
- return viewData[caseElmElm.label] !== undefined || viewData[caseElmElm.id] != undefined;
- });
- }) || caseKeys[0];
-
- // extract all data of the active case
- const caseElements = elm.cases[selectedCase].elements;
- const data = Object.keys(caseElements).reduce((dataAcc, dataCur) => {
- const dataElm = caseElements[dataCur];
- if (isViewElementEmpty(dataElm)) {
- dataAcc[dataElm.label] = null;
- } else if (viewData[dataElm.label] !== undefined) {
- dataAcc[dataElm.label] = viewData[dataElm.label];
- } else if (viewData[dataElm.id] !== undefined) {
- dataAcc[dataElm.id] = viewData[dataElm.id];
- }
- return dataAcc;
- }, {} as { [name: string]: any });
-
- acc[elm.id] = {
- selectedCase,
- data,
- };
- }
- return acc;
- }, {} as { [path: string]: { selectedCase: string, data: { [property: string]: any } } }) || {}
+ }
+
+ private static getChoisesFromElements = (elements: { [name: string]: ViewElement }, viewData: any) => {
+ return Object.keys(elements).reduce((acc, cur) => {
+ const elm = elements[cur];
+ if (isViewElementChoise(elm)) {
+ const caseKeys = Object.keys(elm.cases);
+
+ // find the right case for this choise, use the first one with data, at least use index 0
+ const selectedCase = caseKeys.find(key => {
+ const caseElm = elm.cases[key];
+ return Object.keys(caseElm.elements).some(caseElmKey => {
+ const caseElmElm = caseElm.elements[caseElmKey];
+ return viewData[caseElmElm.label] !== undefined || viewData[caseElmElm.id] != undefined;
+ });
+ }) || caseKeys[0];
+
+ // extract all data of the active case
+ const caseElements = elm.cases[selectedCase].elements;
+ const data = Object.keys(caseElements).reduce((dataAcc, dataCur) => {
+ const dataElm = caseElements[dataCur];
+ if (isViewElementEmpty(dataElm)) {
+ dataAcc[dataElm.label] = null;
+ } else if (viewData[dataElm.label] !== undefined) {
+ dataAcc[dataElm.label] = viewData[dataElm.label];
+ } else if (viewData[dataElm.id] !== undefined) {
+ dataAcc[dataElm.id] = viewData[dataElm.id];
+ }
+ return dataAcc;
+ }, {} as { [name: string]: any });
+
+ acc[elm.id] = {
+ selectedCase,
+ data,
+ };
+ }
+ return acc;
+ }, {} as { [path: string]: { selectedCase: string, data: { [property: string]: any } } }) || {}
+ }
+
+ static getDerivedStateFromProps(nextProps: ConfigurationApplicationComponentProps, prevState: ConfigurationApplicationComponentState & { [OldProps]: ConfigurationApplicationComponentProps }) {
+
+ if (!prevState || !prevState[OldProps] || (prevState[OldProps].viewData !== nextProps.viewData)) {
+ const isNew: boolean = nextProps.vPath?.endsWith("[]") || false;
+ const state = {
+ ...prevState,
+ isNew: isNew,
+ editMode: isNew,
+ viewData: nextProps.viewData || null,
+ [OldProps]: nextProps,
+ choises: nextProps.displaySpecification.displayMode === DisplayModeType.doNotDisplay
+ ? null
+ : nextProps.displaySpecification.displayMode === DisplayModeType.displayAsRPC
+ ? nextProps.displaySpecification.inputViewSpecification && ConfigurationApplicationComponent.getChoisesFromElements(nextProps.displaySpecification.inputViewSpecification.elements, nextProps.viewData) || []
+ : ConfigurationApplicationComponent.getChoisesFromElements(nextProps.displaySpecification.viewSpecification.elements, nextProps.viewData)
+ }
+ return state;
}
-
- static getDerivedStateFromProps(nextProps: ConfigurationApplicationComponentProps, prevState: ConfigurationApplicationComponentState & { [OldProps]: ConfigurationApplicationComponentProps }) {
-
- if (!prevState || !prevState[OldProps] || (prevState[OldProps].viewData !== nextProps.viewData)) {
- const isNew: boolean = nextProps.vPath?.endsWith("[]") || false;
- const state = {
- ...prevState,
- isNew: isNew,
- editMode: isNew,
- viewData: nextProps.viewData || null,
- [OldProps]: nextProps,
- choises: nextProps.displaySpecification.displayMode === DisplayModeType.doNotDisplay
- ? null
- : nextProps.displaySpecification.displayMode === DisplayModeType.displayAsRPC
- ? nextProps.displaySpecification.inputViewSpecification && ConfigurationApplicationComponent.getChoisesFromElements(nextProps.displaySpecification.inputViewSpecification.elements, nextProps.viewData) || []
- : ConfigurationApplicationComponent.getChoisesFromElements(nextProps.displaySpecification.viewSpecification.elements, nextProps.viewData)
+ return null;
+ }
+
+ private navigate = (path: string) => {
+ this.props.history.push(`${this.props.match.url}${path}`);
+ }
+
+ private changeValueFor = (property: string, value: any) => {
+ this.setState({
+ viewData: {
+ ...this.state.viewData,
+ [property]: value
+ }
+ });
+ }
+
+ private collectData = (elements: { [name: string]: ViewElement }) => {
+ // ensure only active choises will be contained
+ const viewData: { [key: string]: any } = { ...this.state.viewData };
+ const choiseKeys = Object.keys(elements).filter(elmKey => isViewElementChoise(elements[elmKey]));
+ const elementsToRemove = choiseKeys.reduce((acc, curChoiceKey) => {
+ const currentChoice = elements[curChoiceKey] as ViewElementChoise;
+ const selectedCase = this.state.choises[curChoiceKey].selectedCase;
+ Object.keys(currentChoice.cases).forEach(caseKey => {
+ const caseElements = currentChoice.cases[caseKey].elements;
+ if (caseKey === selectedCase) {
+ Object.keys(caseElements).forEach(caseElementKey => {
+ const elm = caseElements[caseElementKey];
+ if (isViewElementEmpty(elm)) {
+ // insert null for all empty elements
+ viewData[elm.id] = null;
}
- return state;
- }
- return null;
+ });
+ return;
+ };
+ Object.keys(caseElements).forEach(caseElementKey => {
+ acc.push(caseElements[caseElementKey]);
+ });
+ });
+ return acc;
+ }, [] as ViewElement[]);
+
+ return viewData && Object.keys(viewData).reduce((acc, cur) => {
+ if (!elementsToRemove.some(elm => elm.label === cur || elm.id === cur)) {
+ acc[cur] = viewData[cur];
+ }
+ return acc;
+ }, {} as { [key: string]: any });
+ }
+
+ private isPolicyViewElementForbidden = (element: ViewElement, dataPath: string): boolean => {
+ const policy = getAccessPolicyByUrl(`${dataPath}/${element.id}`);
+ return !(policy.GET && policy.POST);
+ }
+
+ private isPolicyModuleForbidden = (moduleName: string, dataPath: string): boolean => {
+ const policy = getAccessPolicyByUrl(`${dataPath}/${moduleName}`);
+ return !(policy.GET && policy.POST);
+ }
+
+ private getEditorForViewElement = (uiElement: ViewElement): (null | React.ComponentType<BaseProps<any>>) => {
+ if (isViewElementEmpty(uiElement)) {
+ return null;
+ } else if (isViewElementSelection(uiElement)) {
+ return UiElementSelection;
+ } else if (isViewElementBoolean(uiElement)) {
+ return UiElementBoolean;
+ } else if (isViewElementString(uiElement)) {
+ return UiElementString;
+ } else if (isViewElementDate(uiElement)) {
+ return UiElementString;
+ } else if (isViewElementNumber(uiElement)) {
+ return UiElementNumber;
+ } else if (isViewElementUnion(uiElement)) {
+ return UIElementUnion;
+ } else {
+ if (process.env.NODE_ENV !== "production") {
+ console.error(`Unknown element type - ${(uiElement as any).uiType} in ${(uiElement as any).id}.`)
+ }
+ return null;
}
-
- private navigate = (path: string) => {
- this.props.history.push(`${this.props.match.url}${path}`);
+ }
+
+ private renderUIElement = (uiElement: ViewElement, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
+ const isKey = (uiElement.label === keyProperty);
+ const canEdit = editMode && (isNew || (uiElement.config && !isKey));
+
+ // do not show elements w/o any value from the backend
+ if (viewData[uiElement.id] == null && !editMode) {
+ return null;
+ } else if (isViewElementEmpty(uiElement)) {
+ return null;
+ } else if (uiElement.isList) {
+ /* element is a leaf-list */
+ return <UiElementLeafList
+ key={uiElement.id}
+ inputValue={viewData[uiElement.id] == null ? [] : viewData[uiElement.id]}
+ value={uiElement}
+ readOnly={!canEdit}
+ disabled={editMode && !canEdit}
+ onChange={(e) => { this.changeValueFor(uiElement.id, e) }}
+ getEditorForViewElement={this.getEditorForViewElement}
+ />;
+ } else {
+ const Element = this.getEditorForViewElement(uiElement);
+ return Element != null
+ ? (
+ <Element
+ key={uiElement.id}
+ isKey={isKey}
+ inputValue={viewData[uiElement.id] == null ? '' : viewData[uiElement.id]}
+ value={uiElement}
+ readOnly={!canEdit}
+ disabled={editMode && !canEdit}
+ onChange={(e) => { this.changeValueFor(uiElement.id, e) }}
+ />)
+ : null;
}
-
- private changeValueFor = (property: string, value: any) => {
- this.setState({
- viewData: {
- ...this.state.viewData,
- [property]: value
- }
- });
+ };
+
+ // private renderUIReference = (uiElement: ViewElement, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
+ // const isKey = (uiElement.label === keyProperty);
+ // const canEdit = editMode && (isNew || (uiElement.config && !isKey));
+ // if (isViewElementObjectOrList(uiElement)) {
+ // return (
+ // <FormControl key={uiElement.id} style={{ width: 485, marginLeft: 20, marginRight: 20 }}>
+ // <Tooltip title={uiElement.description || ''}>
+ // <Button className={this.props.classes.leftButton} color="secondary" disabled={this.state.editMode} onClick={() => {
+ // this.navigate(`/${uiElement.id}`);
+ // }}>{uiElement.label}</Button>
+ // </Tooltip>
+ // </FormControl>
+ // );
+ // } else {
+ // if (process.env.NODE_ENV !== "production") {
+ // console.error(`Unknown reference type - ${(uiElement as any).uiType} in ${(uiElement as any).id}.`)
+ // }
+ // return null;
+ // }
+ // };
+
+ private renderUIChoise = (uiElement: ViewElementChoise, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
+ const isKey = (uiElement.label === keyProperty);
+
+ const currentChoise = this.state.choises[uiElement.id];
+ const currentCase = currentChoise && uiElement.cases[currentChoise.selectedCase];
+
+ const canEdit = editMode && (isNew || (uiElement.config && !isKey));
+ if (isViewElementChoise(uiElement)) {
+ const subElements = currentCase?.elements;
+ return (
+ <>
+ <FormControl key={uiElement.id} style={{ width: 485, marginLeft: 20, marginRight: 20 }}>
+ <InputLabel htmlFor={`select-${uiElement.id}`} >{uiElement.label}</InputLabel>
+ <Select
+ aria-label={uiElement.label + '-selection'}
+ required={!!uiElement.mandatory}
+ onChange={(e) => {
+ if (currentChoise.selectedCase === e.target.value) {
+ return; // nothing changed
+ }
+ this.setState({ choises: { ...this.state.choises, [uiElement.id]: { ...this.state.choises[uiElement.id], selectedCase: e.target.value as string } } });
+ }}
+ readOnly={!canEdit}
+ disabled={editMode && !canEdit}
+ value={this.state.choises[uiElement.id].selectedCase}
+ inputProps={{
+ name: uiElement.id,
+ id: `select-${uiElement.id}`,
+ }}
+ >
+ {
+ Object.keys(uiElement.cases).map(caseKey => {
+ const caseElm = uiElement.cases[caseKey];
+ return (
+ <MenuItem key={caseElm.id} value={caseKey} aria-label={caseKey}><Tooltip title={caseElm.description || ''}><div style={{ width: "100%" }}>{caseElm.label}</div></Tooltip></MenuItem>
+ );
+ })
+ }
+ </Select>
+ </FormControl>
+ {subElements
+ ? Object.keys(subElements).map(elmKey => {
+ const elm = subElements[elmKey];
+ return this.renderUIElement(elm, viewData, keyProperty, editMode, isNew);
+ })
+ : <h3>Invalid Choise</h3>
+ }
+ </>
+ );
+ } else {
+ if (process.env.NODE_ENV !== "production") {
+ console.error(`Unknown type - ${(uiElement as any).uiType} in ${(uiElement as any).id}.`)
+ }
+ return null;
}
+ };
- private collectData = (elements: { [name: string]: ViewElement }) => {
- // ensure only active choises will be contained
- const viewData: { [key: string]: any } = { ...this.state.viewData };
- const choiseKeys = Object.keys(elements).filter(elmKey => isViewElementChoise(elements[elmKey]));
- const elementsToRemove = choiseKeys.reduce((acc, curChoiceKey) => {
- const currentChoice = elements[curChoiceKey] as ViewElementChoise;
- const selectedCase = this.state.choises[curChoiceKey].selectedCase;
- Object.keys(currentChoice.cases).forEach(caseKey => {
- const caseElements = currentChoice.cases[caseKey].elements;
- if (caseKey === selectedCase) {
- Object.keys(caseElements).forEach(caseElementKey => {
- const elm = caseElements[caseElementKey];
- if (isViewElementEmpty(elm)) {
- // insert null for all empty elements
- viewData[elm.id] = null;
- }
- });
- return;
- };
- Object.keys(caseElements).forEach(caseElementKey => {
- acc.push(caseElements[caseElementKey]);
- });
- });
- return acc;
- }, [] as ViewElement[]);
+ private renderUIView = (viewSpecification: ViewSpecification, dataPath: string, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
+ const { classes } = this.props;
- return viewData && Object.keys(viewData).reduce((acc, cur) => {
- if (!elementsToRemove.some(elm => elm.label === cur || elm.id === cur)) {
- acc[cur] = viewData[cur];
- }
- return acc;
- }, {} as { [key: string]: any });
- }
- private getEditorForViewElement = (uiElement: ViewElement): (null | React.ComponentType<BaseProps<any>>) => {
- if (isViewElementEmpty(uiElement)) {
- return null;
- } else if (isViewElementSelection(uiElement)) {
- return UiElementSelection;
- } else if (isViewElementBoolean(uiElement)) {
- return UiElementBoolean;
- } else if (isViewElementString(uiElement)) {
- return UiElementString;
- } else if (isViewElementDate(uiElement)) {
- return UiElementString;
- } else if (isViewElementNumber(uiElement)) {
- return UiElementNumber;
- } else if (isViewElementUnion(uiElement)) {
- return UIElementUnion;
- } else {
- if (process.env.NODE_ENV !== "production") {
- console.error(`Unknown element type - ${(uiElement as any).uiType} in ${(uiElement as any).id}.`)
- }
- return null;
- }
- }
- private renderUIElement = (uiElement: ViewElement, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
- const isKey = (uiElement.label === keyProperty);
- const canEdit = editMode && (isNew || (uiElement.config && !isKey));
-
- // do not show elements w/o any value from the backend
- if (viewData[uiElement.id] == null && !editMode) {
- return null;
- } else if (isViewElementEmpty(uiElement)) {
- return null;
- } else if (uiElement.isList) {
- /* element is a leaf-list */
- return <UiElementLeafList
- key={uiElement.id}
- inputValue={viewData[uiElement.id] == null ? [] : viewData[uiElement.id]}
- value={uiElement}
- readOnly={!canEdit}
- disabled={editMode && !canEdit}
- onChange={(e) => { this.changeValueFor(uiElement.id, e) }}
- getEditorForViewElement={this.getEditorForViewElement}
- />;
- } else {
- const Element = this.getEditorForViewElement(uiElement);
- return Element != null
- ? (
- <Element
- key={uiElement.id}
- isKey={isKey}
- inputValue={viewData[uiElement.id] == null ? '' : viewData[uiElement.id]}
- value={uiElement}
- readOnly={!canEdit}
- disabled={editMode && !canEdit}
- onChange={(e) => { this.changeValueFor(uiElement.id, e) }}
- />)
- : null;
- }
+ const orderFunc = (vsA: ViewElement, vsB: ViewElement) => {
+ if (keyProperty) {
+ // if (vsA.label === vsB.label) return 0;
+ if (vsA.label === keyProperty) return -1;
+ if (vsB.label === keyProperty) return +1;
+ }
+
+ // if (vsA.uiType === vsB.uiType) return 0;
+ // if (vsA.uiType !== "object" && vsB.uiType !== "object") return 0;
+ // if (vsA.uiType === "object") return +1;
+ return -1;
};
- // private renderUIReference = (uiElement: ViewElement, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
- // const isKey = (uiElement.label === keyProperty);
- // const canEdit = editMode && (isNew || (uiElement.config && !isKey));
- // if (isViewElementObjectOrList(uiElement)) {
- // return (
- // <FormControl key={uiElement.id} style={{ width: 485, marginLeft: 20, marginRight: 20 }}>
- // <Tooltip title={uiElement.description || ''}>
- // <Button className={this.props.classes.leftButton} color="secondary" disabled={this.state.editMode} onClick={() => {
- // this.navigate(`/${uiElement.id}`);
- // }}>{uiElement.label}</Button>
- // </Tooltip>
- // </FormControl>
- // );
- // } else {
- // if (process.env.NODE_ENV !== "production") {
- // console.error(`Unknown reference type - ${(uiElement as any).uiType} in ${(uiElement as any).id}.`)
- // }
- // return null;
- // }
- // };
-
- private renderUIChoise = (uiElement: ViewElementChoise, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
- const isKey = (uiElement.label === keyProperty);
-
- const currentChoise = this.state.choises[uiElement.id];
- const currentCase = currentChoise && uiElement.cases[currentChoise.selectedCase];
-
- const canEdit = editMode && (isNew || (uiElement.config && !isKey));
- if (isViewElementChoise(uiElement)) {
- const subElements = currentCase?.elements;
+ const sections = Object.keys(viewSpecification.elements).reduce((acc, cur) => {
+ const elm = viewSpecification.elements[cur];
+ if (isViewElementObjectOrList(elm)) {
+ acc.references.push(elm);
+ } else if (isViewElementChoise(elm)) {
+ acc.choises.push(elm);
+ } else if (isViewElementRpc(elm)) {
+ acc.rpcs.push(elm);
+ } else {
+ acc.elements.push(elm);
+ }
+ return acc;
+ }, { elements: [] as ViewElement[], references: [] as ViewElement[], choises: [] as ViewElementChoise[], rpcs: [] as ViewElementRpc[] });
+
+ sections.elements = sections.elements.sort(orderFunc);
+
+ return (
+ <div className={classes.uiView}>
+ <div className={classes.section} />
+ {sections.elements.length > 0
+ ? (
+ <div className={classes.section}>
+ {sections.elements.map(element => this.renderUIElement(element, viewData, keyProperty, editMode, isNew))}
+ </div>
+ ) : null
+ }
+ {sections.references.length > 0
+ ? (
+ <div className={classes.section}>
+ {sections.references.map(element => (
+ <UIElementReference key={element.id} element={element} disabled={editMode || this.isPolicyViewElementForbidden(element, dataPath)} onOpenReference={(elm) => { this.navigate(`/${elm.id}`) }} />
+ ))}
+ </div>
+ ) : null
+ }
+ {sections.choises.length > 0
+ ? (
+ <div className={classes.section}>
+ {sections.choises.map(element => this.renderUIChoise(element, viewData, keyProperty, editMode, isNew))}
+ </div>
+ ) : null
+ }
+ {sections.rpcs.length > 0
+ ? (
+ <div className={classes.section}>
+ {sections.rpcs.map(element => (
+ <UIElementReference key={element.id} element={element} disabled={editMode || this.isPolicyViewElementForbidden(element, dataPath)} onOpenReference={(elm) => { this.navigate(`/${elm.id}`) }} />
+ ))}
+ </div>
+ ) : null
+ }
+ </div>
+ );
+ };
+
+ private renderUIViewSelector = (viewSpecification: ViewSpecification, dataPath: string, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
+ const { classes } = this.props;
+ // group by module name
+ const modules = Object.keys(viewSpecification.elements).reduce<{ [key: string]: ViewSpecification }>((acc, cur) => {
+ const elm = viewSpecification.elements[cur];
+ const moduleView = (acc[elm.module] = acc[elm.module] || { ...viewSpecification, elements: {} });
+ moduleView.elements[cur] = elm;
+ return acc;
+ }, {});
+
+ const moduleKeys = Object.keys(modules).sort();
+
+ return (
+ <div className={classes.moduleCollection}>
+ {
+ moduleKeys.map(key => {
+ const moduleView = modules[key];
return (
- <>
- <FormControl key={uiElement.id} style={{ width: 485, marginLeft: 20, marginRight: 20 }}>
- <InputLabel htmlFor={`select-${uiElement.id}`} >{uiElement.label}</InputLabel>
- <Select
- aria-label={uiElement.label+'-selection'}
- required={!!uiElement.mandatory}
- onChange={(e) => {
- if (currentChoise.selectedCase === e.target.value) {
- return; // nothing changed
- }
- this.setState({ choises: { ...this.state.choises, [uiElement.id]: { ...this.state.choises[uiElement.id], selectedCase: e.target.value as string } } });
- }}
- readOnly={!canEdit}
- disabled={editMode && !canEdit}
- value={this.state.choises[uiElement.id].selectedCase}
- inputProps={{
- name: uiElement.id,
- id: `select-${uiElement.id}`,
- }}
- >
- {
- Object.keys(uiElement.cases).map(caseKey => {
- const caseElm = uiElement.cases[caseKey];
- return (
- <MenuItem key={caseElm.id} value={caseKey} aria-label={caseKey}><Tooltip title={caseElm.description || ''}><div style={{ width: "100%" }}>{caseElm.label}</div></Tooltip></MenuItem>
- );
- })
- }
- </Select>
- </FormControl>
- {subElements
- ? Object.keys(subElements).map(elmKey => {
- const elm = subElements[elmKey];
- return this.renderUIElement(elm, viewData, keyProperty, editMode, isNew);
- })
- : <h3>Invalid Choise</h3>
- }
- </>
+ <Accordion key={key} defaultExpanded={moduleKeys.length < 4} aria-label={key + '-panel'} >
+ <AccordionSummaryExt expandIcon={<ExpandMoreIcon />} aria-controls={`content-${key}`} id={`header-${key}`} disabled={this.isPolicyModuleForbidden(`${key}:`, dataPath)} >
+ <Typography className={classes.heading}>{key}</Typography>
+ </AccordionSummaryExt>
+ <AccordionDetails>
+ {this.renderUIView(moduleView, dataPath, viewData, keyProperty, editMode, isNew)}
+ </AccordionDetails>
+ </Accordion>
);
- } else {
- if (process.env.NODE_ENV !== "production") {
- console.error(`Unknown type - ${(uiElement as any).uiType} in ${(uiElement as any).id}.`)
- }
- return null;
+ })
}
+ </div>
+ );
+ };
+
+ private renderUIViewList(listSpecification: ViewSpecification, dataPath: string, listKeyProperty: string, apiDocPath: string, listData: { [key: string]: any }[]) {
+ const listElements = listSpecification.elements;
+ const apiDocPathCreate = apiDocPath ? `${location.origin}${apiDocPath
+ .replace("$$$standard$$$", "topology-netconfnode%20resources%20-%20RestConf%20RFC%208040")
+ .replace("$$$action$$$", "put")}_${listKeyProperty.replace(/[\/=\-\:]/g, '_')}_` : undefined;
+
+ const navigate = (path: string) => {
+ this.props.history.push(`${this.props.match.url}${path}`);
};
- private renderUIView = (viewSpecification: ViewSpecification, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
- const { classes } = this.props;
-
- const orderFunc = (vsA: ViewElement, vsB: ViewElement) => {
- if (keyProperty) {
- // if (vsA.label === vsB.label) return 0;
- if (vsA.label === keyProperty) return -1;
- if (vsB.label === keyProperty) return +1;
- }
-
- // if (vsA.uiType === vsB.uiType) return 0;
- // if (vsA.uiType !== "object" && vsB.uiType !== "object") return 0;
- // if (vsA.uiType === "object") return +1;
- return -1;
- };
-
- const sections = Object.keys(viewSpecification.elements).reduce((acc, cur) => {
- const elm = viewSpecification.elements[cur];
- if (isViewElementObjectOrList(elm)) {
- acc.references.push(elm);
- } else if (isViewElementChoise(elm)) {
- acc.choises.push(elm);
- } else if (isViewElementRpc(elm)) {
- acc.rpcs.push(elm);
- } else {
- acc.elements.push(elm);
- }
- return acc;
- }, { elements: [] as ViewElement[], references: [] as ViewElement[], choises: [] as ViewElementChoise[], rpcs: [] as ViewElementRpc[] });
-
- sections.elements = sections.elements.sort(orderFunc);
-
- return (
- <div className={classes.uiView}>
- <div className={classes.section} />
- {sections.elements.length > 0
- ? (
- <div className={classes.section}>
- {sections.elements.map(element => this.renderUIElement(element, viewData, keyProperty, editMode, isNew))}
- </div>
- ) : null
- }
- {sections.references.length > 0
- ? (
- <div className={classes.section}>
- {sections.references.map(element => (
- <UIElementReference key={element.id} element={element} disabled={editMode} onOpenReference={(elm) => { this.navigate(`/${elm.id}`) }} />
- ))}
- </div>
- ) : null
- }
- {sections.choises.length > 0
- ? (
- <div className={classes.section}>
- {sections.choises.map(element => this.renderUIChoise(element, viewData, keyProperty, editMode, isNew))}
- </div>
- ) : null
- }
- {sections.rpcs.length > 0
- ? (
- <div className={classes.section}>
- {sections.rpcs.map(element => (
- <UIElementReference key={element.id} element={element} disabled={editMode} onOpenReference={(elm) => { this.navigate(`/${elm.id}`) }} />
- ))}
- </div>
- ) : null
- }
- </div>
- );
+ const addNewElementAction = {
+ icon: AddIcon,
+ tooltip: 'Add',
+ onClick: () => {
+ navigate("[]"); // empty key means new element
+ },
+ disabled: !listSpecification.config,
};
- private renderUIViewSelector = (viewSpecification: ViewSpecification, viewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) => {
- const { classes } = this.props;
-
- // group by module name
- const modules = Object.keys(viewSpecification.elements).reduce<{ [key: string]: ViewSpecification }>((acc, cur) => {
- const elm = viewSpecification.elements[cur];
- const moduleView = (acc[elm.module] = acc[elm.module] || { ...viewSpecification, elements: {} });
- moduleView.elements[cur] = elm;
- return acc;
- }, {});
-
- const moduleKeys = Object.keys(modules).sort();
-
- return (
- <div className={classes.moduleCollection}>
- {
- moduleKeys.map(key => {
- const moduleView = modules[key];
- return (
- <Accordion key={key} defaultExpanded={ moduleKeys.length < 4 } aria-label={key+'-panel'} >
- <AccordionSummary expandIcon={<ExpandMoreIcon />} aria-controls={`content-${key}`} id={`header-${key}`} >
- <Typography className={classes.heading}>{key}</Typography>
- </AccordionSummary>
- <AccordionDetails>
- {this.renderUIView(moduleView, viewData, keyProperty, editMode, isNew)}
- </AccordionDetails>
- </Accordion>
- );
- })
- }
- </div>
- );
+ const addWithApiDocElementAction = {
+ icon: PostAdd,
+ tooltip: 'Add',
+ onClick: () => {
+ window.open(apiDocPathCreate, '_blank');
+ },
+ disabled: !listSpecification.config,
};
- private renderUIViewList(listSpecification: ViewSpecification, listKeyProperty: string, apiDocPath: string, listData: { [key: string]: any }[]) {
- const listElements = listSpecification.elements;
- const apiDocPathCreate = apiDocPath ? `${location.origin}${apiDocPath
- .replace("$$$standard$$$","topology-netconfnode%20resources%20-%20RestConf%20RFC%208040")
- .replace("$$$action$$$","put")}_${listKeyProperty.replace(/[\/=\-\:]/g,'_')}_` : undefined;
-
- const navigate = (path: string) => {
- this.props.history.push(`${this.props.match.url}${path}`);
- };
-
- const addNewElementAction = {
- icon: AddIcon, tooltip: 'Add', onClick: () => {
- navigate("[]"); // empty key means new element
- }
- };
-
- const addWithApiDocElementAction = {
- icon: PostAdd, tooltip: 'Add', onClick: () => {
- window.open(apiDocPathCreate, '_blank');
- }
- };
-
- const { classes, removeElement } = this.props;
-
- const DeleteIconWithConfirmation: React.FC<{ rowData: { [key: string]: any }, onReload: () => void }> = (props) => {
- const confirm = useConfirm();
-
- return (
- <Tooltip title={"Remove"} >
- <IconButton className={classes.button} aria-label="remove-element-button"
- onClick={async (e) => {
- e.stopPropagation();
- e.preventDefault();
- confirm({ title: "Do you really want to delete this element ?", description: "This action is permanent!", confirmationButtonProps: { color: "secondary" } })
- .then(() => removeElement(`${this.props.vPath}[${props.rowData[listKeyProperty]}]`))
- .then(props.onReload);
- }} >
- <RemoveIcon />
- </IconButton>
- </Tooltip>
- );
- }
-
- return (
- <SelectElementTable stickyHeader idProperty={listKeyProperty} rows={listData} customActionButtons={apiDocPathCreate ? [addNewElementAction, addWithApiDocElementAction] : [addNewElementAction]} columns={
- Object.keys(listElements).reduce<ColumnModel<{ [key: string]: any }>[]>((acc, cur) => {
- const elm = listElements[cur];
- if (elm.uiType !== "object" && listData.every(entry => entry[elm.label] != null)) {
- if (elm.label !== listKeyProperty) {
- acc.push(elm.uiType === "boolean"
- ? { property: elm.label, type: ColumnType.boolean }
- : elm.uiType === "date"
- ? { property: elm.label, type: ColumnType.date }
- : { property: elm.label, type: elm.uiType === "number" ? ColumnType.numeric : ColumnType.text });
- } else {
- acc.unshift(elm.uiType === "boolean"
- ? { property: elm.label, type: ColumnType.boolean }
- : elm.uiType === "date"
- ? { property: elm.label, type: ColumnType.date }
- : { property: elm.label, type: elm.uiType === "number" ? ColumnType.numeric : ColumnType.text });
- }
- }
- return acc;
- }, []).concat([{
- property: "Actions", disableFilter: true, disableSorting: true, type: ColumnType.custom, customControl: (({ rowData }) => {
- return (
- <DeleteIconWithConfirmation rowData={rowData} onReload={() => this.props.vPath && this.props.reloadView(this.props.vPath)} />
- );
- })
- }])
- } onHandleClick={(ev, row) => {
- ev.preventDefault();
- navigate(`[${encodeURIComponent(row[listKeyProperty])}]`);
- }} ></SelectElementTable>
- );
+ const { classes, removeElement } = this.props;
+
+ const DeleteIconWithConfirmation: React.FC<{disabled?: boolean, rowData: { [key: string]: any }, onReload: () => void }> = (props) => {
+ const confirm = useConfirm();
+
+ return (
+ <Tooltip title={"Remove"} >
+ <IconButton disabled={props.disabled} className={classes.button} aria-label="remove-element-button"
+ onClick={async (e) => {
+ e.stopPropagation();
+ e.preventDefault();
+ confirm({ title: "Do you really want to delete this element ?", description: "This action is permanent!", confirmationButtonProps: { color: "secondary" } })
+ .then(() => removeElement(`${this.props.vPath}[${props.rowData[listKeyProperty]}]`))
+ .then(props.onReload);
+ }} >
+ <RemoveIcon />
+ </IconButton>
+ </Tooltip>
+ );
}
- private renderUIViewRPC(inputViewSpecification: ViewSpecification | undefined, inputViewData: { [key: string]: any }, outputViewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) {
- const { classes } = this.props;
-
- const orderFunc = (vsA: ViewElement, vsB: ViewElement) => {
- if (keyProperty) {
- // if (vsA.label === vsB.label) return 0;
- if (vsA.label === keyProperty) return -1;
- if (vsB.label === keyProperty) return +1;
- }
-
- // if (vsA.uiType === vsB.uiType) return 0;
- // if (vsA.uiType !== "object" && vsB.uiType !== "object") return 0;
- // if (vsA.uiType === "object") return +1;
- return -1;
- };
-
- const sections = inputViewSpecification && Object.keys(inputViewSpecification.elements).reduce((acc, cur) => {
- const elm = inputViewSpecification.elements[cur];
- if (isViewElementObjectOrList(elm)) {
- console.error("Object should not appear in RPC view !");
- } else if (isViewElementChoise(elm)) {
- acc.choises.push(elm);
- } else if (isViewElementRpc(elm)) {
- console.error("RPC should not appear in RPC view !");
+ return (
+ <SelectElementTable stickyHeader idProperty={listKeyProperty} rows={listData} customActionButtons={apiDocPathCreate ? [addNewElementAction, addWithApiDocElementAction] : [addNewElementAction]} columns={
+ Object.keys(listElements).reduce<ColumnModel<{ [key: string]: any }>[]>((acc, cur) => {
+ const elm = listElements[cur];
+ if (elm.uiType !== "object" && listData.every(entry => entry[elm.label] != null)) {
+ if (elm.label !== listKeyProperty) {
+ acc.push(elm.uiType === "boolean"
+ ? { property: elm.label, type: ColumnType.boolean }
+ : elm.uiType === "date"
+ ? { property: elm.label, type: ColumnType.date }
+ : { property: elm.label, type: elm.uiType === "number" ? ColumnType.numeric : ColumnType.text });
} else {
- acc.elements.push(elm);
+ acc.unshift(elm.uiType === "boolean"
+ ? { property: elm.label, type: ColumnType.boolean }
+ : elm.uiType === "date"
+ ? { property: elm.label, type: ColumnType.date }
+ : { property: elm.label, type: elm.uiType === "number" ? ColumnType.numeric : ColumnType.text });
}
- return acc;
- }, { elements: [] as ViewElement[], references: [] as ViewElement[], choises: [] as ViewElementChoise[], rpcs: [] as ViewElementRpc[] })
- || { elements: [] as ViewElement[], references: [] as ViewElement[], choises: [] as ViewElementChoise[], rpcs: [] as ViewElementRpc[] };
-
- sections.elements = sections.elements.sort(orderFunc);
-
- return (
- <>
- <div className={classes.section} />
- { sections.elements.length > 0
- ? (
- <div className={classes.section}>
- {sections.elements.map(element => this.renderUIElement(element, inputViewData, keyProperty, editMode, isNew))}
- </div>
- ) : null
- }
- { sections.choises.length > 0
- ? (
- <div className={classes.section}>
- {sections.choises.map(element => this.renderUIChoise(element, inputViewData, keyProperty, editMode, isNew))}
- </div>
- ) : null
- }
- <Button onClick={() => {
- const resultingViewData = inputViewSpecification && this.collectData(inputViewSpecification.elements);
- this.props.executeRpc(this.props.vPath!, resultingViewData);
- }} >Exec</Button>
- <div className={classes.objectReult}>
- { outputViewData !== undefined
- ? renderObject(outputViewData)
- : null
- }
- </div>
- </>
- );
+ }
+ return acc;
+ }, []).concat([{
+ property: "Actions", disableFilter: true, disableSorting: true, type: ColumnType.custom, customControl: (({ rowData }) => {
+ return (
+ <DeleteIconWithConfirmation disabled={!listSpecification.config} rowData={rowData} onReload={() => this.props.vPath && this.props.reloadView(this.props.vPath)} />
+ );
+ })
+ }])
+ } onHandleClick={(ev, row) => {
+ ev.preventDefault();
+ navigate(`[${encodeURIComponent(row[listKeyProperty])}]`);
+ }} ></SelectElementTable>
+ );
+ }
+
+ private renderUIViewRPC(inputViewSpecification: ViewSpecification | undefined, dataPath: string, inputViewData: { [key: string]: any }, outputViewData: { [key: string]: any }, keyProperty: string | undefined, editMode: boolean, isNew: boolean) {
+ const { classes } = this.props;
+
+ const orderFunc = (vsA: ViewElement, vsB: ViewElement) => {
+ if (keyProperty) {
+ // if (vsA.label === vsB.label) return 0;
+ if (vsA.label === keyProperty) return -1;
+ if (vsB.label === keyProperty) return +1;
+ }
+
+ // if (vsA.uiType === vsB.uiType) return 0;
+ // if (vsA.uiType !== "object" && vsB.uiType !== "object") return 0;
+ // if (vsA.uiType === "object") return +1;
+ return -1;
};
- private renderBreadCrumps() {
- const { editMode } = this.state;
- const { displaySpecification, vPath, nodeId } = this.props;
- const pathParts = splitVPath(vPath!, /(?:([^\/\["]+)(?:\[([^\]]*)\])?)/g); // 1 = property / 2 = optional key
- let lastPath = `/configuration`;
- let basePath = `/configuration/${nodeId}`;
- return (
- <div className={this.props.classes.header}>
- <div>
- <Breadcrumbs aria-label="breadcrumbs">
- <Link color="inherit" href="#" aria-label="back-breadcrumb"
- onClick={(ev: React.MouseEvent<HTMLElement>) => {
- ev.preventDefault();
- this.props.history.push(lastPath);
- }}>Back</Link>
- <Link color="inherit" href="#"
- aria-label={nodeId+'-breadcrumb'}
- onClick={(ev: React.MouseEvent<HTMLElement>) => {
- ev.preventDefault();
- this.props.history.push(`/configuration/${nodeId}`);
- }}><span>{nodeId}</span></Link>
- {
- pathParts.map(([prop, key], ind) => {
- const path = `${basePath}/${prop}`;
- const keyPath = key && `${basePath}/${prop}[${key}]`;
- const propTitle= prop.replace(/^[^:]+:/, "");
- const ret = (
- <span key={ind}>
- <Link color="inherit" href="#"
- aria-label={propTitle+'-breadcrumb'}
- onClick={(ev: React.MouseEvent<HTMLElement>) => {
- ev.preventDefault();
- this.props.history.push(path);
- }}><span>{propTitle}</span></Link>
- {
- keyPath && <Link color="inherit" href="#"
- aria-label={key+'-breadcrumb'}
- onClick={(ev: React.MouseEvent<HTMLElement>) => {
- ev.preventDefault();
- this.props.history.push(keyPath);
- }}>{`[${key}]`}</Link> || null
- }
- </span>
- );
- lastPath = basePath;
- basePath = keyPath || path;
- return ret;
- })
- }
- </Breadcrumbs>
- </div>
- {this.state.editMode && (
- <Fab color="secondary" aria-label="back-button" className={this.props.classes.fab} onClick={async () => {
- this.props.vPath && await this.props.reloadView(this.props.vPath);
- this.setState({ editMode: false });
- }} ><ArrowBack /></Fab>
- ) || null}
- { /* do not show edit if this is a list or it can't be edited */
- displaySpecification.displayMode === DisplayModeType.displayAsObject && displaySpecification.viewSpecification.canEdit && (<div>
- <Fab color="secondary" aria-label={editMode ? 'save-button' : 'edit-button'} className={this.props.classes.fab} onClick={() => {
- if (this.state.editMode) {
- // ensure only active choises will be contained
- const resultingViewData = this.collectData(displaySpecification.viewSpecification.elements);
- this.props.onUpdateData(this.props.vPath!, resultingViewData);
- }
- this.setState({ editMode: !editMode });
- }}>
- {editMode
- ? <SaveIcon />
- : <EditIcon />
- }
- </Fab>
- </div> || null)
- }
+ const sections = inputViewSpecification && Object.keys(inputViewSpecification.elements).reduce((acc, cur) => {
+ const elm = inputViewSpecification.elements[cur];
+ if (isViewElementObjectOrList(elm)) {
+ console.error("Object should not appear in RPC view !");
+ } else if (isViewElementChoise(elm)) {
+ acc.choises.push(elm);
+ } else if (isViewElementRpc(elm)) {
+ console.error("RPC should not appear in RPC view !");
+ } else {
+ acc.elements.push(elm);
+ }
+ return acc;
+ }, { elements: [] as ViewElement[], references: [] as ViewElement[], choises: [] as ViewElementChoise[], rpcs: [] as ViewElementRpc[] })
+ || { elements: [] as ViewElement[], references: [] as ViewElement[], choises: [] as ViewElementChoise[], rpcs: [] as ViewElementRpc[] };
+
+ sections.elements = sections.elements.sort(orderFunc);
+
+ return (
+ <>
+ <div className={classes.section} />
+ { sections.elements.length > 0
+ ? (
+ <div className={classes.section}>
+ {sections.elements.map(element => this.renderUIElement(element, inputViewData, keyProperty, editMode, isNew))}
</div>
- );
- }
-
- private renderValueSelector() {
- const { listKeyProperty, listSpecification, listData, onValueSelected } = this.props;
- if (!listKeyProperty || !listSpecification) {
- throw new Error("ListKex ot view not specified.");
+ ) : null
}
-
- return (
- <div className={this.props.classes.container}>
- <SelectElementTable stickyHeader idProperty={listKeyProperty} rows={listData} columns={
- Object.keys(listSpecification.elements).reduce<ColumnModel<{ [key: string]: any }>[]>((acc, cur) => {
- const elm = listSpecification.elements[cur];
- if (elm.uiType !== "object" && listData.every(entry => entry[elm.label] != null)) {
- if (elm.label !== listKeyProperty) {
- acc.push({ property: elm.label, type: elm.uiType === "number" ? ColumnType.numeric : ColumnType.text });
- } else {
- acc.unshift({ property: elm.label, type: elm.uiType === "number" ? ColumnType.numeric : ColumnType.text });
- }
- }
- return acc;
- }, [])
- } onHandleClick={(ev, row) => { ev.preventDefault(); onValueSelected(row); }} ></SelectElementTable>
+ { sections.choises.length > 0
+ ? (
+ <div className={classes.section}>
+ {sections.choises.map(element => this.renderUIChoise(element, inputViewData, keyProperty, editMode, isNew))}
</div>
- );
- }
-
- private renderValueEditor() {
- const { displaySpecification: ds, outputData } = this.props;
- const { viewData, editMode, isNew } = this.state;
-
- return (
- <div className={this.props.classes.container}>
- {this.renderBreadCrumps()}
- {ds.displayMode === DisplayModeType.doNotDisplay
- ? null
- : ds.displayMode === DisplayModeType.displayAsList && viewData instanceof Array
- ? this.renderUIViewList(ds.viewSpecification, ds.keyProperty!, ds.apidocPath!, viewData)
- : ds.displayMode === DisplayModeType.displayAsRPC
- ? this.renderUIViewRPC(ds.inputViewSpecification, viewData!, outputData, undefined, true, false)
- : this.renderUIViewSelector(ds.viewSpecification, viewData!, ds.keyProperty, editMode, isNew)
- }
- </div >
- );
- }
-
- private renderCollectingData() {
- return (
- <div className={this.props.classes.outer}>
- <div className={this.props.classes.inner}>
- <Loader />
- <h3>Processing ...</h3>
- </div>
- </div>
- );
+ ) : null
+ }
+ <Button onClick={() => {
+ const resultingViewData = inputViewSpecification && this.collectData(inputViewSpecification.elements);
+ this.props.executeRpc(this.props.vPath!, resultingViewData);
+ }} >Exec</Button>
+ <div className={classes.objectReult}>
+ {outputViewData !== undefined
+ ? renderObject(outputViewData)
+ : null
+ }
+ </div>
+ </>
+ );
+ };
+
+ private renderBreadCrumps() {
+ const { editMode } = this.state;
+ const { displaySpecification, vPath, nodeId } = this.props;
+ const pathParts = splitVPath(vPath!, /(?:([^\/\["]+)(?:\[([^\]]*)\])?)/g); // 1 = property / 2 = optional key
+ let lastPath = `/configuration`;
+ let basePath = `/configuration/${nodeId}`;
+ return (
+ <div className={this.props.classes.header}>
+ <div>
+ <Breadcrumbs aria-label="breadcrumbs">
+ <Link color="inherit" href="#" aria-label="back-breadcrumb"
+ onClick={(ev: React.MouseEvent<HTMLElement>) => {
+ ev.preventDefault();
+ this.props.history.push(lastPath);
+ }}>Back</Link>
+ <Link color="inherit" href="#"
+ aria-label={nodeId + '-breadcrumb'}
+ onClick={(ev: React.MouseEvent<HTMLElement>) => {
+ ev.preventDefault();
+ this.props.history.push(`/configuration/${nodeId}`);
+ }}><span>{nodeId}</span></Link>
+ {
+ pathParts.map(([prop, key], ind) => {
+ const path = `${basePath}/${prop}`;
+ const keyPath = key && `${basePath}/${prop}[${key}]`;
+ const propTitle = prop.replace(/^[^:]+:/, "");
+ const ret = (
+ <span key={ind}>
+ <Link color="inherit" href="#"
+ aria-label={propTitle + '-breadcrumb'}
+ onClick={(ev: React.MouseEvent<HTMLElement>) => {
+ ev.preventDefault();
+ this.props.history.push(path);
+ }}><span>{propTitle}</span></Link>
+ {
+ keyPath && <Link color="inherit" href="#"
+ aria-label={key + '-breadcrumb'}
+ onClick={(ev: React.MouseEvent<HTMLElement>) => {
+ ev.preventDefault();
+ this.props.history.push(keyPath);
+ }}>{`[${key}]`}</Link> || null
+ }
+ </span>
+ );
+ lastPath = basePath;
+ basePath = keyPath || path;
+ return ret;
+ })
+ }
+ </Breadcrumbs>
+ </div>
+ {this.state.editMode && (
+ <Fab color="secondary" aria-label="back-button" className={this.props.classes.fab} onClick={async () => {
+ this.props.vPath && await this.props.reloadView(this.props.vPath);
+ this.setState({ editMode: false });
+ }} ><ArrowBack /></Fab>
+ ) || null}
+ { /* do not show edit if this is a list or it can't be edited */
+ displaySpecification.displayMode === DisplayModeType.displayAsObject && displaySpecification.viewSpecification.canEdit && (<div>
+ <Fab color="secondary" aria-label={editMode ? 'save-button' : 'edit-button'} className={this.props.classes.fab} onClick={() => {
+ if (this.state.editMode) {
+ // ensure only active choises will be contained
+ const resultingViewData = this.collectData(displaySpecification.viewSpecification.elements);
+ this.props.onUpdateData(this.props.vPath!, resultingViewData);
+ }
+ this.setState({ editMode: !editMode });
+ }}>
+ {editMode
+ ? <SaveIcon />
+ : <EditIcon />
+ }
+ </Fab>
+ </div> || null)
+ }
+ </div>
+ );
+ }
+
+ private renderValueSelector() {
+ const { listKeyProperty, listSpecification, listData, onValueSelected } = this.props;
+ if (!listKeyProperty || !listSpecification) {
+ throw new Error("ListKex ot view not specified.");
}
- render() {
- return this.props.collectingData || !this.state.viewData
- ? this.renderCollectingData()
- : this.props.listSpecification
- ? this.renderValueSelector()
- : this.renderValueEditor();
- }
+ return (
+ <div className={this.props.classes.container}>
+ <SelectElementTable stickyHeader idProperty={listKeyProperty} rows={listData} columns={
+ Object.keys(listSpecification.elements).reduce<ColumnModel<{ [key: string]: any }>[]>((acc, cur) => {
+ const elm = listSpecification.elements[cur];
+ if (elm.uiType !== "object" && listData.every(entry => entry[elm.label] != null)) {
+ if (elm.label !== listKeyProperty) {
+ acc.push({ property: elm.label, type: elm.uiType === "number" ? ColumnType.numeric : ColumnType.text });
+ } else {
+ acc.unshift({ property: elm.label, type: elm.uiType === "number" ? ColumnType.numeric : ColumnType.text });
+ }
+ }
+ return acc;
+ }, [])
+ } onHandleClick={(ev, row) => { ev.preventDefault(); onValueSelected(row); }} ></SelectElementTable>
+ </div>
+ );
+ }
+
+ private renderValueEditor() {
+ const { displaySpecification: ds, outputData } = this.props;
+ const { viewData, editMode, isNew } = this.state;
+
+ return (
+ <div className={this.props.classes.container}>
+ {this.renderBreadCrumps()}
+ {ds.displayMode === DisplayModeType.doNotDisplay
+ ? null
+ : ds.displayMode === DisplayModeType.displayAsList && viewData instanceof Array
+ ? this.renderUIViewList(ds.viewSpecification, ds.dataPath!, ds.keyProperty!, ds.apidocPath!, viewData)
+ : ds.displayMode === DisplayModeType.displayAsRPC
+ ? this.renderUIViewRPC(ds.inputViewSpecification, ds.dataPath!, viewData!, outputData, undefined, true, false)
+ : this.renderUIViewSelector(ds.viewSpecification, ds.dataPath!, viewData!, ds.keyProperty, editMode, isNew)
+ }
+ </div >
+ );
+ }
+
+ private renderCollectingData() {
+ return (
+ <div className={this.props.classes.outer}>
+ <div className={this.props.classes.inner}>
+ <Loader />
+ <h3>Processing ...</h3>
+ </div>
+ </div>
+ );
+ }
+
+ render() {
+ return this.props.collectingData || !this.state.viewData
+ ? this.renderCollectingData()
+ : this.props.listSpecification
+ ? this.renderValueSelector()
+ : this.renderValueEditor();
+ }
}
export const ConfigurationApplication = withStyles(styles)(withRouter(connect(mapProps, mapDispatch)(ConfigurationApplicationComponent)));
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx b/sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx
index 5d849986d..5cac22eba 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx
+++ b/sdnr/wt/odlux/apps/configurationApp/src/views/networkElementSelector.tsx
@@ -25,7 +25,7 @@ import { MaterialTable, MaterialTableCtorType, ColumnType } from "../../../../fr
import { createConnectedNetworkElementsProperties, createConnectedNetworkElementsActions } from "../../../configurationApp/src/handlers/connectedNetworkElementsHandler";
import { NetworkElementConnection } from "../models/networkElementConnection";
-import { Tooltip, Button, IconButton } from "@material-ui/core";
+
const mapProps = (state: IApplicationStoreState) => ({
connectedNetworkElementsProperties: createConnectedNetworkElementsProperties(state),
diff --git a/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts b/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts
index c5cb8fb4c..2d38976d5 100644
--- a/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts
+++ b/sdnr/wt/odlux/apps/configurationApp/src/yang/yangParser.ts
@@ -278,6 +278,7 @@ export class YangParser {
name: "root",
language: "en-US",
canEdit: false,
+ config: true,
parentView: "0",
title: "root",
elements: {},
@@ -544,6 +545,28 @@ export class YangParser {
console.warn(error.message);
}
});
+
+ // resolve readOnly
+ const resolveReadOnly = (view: ViewSpecification, parentConfig: boolean) => {
+
+ // update view config
+ view.config = view.config && parentConfig;
+
+ Object.keys(view.elements).forEach((key) => {
+ const elm = view.elements[key];
+
+ // update element config
+ elm.config = elm.config && view.config;
+
+ // update all sub-elements of objects
+ if (elm.uiType === "object") {
+ resolveReadOnly(this.views[+elm.viewId], elm.config);
+ }
+
+ })
+ }
+
+ const dump = resolveReadOnly(this.views[0], true);
};
private _nextId = 1;
@@ -686,7 +709,7 @@ export class YangParser {
module: context.name || module.name || '',
uiType: "object",
viewId: currentView.id,
- config: config
+ config: currentView.config,
});
acc.push(currentView, ...subViews);
return acc;
@@ -717,7 +740,7 @@ export class YangParser {
uiType: "object",
viewId: currentView.id,
key: key,
- config: elmConfig
+ config: elmConfig && currentView.config,
});
acc.push(currentView, ...subViews);
return acc;
@@ -876,6 +899,7 @@ export class YangParser {
title: statement.arg != null ? statement.arg : undefined,
language: "en-us",
canEdit: false,
+ config: config,
ifFeature: ifFeature,
when: whenCondition,
elements: elements.reduce<{ [name: string]: ViewElement }>((acc, cur) => {
@@ -921,7 +945,7 @@ export class YangParser {
const elm = groupingViewSpec.elements[key];
// a useRef on root level need a namespace
viewSpec.elements[parentId === 0 ? `${module.name}:${key}` : key] = {
- ...groupingViewSpec.elements[key],
+ ...elm,
when: elm.when ? `(${groupingViewSpec.when}) and (${elm.when})` : groupingViewSpec.when,
ifFeature: elm.ifFeature ? `(${groupingViewSpec.ifFeature}) and (${elm.ifFeature})` : groupingViewSpec.ifFeature,
};
diff --git a/sdnr/wt/odlux/apps/connectApp/package.json b/sdnr/wt/odlux/apps/connectApp/package.json
index 836af66ee..4fae39ccb 100644
--- a/sdnr/wt/odlux/apps/connectApp/package.json
+++ b/sdnr/wt/odlux/apps/connectApp/package.json
@@ -24,17 +24,17 @@
"@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/policies.json b/sdnr/wt/odlux/apps/connectApp/policies.json
new file mode 100644
index 000000000..2ec73612e
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/policies.json
@@ -0,0 +1,12 @@
+[
+ {
+ "path": "/rests/**/node=Sim2230**",
+ "methods": {
+ "get": true,
+ "post": false,
+ "put": false,
+ "delete": false,
+ "patch": false
+ }
+ }
+] \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts b/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts
index a3bdc6828..a83e00239 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/actions/commonNetworkElementsActions.ts
@@ -23,13 +23,13 @@ import { Action } from '../../../../framework/src/flux/action';
import { Dispatch } from '../../../../framework/src/flux/store';
import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
-import { networkElementsReloadAction, networkElementsReloadActionAsync } from '../handlers/networkElementsHandler';
+import { networkElementsReloadAction } from '../handlers/networkElementsHandler';
import { connectionStatusLogReloadAction } from '../handlers/connectionStatusLogHandler';
import { PanelId } from '../models/panelId';
import { guiCutThrough } from '../models/guiCutTrough';
-import connectService from '../services/connectService';
-import { NetworkElementConnection } from '../models/networkElementConnection';
+import { connectService} from '../services/connectService';
+
export class SetPanelAction extends Action {
constructor(public panelId: PanelId) {
@@ -38,7 +38,7 @@ export class SetPanelAction extends Action {
}
export class AddWebUriList extends Action {
- constructor(public searchedElements: guiCutThrough[], public notSearchedElements: string[], public unsupportedElements: string[], public newlySearchedElements?: string[] ) {
+ constructor(public searchedElements: guiCutThrough[], public notSearchedElements: string[], public unsupportedElements: string[], public newlySearchedElements?: string[]) {
super();
}
}
@@ -60,49 +60,47 @@ export class SetWeburiSearchBusy extends Action {
}
let isBusy = false;
-export const findWebUrisForGuiCutThroughAsyncAction = (networkElements: NetworkElementConnection[]) => async (dispatcher: Dispatch, getState: () => IApplicationStoreState) => {
+export const findWebUrisForGuiCutThroughAsyncAction = (networkElementIds: string[]) => async (dispatcher: Dispatch, getState: () => IApplicationStoreState) => {
// keep method from executing simultanously; state not used because change of iu isn't needed
- if (isBusy)
- return;
- isBusy = true;
- const { connect: { guiCutThrough } } = getState();
+
+ const { connect: { guiCutThrough, networkElements } } = getState();
let notConnectedElements: string[] = [];
let elementsToSearch: string[] = [];
let prevFoundElements: string[] = [];
- let unsupportedElements: string[]= [];
+ let unsupportedElements: string[] = [];
-
- networkElements.forEach(item => {
- const id = item.id as string;
+ networkElementIds.forEach(id => {
+ const item = networkElements.rows.find((ne) => ne.id === id);
+ if (item) {
if (item.status === "Connected") {
- if(item.coreModelCapability!== "Unsupported"){
+ // if (item.coreModelCapability !== "Unsupported") {
// element is connected and is added to search list, if it doesn't exist already
- const exists = guiCutThrough.searchedElements.filter(element => element.nodeId === id).length > 0;
+ const exists = guiCutThrough.searchedElements.filter(element => element.id === id).length > 0;
if (!exists) {
elementsToSearch.push(id);
-
+
//element was found previously, but wasn't connected
if (guiCutThrough.notSearchedElements.length > 0 && guiCutThrough.notSearchedElements.includes(id)) {
prevFoundElements.push(id);
}
- }
- }else{
- // element does not support core model and must not be searched for a weburi
- const id = item.id as string;
- const exists = guiCutThrough.unsupportedElements.filter(element => element === id).length > 0;
- if(!exists){
- unsupportedElements.push(id);
-
- //element was found previously, but wasn't connected
- if (guiCutThrough.notSearchedElements.length > 0 && guiCutThrough.notSearchedElements.includes(id)) {
- prevFoundElements.push(id);
- }
}
- }
+ // } else {
+ // // element does not support core model and must not be searched for a weburi
+ // const id = item.id as string;
+ // const exists = guiCutThrough.unsupportedElements.filter(element => element === id).length > 0;
+ // if (!exists) {
+ // unsupportedElements.push(id);
+
+ // //element was found previously, but wasn't connected
+ // if (guiCutThrough.notSearchedElements.length > 0 && guiCutThrough.notSearchedElements.includes(id)) {
+ // prevFoundElements.push(id);
+ // }
+ // }
+ // }
}
else {
// element isn't connected and cannot be searched for a weburi
@@ -110,25 +108,25 @@ export const findWebUrisForGuiCutThroughAsyncAction = (networkElements: NetworkE
notConnectedElements.push(item.id as string);
}
}
+ }
});
-
- if (elementsToSearch.length > 0 || notConnectedElements.length > 0 || unsupportedElements.length>0 ) {
- const result = await connectService.getAllWebUriExtensionsForNetworkElementListAsync(elementsToSearch);
- dispatcher(new AddWebUriList(result, notConnectedElements, unsupportedElements, prevFoundElements));
+
+ if (elementsToSearch.length > 0 || notConnectedElements.length > 0 || unsupportedElements.length > 0) {
+ const result = await connectService.getAllWebUriExtensionsForNetworkElementListAsync(elementsToSearch);
+ dispatcher(new AddWebUriList(result, notConnectedElements, unsupportedElements, prevFoundElements));
}
- isBusy = false;
}
export const setPanelAction = (panelId: PanelId) => {
return new SetPanelAction(panelId);
}
-export const updateCurrentViewAsyncAction = () => async (dispatch: Dispatch, getState: () => IApplicationStoreState) => {
+export const updateCurrentViewAsyncAction = () => (dispatch: Dispatch, getState: () => IApplicationStoreState) => {
const { connect: { currentOpenPanel } } = getState();
if (currentOpenPanel === "NetworkElements") {
- return await dispatch(networkElementsReloadActionAsync);
+ return dispatch(networkElementsReloadAction);
}
else {
return dispatch(connectionStatusLogReloadAction);
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx
index f2fd2937d..94b4872dd 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/connectionStatusLog.tsx
@@ -19,9 +19,11 @@ import * as React from 'react';
import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect';
import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
+import Refresh from '@material-ui/icons/Refresh';
import { createConnectionStatusLogActions, createConnectionStatusLogProperties } from '../handlers/connectionStatusLogHandler';
import { NetworkElementConnectionLog } from '../models/networkElementConnectionLog';
+import RefreshConnectionStatusLogDialog, { RefreshConnectionStatusLogDialogMode } from './refreshConnectionStatusLogDialog';
const mapProps = (state: IApplicationStoreState) => ({
connectionStatusLogProperties: createConnectionStatusLogProperties(state),
@@ -34,22 +36,52 @@ const mapDispatch = (dispatcher: IDispatcher) => ({
const ConnectionStatusTable = MaterialTable as MaterialTableCtorType<NetworkElementConnectionLog>;
type ConnectionStatusLogComponentProps = Connect<typeof mapProps, typeof mapDispatch>;
+type ConnectionStatusLogComponentState = {
+ refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode
+}
let initialSorted = false;
-class ConnectionStatusLogComponent extends React.Component<ConnectionStatusLogComponentProps> {
+class ConnectionStatusLogComponent extends React.Component<ConnectionStatusLogComponentProps,ConnectionStatusLogComponentState > {
+ constructor(props: ConnectionStatusLogComponentProps) {
+ super(props);
+
+ this.state = {
+ refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.None
+ };
+ }
+
render(): JSX.Element {
+ const refreshConnectionStatusLogAction = {
+ icon: Refresh, tooltip: 'Refresh Connection Status Log Table', onClick: () => {
+ this.setState({
+ refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.RefreshConnectionStatusLogTable
+ });
+ }
+ };
+
return (
- <ConnectionStatusTable stickyHeader tableId="connection-status-table" columns={[
+ <>
+ <ConnectionStatusTable stickyHeader tableId="connection-status-table" customActionButtons={[refreshConnectionStatusLogAction]} columns={[
{ property: "timestamp", title: "Timestamp", type: ColumnType.text },
{ property: "nodeId", title: "Node Name", type: ColumnType.text },
{ property: "status", title: "Connection Status", type: ColumnType.text },
]} idProperty="id" {...this.props.connectionStatusLogActions} {...this.props.connectionStatusLogProperties} >
</ConnectionStatusTable>
+ <RefreshConnectionStatusLogDialog
+ mode={ this.state.refreshConnectionStatusLogEditorMode }
+ onClose={ this.onCloseRefreshConnectionStatusLogDialog }
+ />
+ </>
);
};
+ private onCloseRefreshConnectionStatusLogDialog = () => {
+ this.setState({
+ refreshConnectionStatusLogEditorMode: RefreshConnectionStatusLogDialogMode.None
+ });
+ }
componentDidMount() {
if (!initialSorted) {
initialSorted = true;
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx
index 53e10481a..84a22a99a 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/networkElements.tsx
@@ -19,12 +19,14 @@ import * as React from 'react';
import { Theme, createStyles, withStyles, WithStyles } from '@material-ui/core/styles';
import AddIcon from '@material-ui/icons/Add';
+import Refresh from '@material-ui/icons/Refresh';
import LinkIcon from '@material-ui/icons/Link';
import LinkOffIcon from '@material-ui/icons/LinkOff';
import RemoveIcon from '@material-ui/icons/RemoveCircleOutline';
import EditIcon from '@material-ui/icons/Edit';
import Info from '@material-ui/icons/Info';
import ComputerIcon from '@material-ui/icons/Computer';
+import { MenuItem, Divider, Typography } from '@material-ui/core';
import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
@@ -34,12 +36,14 @@ import { NavigateToApplication } from '../../../../framework/src/actions/navigat
import { createNetworkElementsActions, createNetworkElementsProperties } from '../handlers/networkElementsHandler';
import { NetworkElementConnection } from '../models/networkElementConnection';
+import { TopologyNode } from '../models/topologyNetconf';
import EditNetworkElementDialog, { EditNetworkElementDialogMode } from './editNetworkElementDialog';
+import RefreshNetworkElementsDialog, { RefreshNetworkElementsDialogMode } from './refreshNetworkElementsDialog';
import InfoNetworkElementDialog, { InfoNetworkElementDialogMode } from './infoNetworkElementDialog';
import { loadAllInfoElementAsync } from '../actions/infoNetworkElementActions';
-import { TopologyNode } from '../models/topologyNetconf';
-import { MenuItem, Divider, Typography } from '@material-ui/core';
+import { connectService } from '../services/connectService';
+import { getAccessPolicyByUrl } from '../../../../framework/src/services/restService';
const styles = (theme: Theme) => createStyles({
connectionStatusConnected: {
@@ -63,6 +67,22 @@ const styles = (theme: Theme) => createStyles({
}
});
+type GetStatelessComponentProps<T> = T extends (props: infer P & { children?: React.ReactNode }) => any ? P : any
+const MenuItemExt : React.FC<GetStatelessComponentProps<typeof MenuItem>> = (props) => {
+ const [disabled, setDisabled] = React.useState(true);
+ const onMouseDown = (ev: React.MouseEvent<HTMLElement>) => {
+ if (ev.button ===1){
+ setDisabled(!disabled);
+ ev.preventDefault();
+ }
+ };
+ return (
+ <div onMouseDown={onMouseDown} >
+ <MenuItem {...{...props, disabled: props.disabled && disabled }} />
+ </div>
+ );
+};
+
const mapProps = (state: IApplicationStoreState) => ({
networkElementsProperties: createNetworkElementsProperties(state),
applicationState: state,
@@ -78,6 +98,7 @@ type NetworkElementsListComponentProps = WithStyles<typeof styles> & Connect<typ
type NetworkElementsListComponentState = {
networkElementToEdit: NetworkElementConnection,
networkElementEditorMode: EditNetworkElementDialogMode,
+ refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode,
infoNetworkElementEditorMode: InfoNetworkElementDialogMode,
elementInfo: TopologyNode | null
}
@@ -94,19 +115,21 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement
this.state = {
networkElementToEdit: emptyRequireNetworkElement,
networkElementEditorMode: EditNetworkElementDialogMode.None,
+ refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.None,
elementInfo: null,
infoNetworkElementEditorMode: InfoNetworkElementDialogMode.None
};
}
-
+
getContextMenu(rowData: NetworkElementConnection): JSX.Element[] {
-
-
-
- const { configuration, fault, inventory } = this.props.applicationState as any;
- let buttonArray = [
- <MenuItem aria-label={"mount-button"} onClick={event => this.onOpenMountdNetworkElementsDialog(event, rowData)} ><LinkIcon /><Typography>Mount</Typography></MenuItem>,
- <MenuItem aria-label={"unmount-button"} onClick={event => this.onOpenUnmountdNetworkElementsDialog(event, rowData)}><LinkOffIcon /><Typography>Unmount</Typography></MenuItem>,
+ const mountUri = rowData.id && connectService.getNetworkElementUri(rowData.id);
+ const mountPolicy = mountUri && getAccessPolicyByUrl(mountUri);
+ const canMount = mountPolicy && mountPolicy.POST || false;
+
+ const { configuration} = this.props.applicationState as any;
+ const buttonArray = [
+ <MenuItemExt aria-label={"mount-button"} onClick={event => this.onOpenMountdNetworkElementsDialog(event, rowData)} disabled={!canMount} ><LinkIcon /><Typography>Mount</Typography></MenuItemExt>,
+ <MenuItemExt aria-label={"unmount-button"} onClick={event => this.onOpenUnmountdNetworkElementsDialog(event, rowData)} disabled={!canMount} ><LinkOffIcon /><Typography>Unmount</Typography></MenuItemExt>,
<Divider />,
<MenuItem aria-label={"info-button"} onClick={event => this.onOpenInfoNetworkElementDialog(event, rowData)} disabled={rowData.status === "Connecting" || rowData.status === "Disconnected"} ><Info /><Typography>Info</Typography></MenuItem>,
<MenuItem aria-label={"edit-button"} onClick={event => this.onOpenEditNetworkElementDialog(event, rowData)}><EditIcon /><Typography>Edit</Typography></MenuItem>,
@@ -121,9 +144,9 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement
<MenuItem onClick={event => this.props.navigateToApplication("security", rowData.nodeId)} disabled={true} ><Typography>Security</Typography></MenuItem>,
];
- if (rowData.webUri) {
+ if (rowData.weburi) {
// add an icon for gui cuttrough, if weburi is available
- return [<MenuItem aria-label={"web-client-button"} onClick={event => window.open(rowData.webUri, "_blank")} ><ComputerIcon /><Typography>Web Client</Typography></MenuItem>].concat(buttonArray)
+ return [<MenuItem aria-label={"web-client-button"} onClick={event => window.open(rowData.weburi, "_blank")} ><ComputerIcon /><Typography>Web Client</Typography></MenuItem>].concat(buttonArray)
} else {
return buttonArray;
}
@@ -134,6 +157,12 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement
render(): JSX.Element {
const { classes } = this.props;
const { networkElementToEdit } = this.state;
+
+ // const mountUri = rowData.id && connectService.getNetworkElementUri(rowData.id);
+ // const mountPolicy = mountUri && getAccessPolicyByUrl(mountUri);
+ // const canAdd = mountPolicy && mountPolicy.POST || false;
+ const canAdd = true;
+
const addRequireNetworkElementAction = {
icon: AddIcon, tooltip: 'Add', onClick: () => {
this.setState({
@@ -143,9 +172,17 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement
}
};
+ const refreshNetworkElementsAction = {
+ icon: Refresh, tooltip: 'Refresh Network Elements table', onClick: () => {
+ this.setState({
+ refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.RefreshNetworkElementsTable
+ });
+ }
+ };
+
return (
<>
- <NetworkElementTable stickyHeader tableId="network-element-table" customActionButtons={[addRequireNetworkElementAction]} columns={[
+ <NetworkElementTable stickyHeader tableId="network-element-table" customActionButtons={[refreshNetworkElementsAction, ...canAdd ? [addRequireNetworkElementAction]: []]} columns={[
{ property: "nodeId", title: "Node Name", type: ColumnType.text },
{ property: "isRequired", title: "Required", type: ColumnType.boolean },
{ property: "status", title: "Connection Status", type: ColumnType.text },
@@ -163,6 +200,10 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement
mode={this.state.networkElementEditorMode}
onClose={this.onCloseEditNetworkElementDialog}
/>
+ <RefreshNetworkElementsDialog
+ mode={this.state.refreshNetworkElementsEditorMode}
+ onClose={this.onCloseRefreshNetworkElementsDialog}
+ />
<InfoNetworkElementDialog
initialNetworkElement={networkElementToEdit}
mode={this.state.infoNetworkElementEditorMode}
@@ -243,7 +284,11 @@ export class NetworkElementsListComponent extends React.Component<NetworkElement
networkElementToEdit: emptyRequireNetworkElement,
});
}
+ private onCloseRefreshNetworkElementsDialog = () => {
+ this.setState({
+ refreshNetworkElementsEditorMode: RefreshNetworkElementsDialogMode.None
+ });
+ }
}
export const NetworkElementsList = withStyles(styles)(connect(mapProps, mapDispatch)(NetworkElementsListComponent));
-export default NetworkElementsList; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/refreshConnectionStatusLogDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/refreshConnectionStatusLogDialog.tsx
new file mode 100644
index 000000000..41229eae6
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/refreshConnectionStatusLogDialog.tsx
@@ -0,0 +1,117 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH 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 * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+import { connectionStatusLogReloadAction } from '../handlers/connectionStatusLogHandler';
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { ConnectionStatusLogType } from '../models/connectionStatusLog';
+
+export enum RefreshConnectionStatusLogDialogMode {
+ None = "none",
+ RefreshConnectionStatusLogTable = "RefreshConnectionStatusLogTable",
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ refreshConnectionStatusLog: () => dispatcher.dispatch(connectionStatusLogReloadAction)
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ applyButtonText: string,
+ cancelButtonText: string,
+ enableMountIdEditor: boolean,
+ enableUsernameEditor: boolean,
+ enableExtendedEditor: boolean,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [RefreshConnectionStatusLogDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ applyButtonText: "",
+ cancelButtonText: "",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ },
+ [RefreshConnectionStatusLogDialogMode.RefreshConnectionStatusLogTable]: {
+ dialogTitle: "Do you want to refresh the Connection Status Log table?",
+ dialogDescription: "",
+ applyButtonText: "Yes",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: true,
+ enableUsernameEditor: true,
+ enableExtendedEditor: true,
+ }
+}
+
+type RefreshConnectionStatusLogDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: RefreshConnectionStatusLogDialogMode;
+ onClose: () => void;
+};
+
+type RefreshConnectionStatusLogDialogComponentState = ConnectionStatusLogType & { isNameValid: boolean, isHostSet: boolean };
+
+class RefreshConnectionStatusLogDialogComponent extends React.Component<RefreshConnectionStatusLogDialogComponentProps, RefreshConnectionStatusLogDialogComponentState> {
+ constructor(props: RefreshConnectionStatusLogDialogComponentProps) {
+ super(props);
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ return (
+ <Dialog open={this.props.mode !== RefreshConnectionStatusLogDialogMode.None}>
+ <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button aria-label="dialog-confirm-button" onClick={(event) => {
+ this.onRefresh();
+ }} > {setting.applyButtonText} </Button>
+ <Button aria-label="dialog-cancel-button" onClick={(event) => {
+ this.onCancel();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onRefresh = () => {
+ this.props.refreshConnectionStatusLog();
+ this.props.onClose();
+ };
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+}
+
+export const RefreshConnectionStatusLogDialog = connect(undefined, mapDispatch)(RefreshConnectionStatusLogDialogComponent);
+export default RefreshConnectionStatusLogDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/components/refreshNetworkElementsDialog.tsx b/sdnr/wt/odlux/apps/connectApp/src/components/refreshNetworkElementsDialog.tsx
new file mode 100644
index 000000000..a349977ab
--- /dev/null
+++ b/sdnr/wt/odlux/apps/connectApp/src/components/refreshNetworkElementsDialog.tsx
@@ -0,0 +1,117 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH 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 * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+import { networkElementsReloadAction } from '../handlers/networkElementsHandler';
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { NetworkElementConnection } from '../models/networkElementConnection';
+
+export enum RefreshNetworkElementsDialogMode {
+ None = "none",
+ RefreshNetworkElementsTable = "RefreshNetworkElementsTable",
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ refreshNetworkElement: () => dispatcher.dispatch(networkElementsReloadAction)
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ applyButtonText: string,
+ cancelButtonText: string,
+ enableMountIdEditor: boolean,
+ enableUsernameEditor: boolean,
+ enableExtendedEditor: boolean,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [RefreshNetworkElementsDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ applyButtonText: "",
+ cancelButtonText: "",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ },
+ [RefreshNetworkElementsDialogMode.RefreshNetworkElementsTable]: {
+ dialogTitle: "Do you want to refresh the Network Elements table?",
+ dialogDescription: "",
+ applyButtonText: "Yes",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: true,
+ enableUsernameEditor: true,
+ enableExtendedEditor: true,
+ }
+}
+
+type RefreshNetworkElementsDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: RefreshNetworkElementsDialogMode;
+ onClose: () => void;
+};
+
+type RefreshNetworkElementsDialogComponentState = NetworkElementConnection & { isNameValid: boolean, isHostSet: boolean };
+
+class RefreshNetworkElementsDialogComponent extends React.Component<RefreshNetworkElementsDialogComponentProps, RefreshNetworkElementsDialogComponentState> {
+ constructor(props: RefreshNetworkElementsDialogComponentProps) {
+ super(props);
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ return (
+ <Dialog open={this.props.mode !== RefreshNetworkElementsDialogMode.None}>
+ <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button aria-label="dialog-confirm-button" onClick={(event) => {
+ this.onRefresh();
+ }} > {setting.applyButtonText} </Button>
+ <Button aria-label="dialog-cancel-button" onClick={(event) => {
+ this.onCancel();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onRefresh = () => {
+ this.props.refreshNetworkElement();
+ this.props.onClose();
+ };
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+}
+
+export const RefreshNetworkElementsDialog = connect(undefined, mapDispatch)(RefreshNetworkElementsDialogComponent);
+export default RefreshNetworkElementsDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts
index 302a981eb..c23e43924 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/connectAppRootHandler.ts
@@ -68,7 +68,7 @@ const guiCutThroughHandler: IActionHandler<guiCutThroughState> = (state = { sear
} else if (action instanceof RemoveWebUri) {
const nodeId = action.element;
- const webUris = state.searchedElements.filter(item => item.nodeId !== nodeId);
+ const webUris = state.searchedElements.filter(item => item.id !== nodeId);
const knownElements = state.notSearchedElements.filter(item => item !== nodeId);
const unsupportedElement = state.unsupportedElements.filter(item => item != nodeId);
state = { notSearchedElements: knownElements, searchedElements: webUris, unsupportedElements: unsupportedElement };
diff --git a/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts b/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts
index 4fe858c69..b74a39427 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/handlers/networkElementsHandler.ts
@@ -17,10 +17,11 @@
*/
import { createExternal, IExternalTableState } from '../../../../framework/src/components/material-table/utilities';
import { createSearchDataHandler } from '../../../../framework/src/utilities/elasticSearch';
+import { getAccessPolicyByUrl } from '../../../../framework/src/services/restService';
import { NetworkElementConnection } from '../models/networkElementConnection';
-import connectService from '../services/connectService';
-import { requestRest } from '../../../../framework/src/services/restService';
+import { connectService } from '../services/connectService';
+
export interface INetworkElementsState extends IExternalTableState<NetworkElementConnection> { }
// create eleactic search material data fetch handler
@@ -31,8 +32,7 @@ export const {
createActions: createNetworkElementsActions,
createProperties: createNetworkElementsProperties,
reloadAction: networkElementsReloadAction,
- reloadActionAsync: networkElementsReloadActionAsync
-
+
// set value action, to change a value
} = createExternal<NetworkElementConnection>(networkElementsSearchHandler, appState => {
@@ -43,9 +43,9 @@ export const {
appState.connect.networkElements.rows.forEach(element => {
if (element.status === "Connected") {
- const webUri = webUris.find(item => item.nodeId === element.id as string);
+ const webUri = webUris.find(item => item.id === element.id as string);
if (webUri) {
- element.webUri = webUri.webUri;
+ element.weburi = webUri.weburi;
element.isWebUriUnreachable = false;
}
else {
@@ -56,5 +56,10 @@ export const {
}
return appState.connect.networkElements
+}, (ne) => {
+ if (!ne || !ne.id) return true;
+ const neUrl = connectService.getNetworkElementUri(ne.id);
+ const policy = getAccessPolicyByUrl(neUrl);
+ return !(policy.GET || policy.POST);
});
diff --git a/sdnr/wt/odlux/apps/connectApp/src/index.html b/sdnr/wt/odlux/apps/connectApp/src/index.html
index 9c8a2063e..6f44c25f7 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/index.html
+++ b/sdnr/wt/odlux/apps/connectApp/src/index.html
@@ -19,6 +19,7 @@
connectApp.register();
faultApp.register();
inventoryApp.register();
+ app("./app.tsx").configureApplication({ authentication:"basic", enablePolicy: false,});
app("./app.tsx").runApplication();
});
</script>
diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts b/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts
index d44eea685..b9f515dc8 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/models/guiCutTrough.ts
@@ -16,4 +16,7 @@
* ============LICENSE_END==========================================================================
*/
-export type guiCutThrough = { webUri?: string, nodeId: string } \ No newline at end of file
+export type guiCutThrough = {
+ id: string,
+ weburi?: string
+} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts
index b3586d693..71eddc808 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/models/networkElementConnection.ts
@@ -24,7 +24,7 @@ export type NetworkElementConnection = {
port: number;
username?: string;
password?: string;
- webUri?: string;
+ weburi?: string;
isWebUriUnreachable?: boolean;
status?: "Connected" | "mounted" | "unmounted" | "Connecting" | "Disconnected" | "idle";
coreModelCapability?: string;
diff --git a/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx b/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx
index f711c440c..93bed1aad 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/pluginConnect.tsx
@@ -20,19 +20,12 @@ import { faPlug } from '@fortawesome/free-solid-svg-icons';
import applicationManager from '../../../framework/src/services/applicationManager';
import { subscribe, IFormatedMessage } from '../../../framework/src/services/notificationService';
+import { AddSnackbarNotification } from '../../../framework/src/actions/snackbarActions';
import connectAppRootHandler from './handlers/connectAppRootHandler';
import ConnectApplication from './views/connectView';
-import { AddSnackbarNotification } from '../../../framework/src/actions/snackbarActions';
-import { updateCurrentViewAsyncAction } from './actions/commonNetworkElementsActions';
-
-type ObjectNotification = {
- counter: string;
- nodeName: string;
- objectId: string;
- timeStamp: string;
-}
+import { findWebUrisForGuiCutThroughAsyncAction, updateCurrentViewAsyncAction } from './actions/commonNetworkElementsActions';
export function register() {
const applicationApi = applicationManager.registerApplication({
@@ -44,13 +37,19 @@ export function register() {
});
// subscribe to the websocket notifications
- subscribe<ObjectNotification & IFormatedMessage>(["ObjectCreationNotification", "ObjectDeletionNotification", "AttributeValueChangedNotification"], (msg => {
+ subscribe<IFormatedMessage>(["object-creation-notification", "object-deletion-notification", "attribute-value-changed-notification"], (msg => {
const store = applicationApi.applicationStore;
- if (msg && msg.notifType === "ObjectCreationNotification" && store) {
- store.dispatch(new AddSnackbarNotification({ message: `Adding network element [${msg.objectId}]`, options: { variant: 'info' } }));
- } else if (msg && (msg.notifType === "ObjectDeletionNotification" || msg.notifType === "AttributeValueChangedNotification") && store) {
- store.dispatch(new AddSnackbarNotification({ message: `Updating network element [${msg.objectId}]`, options: { variant: 'info' } }));
+ if (msg && msg.type.type === "object-creation-notification" && store) {
+ store.dispatch(new AddSnackbarNotification({ message: `Adding network element [${msg['node-id']}]`, options: { variant: 'info' } }));
+ } else if (msg && (msg.type.type === "object-deletion-notification" || msg.type.type === "attribute-value-changed-notification") && store) {
+ store.dispatch(new AddSnackbarNotification({ message: `Updating network element [${msg['node-id']}]`, options: { variant: 'info' } }));
+ }
+ if (store) {
+ store.dispatch(updateCurrentViewAsyncAction() as any).then(() => {
+ if (msg['node-id']) {
+ store.dispatch(findWebUrisForGuiCutThroughAsyncAction([msg['node-id']]));
+ }
+ });
}
- store && store.dispatch(updateCurrentViewAsyncAction());
}));
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts b/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts
index fbbfa68d9..5d7667a7f 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts
+++ b/sdnr/wt/odlux/apps/connectApp/src/services/connectService.ts
@@ -28,12 +28,15 @@ import { guiCutThrough } from '../models/guiCutTrough';
* Represents a web api accessor service for all Network Elements actions.
*/
class ConnectService {
+ public getNetworkElementUri = (nodeId: string) => '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId;
+ public getNetworkElementConnectDataProviderUri = (operation: "create" | "update" | "delete" ) => `/rests/operations/data-provider:${operation}-network-element-connection`;
+ public getAllWebUriExtensionsForNetworkElementListUri = (nodeId: string) => this.getNetworkElementUri(nodeId) + '/yang-ext:mount/core-model:network-element';
/**
* Inserts a network elements.
*/
public async createNetworkElement(element: NetworkElementConnection): Promise<NetworkElementConnection | null> {
- const path = `/rests/operations/data-provider:create-network-element-connection`;
+ const path = this.getNetworkElementConnectDataProviderUri("create") ;
const result = await requestRest<NetworkElementConnection>(path, {
method: "POST", body: JSON.stringify(convertPropertyNames({ "data-provider:input": element }, replaceUpperCase))
});
@@ -44,7 +47,7 @@ class ConnectService {
* Updates a network element.
*/
public async updateNetworkElement(element: UpdateNetworkElement): Promise<NetworkElementConnection | null> {
- const path = `/rests/operations/data-provider:update-network-element-connection`;
+ const path = this.getNetworkElementConnectDataProviderUri("update");
const result = await requestRest<NetworkElementConnection>(path, {
method: "POST", body: JSON.stringify(convertPropertyNames({ "data-provider:input": element }, replaceUpperCase))
});
@@ -58,7 +61,7 @@ class ConnectService {
const query = {
"id": element.id
};
- const path = `/rests/operations/data-provider:delete-network-element-connection`;
+ const path = this.getNetworkElementConnectDataProviderUri("delete");
const result = await requestRest<NetworkElementConnection>(path, {
method: "POST", body: JSON.stringify(convertPropertyNames({ "data-provider:input": query }, replaceUpperCase))
});
@@ -67,7 +70,7 @@ class ConnectService {
/** Mounts network element. */
public async mountNetworkElement(networkElement: NetworkElementConnection): Promise<boolean> {
- const path = '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + networkElement.nodeId;
+ const path = this.getNetworkElementUri(networkElement.nodeId);
const mountXml = [
'<node xmlns="urn:TBD:params:xml:ns:yang:network-topology">',
`<node-id>${networkElement.nodeId}</node-id>`,
@@ -106,7 +109,7 @@ class ConnectService {
/** Unmounts a network element by its id. */
public async unmountNetworkElement(nodeId: string): Promise<boolean> {
- const path = '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId;
+ const path = this.getNetworkElementUri(nodeId);
try {
const result = await requestRest<string>(path, {
@@ -126,7 +129,7 @@ class ConnectService {
/** Yang capabilities of the selected network elements. */
public async infoNetworkElement(nodeId: string): Promise<TopologyNode | null> {
- const path = '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId;
+ const path = this.getNetworkElementUri(nodeId);
const topologyRequestPomise = requestRest<Topology>(path, { method: "GET" });
return topologyRequestPomise && topologyRequestPomise.then(result => {
@@ -157,38 +160,80 @@ class ConnectService {
})) || null;
}
- public getAllWebUriExtensionsForNetworkElementListAsync(ne: string[]) {
-
- let promises: any[] = [];
- let webUris: guiCutThrough[] = []
-
- ne.forEach(nodeId => {
- const path = '/rests/data/network-topology:network-topology/topology=topology-netconf/node=' + nodeId + '/yang-ext:mount/core-model:network-element';
+ public async getAllWebUriExtensionsForNetworkElementListAsync(neList: string[]): Promise<(guiCutThrough)[]> {
+ const path = `/rests/operations/data-provider:read-gui-cut-through-entry`;
+ let webUriList: guiCutThrough[] = []
+ const query = {
+ "data-provider:input": {
+ "filter": [{
+ "property": "id",
+ "filtervalues": neList
+ }],
+ "pagination": {
+ "size": 20,
+ "page": 1
+ }
+ }
+ }
- // add search request to array
- promises.push(requestRest<any>(path, { method: "GET" })
- .then(result => {
- if (result != null && result['core-model:network-element'] && result['core-model:network-element'].extension) {
- const webUri = result['core-model:network-element'].extension.find((item: any) => item['value-name'] === "webUri")
- if (webUri) {
- webUris.push({ webUri: webUri.value, nodeId: nodeId });
- } else {
- webUris.push({ webUri: undefined, nodeId: nodeId });
+ const result = await requestRest<Result<guiCutThrough>>(path, { method: "POST", body: JSON.stringify(query) });
+ const resultData = result && result["data-provider:output"] && result["data-provider:output"].data;
+ neList.forEach(nodeId => {
+ let entryNotFound = true;
+ if (resultData) {
+ const BreakException = {};
+ try {
+ resultData.forEach(entry => {
+ if (entry.id == nodeId) {
+ entryNotFound = false;
+ if (entry.weburi) {
+ webUriList.push({ id: nodeId, weburi: entry.weburi });
+ } else {
+ webUriList.push({ id: nodeId, weburi: undefined });
+ }
+ throw BreakException;
}
- } else {
- webUris.push({ webUri: undefined, nodeId: nodeId });
- }
- })
- .catch(error => {
- webUris.push({ webUri: undefined, nodeId: nodeId });
- }))
-
- })
-
- // wait until all promises are done and return weburis
- return Promise.all(promises).then(result => { return webUris });
+ });
+ } catch (e) {}
+ }
+ if (entryNotFound)
+ webUriList.push({ id: nodeId, weburi: undefined });
+ });
+ return webUriList;
}
+ // public async getAllWebUriExtensionsForNetworkElementListAsync(ne: string[]): Promise<(guiCutThrough)[] | null> {
+
+ // let promises: any[] = [];
+ // let webUris: guiCutThrough[] = []
+
+ // ne.forEach(nodeId => {
+ // const path = this.getAllWebUriExtensionsForNetworkElementListUri(nodeId);
+
+ // // add search request to array
+ // promises.push(requestRest<any>(path, { method: "GET" })
+ // .then(result => {
+ // if (result != null && result['core-model:network-element'] && result['core-model:network-element'].extension) {
+ // const webUri = result['core-model:network-element'].extension.find((item: any) => item['value-name'] === "webUri")
+ // if (webUri) {
+ // webUris.push({ weburi: webUri.value, id: nodeId });
+ // } else {
+ // webUris.push({ weburi: undefined, id: nodeId });
+ // }
+ // } else {
+ // webUris.push({ weburi: undefined, id: nodeId });
+ // }
+ // })
+ // .catch(error => {
+ // webUris.push({ weburi: undefined, id: nodeId });
+ // }))
+ // })
+ // // wait until all promises are done and return weburis
+ // return Promise.all(promises).then(result => { return webUris });
+ // }
+
}
+
+
+
export const connectService = new ConnectService();
-export default connectService;
diff --git a/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx b/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx
index 1fa5e1909..34b1b94b6 100644
--- a/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx
+++ b/sdnr/wt/odlux/apps/connectApp/src/views/connectView.tsx
@@ -40,10 +40,9 @@ const mapProps = (state: IApplicationStoreState) => ({
const mapDispatcher = (dispatcher: IDispatcher) => ({
networkElementsActions: createNetworkElementsActions(dispatcher.dispatch),
connectionStatusLogActions: createConnectionStatusLogActions(dispatcher.dispatch),
- onLoadNetworkElements: () => {
- dispatcher.dispatch(networkElementsReloadAction);
- },
- loadWebUris: async (networkElements: NetworkElementConnection[]) => { await dispatcher.dispatch(findWebUrisForGuiCutThroughAsyncAction(networkElements)) },
+ onLoadNetworkElements: () => dispatcher.dispatch(networkElementsReloadAction),
+ loadWebUris: (networkElements: NetworkElementConnection[]) =>
+ dispatcher.dispatch(findWebUrisForGuiCutThroughAsyncAction(networkElements.map((ne) => ne.id!))),
isBusy: (busy: boolean) => dispatcher.dispatch(new SetWeburiSearchBusy(busy)),
onLoadConnectionStatusLog: () => {
dispatcher.dispatch(connectionStatusLogReloadAction);
@@ -65,12 +64,14 @@ class ConnectApplicationComponent extends React.Component<ConnectApplicationComp
//this.props.connectionStatusLogActions.onToggleFilter();
}
- public componentDidUpdate = async () => {
- // search for guicutthroughs after networkelements were found
+ public componentDidUpdate = () => {
+
const networkElements = this.props.netWorkElements;
if (networkElements.rows.length > 0) {
- await this.props.loadWebUris(networkElements.rows);
+ // Update all netWorkElements for propper WebUriClient settings in case of table data changes.
+ // e.G: Pagination of the table data (there is no event)
+ this.props.loadWebUris(networkElements.rows);
}
}
diff --git a/sdnr/wt/odlux/apps/connectApp/webpack.config.js b/sdnr/wt/odlux/apps/connectApp/webpack.config.js
index 7f36e4e17..df88a80a9 100644
--- a/sdnr/wt/odlux/apps/connectApp/webpack.config.js
+++ b/sdnr/wt/odlux/apps/connectApp/webpack.config.js
@@ -11,6 +11,8 @@ const webpack = require("webpack");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const TerserPlugin = require('terser-webpack-plugin');
+const policies = require('./policies.json');
+
// const __dirname = (path => path.replace(/^([a-z]\:)/, c => c.toUpperCase()))(process.__dirname());
module.exports = (env) => {
@@ -124,34 +126,54 @@ module.exports = (env) => {
stats: {
colors: true
},
- proxy: {
- "/oauth2/": {
- target: "http://sdnr:8181",
+ before: function(app, server, compiler) {
+ app.get('/oauth/policies',(_, res) => res.json(policies));
+ },
+ proxy: {
+ "/about": {
+ target: "http://localhost:18181",
+ secure: false
+ },
+ "/yang-schema/": {
+ target: "http://localhost:18181",
+ secure: false
+ },
+ "/oauth/": {
+ target: "http://localhost:18181",
secure: false
},
-
- "/oauth/": {
- target: "http://sdnr:8181",
- secure: false
- },
"/database/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/restconf/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/rests/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/help/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
+ secure: false
+ },
+ "/about/": {
+ target: "http://localhost:18181",
+ secure: false
+ },
+ "/tree/": {
+ target: "http://localhost:18181",
secure: false
},
"/websocket": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
+ ws: true,
+ changeOrigin: true,
+ secure: false
+ },
+ "/apidoc": {
+ target: "http://localhost:18181",
ws: true,
changeOrigin: true,
secure: false
diff --git a/sdnr/wt/odlux/apps/demoApp/package.json b/sdnr/wt/odlux/apps/demoApp/package.json
index 9505cfbb0..7756fe328 100644
--- a/sdnr/wt/odlux/apps/demoApp/package.json
+++ b/sdnr/wt/odlux/apps/demoApp/package.json
@@ -24,17 +24,17 @@
"@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/demoApp/src/index.html b/sdnr/wt/odlux/apps/demoApp/src/index.html
index e85bcbb03..521c8902c 100644
--- a/sdnr/wt/odlux/apps/demoApp/src/index.html
+++ b/sdnr/wt/odlux/apps/demoApp/src/index.html
@@ -17,6 +17,7 @@
// run the application
require(["app","demoApp"], function (app, demoApp) {
demoApp.register();
+ app("./app.tsx").configureApplication({ authentication:"oauth", enablePolicy: true,});
app("./app.tsx");
});
</script>
diff --git a/sdnr/wt/odlux/apps/eventLogApp/package.json b/sdnr/wt/odlux/apps/eventLogApp/package.json
index 4e98a1756..dfcebfe63 100644
--- a/sdnr/wt/odlux/apps/eventLogApp/package.json
+++ b/sdnr/wt/odlux/apps/eventLogApp/package.json
@@ -24,17 +24,17 @@
"@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/eventLogApp/src/components/refreshEventLogDialog.tsx b/sdnr/wt/odlux/apps/eventLogApp/src/components/refreshEventLogDialog.tsx
new file mode 100644
index 000000000..7d86e9f04
--- /dev/null
+++ b/sdnr/wt/odlux/apps/eventLogApp/src/components/refreshEventLogDialog.tsx
@@ -0,0 +1,117 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH 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 * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+import { eventLogReloadAction } from '../handlers/eventLogHandler';
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { EventLogType } from '../models/eventLogType';
+
+export enum RefreshEventLogDialogMode {
+ None = "none",
+ RefreshEventLogTable = "RefreshEventLogTable",
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ refreshEventLog: () => dispatcher.dispatch(eventLogReloadAction)
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ applyButtonText: string,
+ cancelButtonText: string,
+ enableMountIdEditor: boolean,
+ enableUsernameEditor: boolean,
+ enableExtendedEditor: boolean,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [RefreshEventLogDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ applyButtonText: "",
+ cancelButtonText: "",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ },
+ [RefreshEventLogDialogMode.RefreshEventLogTable]: {
+ dialogTitle: "Do you want to refresh the Event Log?",
+ dialogDescription: "",
+ applyButtonText: "Yes",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: true,
+ enableUsernameEditor: true,
+ enableExtendedEditor: true,
+ }
+}
+
+type RefreshEventLogDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: RefreshEventLogDialogMode;
+ onClose: () => void;
+};
+
+type RefreshEventLogDialogComponentState = EventLogType & { isNameValid: boolean, isHostSet: boolean };
+
+class RefreshEventLogDialogComponent extends React.Component<RefreshEventLogDialogComponentProps, RefreshEventLogDialogComponentState> {
+ constructor(props: RefreshEventLogDialogComponentProps) {
+ super(props);
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ return (
+ <Dialog open={this.props.mode !== RefreshEventLogDialogMode.None}>
+ <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button aria-label="dialog-confirm-button" onClick={(event) => {
+ this.onRefresh();
+ }} > {setting.applyButtonText} </Button>
+ <Button aria-label="dialog-cancel-button" onClick={(event) => {
+ this.onCancel();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onRefresh = () => {
+ this.props.refreshEventLog();
+ this.props.onClose();
+ };
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+}
+
+export const RefreshEventLogDialog = connect(undefined, mapDispatch)(RefreshEventLogDialogComponent);
+export default RefreshEventLogDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/eventLogApp/src/views/eventLog.tsx b/sdnr/wt/odlux/apps/eventLogApp/src/views/eventLog.tsx
index 3d81e4e46..748c66e51 100644
--- a/sdnr/wt/odlux/apps/eventLogApp/src/views/eventLog.tsx
+++ b/sdnr/wt/odlux/apps/eventLogApp/src/views/eventLog.tsx
@@ -19,10 +19,12 @@ import * as React from "react";
import { Connect, connect, IDispatcher } from '../../../../framework/src/flux/connect';
import { MaterialTable, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
+import Refresh from '@material-ui/icons/Refresh';
import { EventLogType } from '../models/eventLogType';
import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
import { createEventLogProperties, createEventLogActions } from "../handlers/eventLogHandler";
+import RefreshEventLogDialog, { RefreshEventLogDialogMode } from '../components/refreshEventLogDialog';
const EventLogTable = MaterialTable as MaterialTableCtorType<EventLogType & { _id: string }>;
@@ -35,22 +37,56 @@ const mapDispatch = (dispatcher: IDispatcher) => ({
eventLogActions: createEventLogActions(dispatcher.dispatch)
});
+type EventLogComponentProps = Connect<typeof mapProps, typeof mapDispatch>;
+type EventLogComponentState = {
+ refreshEventLogEditorMode: RefreshEventLogDialogMode
+}
let initalSorted = false;
-class EventLogComponent extends React.Component<Connect<typeof mapProps, typeof mapDispatch>> {
- render() {
- return <EventLogTable stickyHeader title="Event Log" tableId="event-log-table" idProperty="_id" columns={[
- { property: "nodeId", title: "Node Name" },
- { property: "counter", title: "Counter" },
- { property: "timestamp", title: "Timestamp" },
- { property: "objectId", title: "Object ID" },
- { property: "attributeName", title: "Attribute Name" },
- { property: "newValue", title: "Message" },
- { property: "sourceType", title: "Source" }
- ]} {...this.props.eventLogActions} {...this.props.eventLogProperties} >
- </EventLogTable>
+class EventLogComponent extends React.Component<EventLogComponentProps, EventLogComponentState> {
+ constructor(props: EventLogComponentProps) {
+ super(props);
+
+ this.state = {
+ refreshEventLogEditorMode: RefreshEventLogDialogMode.None
+ };
+ }
+
+ render(): JSX.Element {
+
+ const refreshEventLogAction = {
+ icon: Refresh, tooltip: 'Refresh Event log', onClick: () => {
+ this.setState({
+ refreshEventLogEditorMode: RefreshEventLogDialogMode.RefreshEventLogTable
+ });
+ }
+ };
+ return (
+ <>
+ <EventLogTable stickyHeader title="Event Log" tableId="event-log-table" idProperty="_id" customActionButtons={[refreshEventLogAction]}
+ columns={[
+ { property: "nodeId", title: "Node Name" },
+ { property: "counter", title: "Counter" },
+ { property: "timestamp", title: "Timestamp" },
+ { property: "objectId", title: "Object ID" },
+ { property: "attributeName", title: "Attribute Name" },
+ { property: "newValue", title: "Message" },
+ { property: "sourceType", title: "Source" }
+ ]} {...this.props.eventLogActions} {...this.props.eventLogProperties} >
+ </EventLogTable>
+ <RefreshEventLogDialog
+ mode={this.state.refreshEventLogEditorMode}
+ onClose={this.onCloseRefreshEventLogDialog}
+ />
+ </>
+ )
}
+ private onCloseRefreshEventLogDialog = () => {
+ this.setState({
+ refreshEventLogEditorMode: RefreshEventLogDialogMode.None
+ });
+ }
componentDidMount() {
if (!initalSorted) {
diff --git a/sdnr/wt/odlux/apps/faultApp/package.json b/sdnr/wt/odlux/apps/faultApp/package.json
index 70952530c..5d1439b85 100644
--- a/sdnr/wt/odlux/apps/faultApp/package.json
+++ b/sdnr/wt/odlux/apps/faultApp/package.json
@@ -24,17 +24,17 @@
"@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/faultApp/src/components/refreshAlarmLogDialog.tsx b/sdnr/wt/odlux/apps/faultApp/src/components/refreshAlarmLogDialog.tsx
new file mode 100644
index 000000000..1d1b34cf2
--- /dev/null
+++ b/sdnr/wt/odlux/apps/faultApp/src/components/refreshAlarmLogDialog.tsx
@@ -0,0 +1,117 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH 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 * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+import { alarmLogEntriesReloadAction } from '../handlers/alarmLogEntriesHandler';
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { Fault } from '../models/fault';
+
+export enum RefreshAlarmLogDialogMode {
+ None = "none",
+ RefreshAlarmLogTable = "RefreshAlarmLogTable",
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ refreshAlarmLog: () => dispatcher.dispatch(alarmLogEntriesReloadAction)
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ applyButtonText: string,
+ cancelButtonText: string,
+ enableMountIdEditor: boolean,
+ enableUsernameEditor: boolean,
+ enableExtendedEditor: boolean,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [RefreshAlarmLogDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ applyButtonText: "",
+ cancelButtonText: "",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ },
+ [RefreshAlarmLogDialogMode.RefreshAlarmLogTable]: {
+ dialogTitle: "Do you want to refresh the Alarm Log?",
+ dialogDescription: "",
+ applyButtonText: "Yes",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: true,
+ enableUsernameEditor: true,
+ enableExtendedEditor: true,
+ }
+}
+
+type RefreshAlarmLogDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: RefreshAlarmLogDialogMode;
+ onClose: () => void;
+};
+
+type RefreshAlarmLogDialogComponentState = Fault & { isNameValid: boolean, isHostSet: boolean };
+
+class RefreshAlarmLogDialogComponent extends React.Component<RefreshAlarmLogDialogComponentProps, RefreshAlarmLogDialogComponentState> {
+ constructor(props: RefreshAlarmLogDialogComponentProps) {
+ super(props);
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ return (
+ <Dialog open={this.props.mode !== RefreshAlarmLogDialogMode.None}>
+ <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button aria-label="dialog-confirm-button" onClick={(event) => {
+ this.onRefresh();
+ }} > {setting.applyButtonText} </Button>
+ <Button aria-label="dialog-cancel-button" onClick={(event) => {
+ this.onCancel();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onRefresh = () => {
+ this.props.refreshAlarmLog();
+ this.props.onClose();
+ };
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+}
+
+export const RefreshAlarmLogDialog = connect(undefined, mapDispatch)(RefreshAlarmLogDialogComponent);
+export default RefreshAlarmLogDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/faultApp/src/components/refreshCurrentProblemsDialog.tsx b/sdnr/wt/odlux/apps/faultApp/src/components/refreshCurrentProblemsDialog.tsx
new file mode 100644
index 000000000..c49722077
--- /dev/null
+++ b/sdnr/wt/odlux/apps/faultApp/src/components/refreshCurrentProblemsDialog.tsx
@@ -0,0 +1,117 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH 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 * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+import { currentProblemsReloadAction } from '../handlers/currentProblemsHandler';
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { Fault } from '../models/fault';
+
+export enum RefreshCurrentProblemsDialogMode {
+ None = "none",
+ RefreshCurrentProblemsTable = "RefreshCurrentProblemsTable",
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ refreshCurrentProblems: () => dispatcher.dispatch(currentProblemsReloadAction)
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ applyButtonText: string,
+ cancelButtonText: string,
+ enableMountIdEditor: boolean,
+ enableUsernameEditor: boolean,
+ enableExtendedEditor: boolean,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [RefreshCurrentProblemsDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ applyButtonText: "",
+ cancelButtonText: "",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ },
+ [RefreshCurrentProblemsDialogMode.RefreshCurrentProblemsTable]: {
+ dialogTitle: "Do you want to refresh the Current Problems List?",
+ dialogDescription: "",
+ applyButtonText: "Yes",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: true,
+ enableUsernameEditor: true,
+ enableExtendedEditor: true,
+ }
+}
+
+type RefreshCurrentProblemsDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: RefreshCurrentProblemsDialogMode;
+ onClose: () => void;
+};
+
+type RefreshCurrentProblemsDialogComponentState = Fault & { isNameValid: boolean, isHostSet: boolean };
+
+class RefreshCurrentProblemsDialogComponent extends React.Component<RefreshCurrentProblemsDialogComponentProps, RefreshCurrentProblemsDialogComponentState> {
+ constructor(props: RefreshCurrentProblemsDialogComponentProps) {
+ super(props);
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ return (
+ <Dialog open={this.props.mode !== RefreshCurrentProblemsDialogMode.None}>
+ <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button aria-label="dialog-confirm-button" onClick={(event) => {
+ this.onRefresh();
+ }} > {setting.applyButtonText} </Button>
+ <Button aria-label="dialog-cancel-button" onClick={(event) => {
+ this.onCancel();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onRefresh = () => {
+ this.props.refreshCurrentProblems();
+ this.props.onClose();
+ };
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+}
+
+export const RefreshCurrentProblemsDialog = connect(undefined, mapDispatch)(RefreshCurrentProblemsDialogComponent);
+export default RefreshCurrentProblemsDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx b/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx
index 2c167c5b2..d313a2048 100644
--- a/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx
+++ b/sdnr/wt/odlux/apps/faultApp/src/views/faultApplication.tsx
@@ -35,8 +35,12 @@ import { createCurrentProblemsProperties, createCurrentProblemsActions, currentP
import { createAlarmLogEntriesProperties, createAlarmLogEntriesActions, alarmLogEntriesReloadAction } from '../handlers/alarmLogEntriesHandler';
import { setPanelAction } from '../actions/panelChangeActions';
import { Tooltip, IconButton, AppBar, Tabs, Tab } from '@material-ui/core';
-import RefreshIcon from '@material-ui/icons/Refresh';
+import Sync from '@material-ui/icons/Sync';
+import Refresh from '@material-ui/icons/Refresh';
+
import ClearStuckAlarmsDialog, { ClearStuckAlarmsDialogMode } from '../components/clearStuckAlarmsDialog';
+import RefreshAlarmLogDialog, { RefreshAlarmLogDialogMode } from '../components/refreshAlarmLogDialog';
+import RefreshCurrentProblemsDialog, { RefreshCurrentProblemsDialogMode } from '../components/refreshCurrentProblemsDialog';
import { SetPartialUpdatesAction } from '../actions/partialUpdatesAction';
const mapProps = (state: IApplicationStoreState) => ({
@@ -61,7 +65,9 @@ type FaultApplicationComponentProps = RouteComponentProps & Connect<typeof mapPr
type FaultApplicationState = {
clearAlarmDialogMode: ClearStuckAlarmsDialogMode,
- stuckAlarms: string[]
+ stuckAlarms: string[],
+ refreshAlarmLogEditorMode: RefreshAlarmLogDialogMode,
+ refreshCurrentProblemsEditorMode: RefreshCurrentProblemsDialogMode
}
@@ -78,7 +84,12 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
*/
constructor(props: FaultApplicationComponentProps) {
super(props);
- this.state = { clearAlarmDialogMode: ClearStuckAlarmsDialogMode.None, stuckAlarms: [] }
+ this.state = {
+ clearAlarmDialogMode: ClearStuckAlarmsDialogMode.None,
+ stuckAlarms: [],
+ refreshAlarmLogEditorMode: RefreshAlarmLogDialogMode.None,
+ refreshCurrentProblemsEditorMode: RefreshCurrentProblemsDialogMode.None
+ }
}
onDialogClose = () => {
@@ -127,10 +138,27 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
render(): JSX.Element {
const refreshButton = {
- icon: RefreshIcon, tooltip: 'Clear stuck alarms', onClick: this.onDialogOpen
+ icon: Sync, tooltip: 'Clear stuck alarms', onClick: this.onDialogOpen
+ };
+
+ const refreshCurrentProblemsAction = {
+ icon: Refresh, tooltip: 'Refresh Current Problems List', onClick: () => {
+ this.setState({
+ refreshCurrentProblemsEditorMode: RefreshCurrentProblemsDialogMode.RefreshCurrentProblemsTable
+ });
+ }
+ };
+
+ const refreshAlarmLogAction = {
+ icon: Refresh, tooltip: 'Refresh Alarm log table', onClick: () => {
+ this.setState({
+ refreshAlarmLogEditorMode: RefreshAlarmLogDialogMode.RefreshAlarmLogTable
+ });
+ }
};
+
const areFaultsAvailable = this.props.currentProblemsProperties.rows && this.props.currentProblemsProperties.rows.length > 0
- const customAction = areFaultsAvailable ? [refreshButton] : [];
+ const customActions = areFaultsAvailable ? [refreshButton, refreshCurrentProblemsAction] : [refreshCurrentProblemsAction];
const { panelId: activePanelId } = this.props;
@@ -144,15 +172,22 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
</Tabs>
</AppBar>
{
- activePanelId === 'CurrentProblem' && <FaultTable stickyHeader tableId="current-problems-table" idProperty={'id'} customActionButtons={customAction} columns={[
- { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
- { property: "timestamp", type: ColumnType.text, title: "Timestamp" },
- { property: "nodeId", title: "Node Name", type: ColumnType.text },
- { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
- { property: "objectId", title: "Object Id", type: ColumnType.text },
- { property: "problem", title: "Alarm Type", type: ColumnType.text },
- { property: "severity", title: "Severity", type: ColumnType.text, width: "140px" },
- ]} {...this.props.currentProblemsProperties} {...this.props.currentProblemsActions} />
+ activePanelId === 'CurrentProblem' &&
+ <>
+ <FaultTable stickyHeader tableId="current-problems-table" idProperty={'id'} customActionButtons={customActions} columns={[
+ { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
+ { property: "timestamp", type: ColumnType.text, title: "Timestamp" },
+ { property: "nodeId", title: "Node Name", type: ColumnType.text },
+ { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
+ { property: "objectId", title: "Object Id", type: ColumnType.text },
+ { property: "problem", title: "Alarm Type", type: ColumnType.text },
+ { property: "severity", title: "Severity", type: ColumnType.text, width: "140px" },
+ ]} {...this.props.currentProblemsProperties} {...this.props.currentProblemsActions} />
+ <RefreshCurrentProblemsDialog
+ mode={this.state.refreshCurrentProblemsEditorMode}
+ onClose={this.onCloseRefreshCurrentProblemsDialog}
+ />
+ </>
}
{activePanelId === 'AlarmNotifications' &&
@@ -168,18 +203,24 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
}
- {activePanelId === 'AlarmLog' &&
- <FaultTable stickyHeader idProperty={'id'} tableId="alarm-log-table"
- columns={[
- { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
- { property: "timestamp", title: "Timestamp" },
- { property: "nodeId", title: "Node Name" },
- { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
- { property: "objectId", title: "Object Id" },
- { property: "problem", title: "Alarm Type" },
- { property: "severity", title: "Severity", width: "140px" },
- { property: "sourceType", title: "Source", width: "140px" },
- ]} {...this.props.alarmLogEntriesProperties} {...this.props.alarmLogEntriesActions} />
+ {activePanelId === 'AlarmLog' &&
+ <>
+ <FaultTable stickyHeader idProperty={'id'} tableId="alarm-log-table" customActionButtons={[refreshAlarmLogAction]}
+ columns={[
+ { property: "icon", title: "", type: ColumnType.custom, customControl: this.renderIcon },
+ { property: "timestamp", title: "Timestamp" },
+ { property: "nodeId", title: "Node Name" },
+ { property: "counter", title: "Count", type: ColumnType.numeric, width: "100px" },
+ { property: "objectId", title: "Object Id" },
+ { property: "problem", title: "Alarm Type" },
+ { property: "severity", title: "Severity", width: "140px" },
+ { property: "sourceType", title: "Source", width: "140px" },
+ ]} {...this.props.alarmLogEntriesProperties} {...this.props.alarmLogEntriesActions} />
+ <RefreshAlarmLogDialog
+ mode={this.state.refreshAlarmLogEditorMode}
+ onClose={this.onCloseRefreshAlarmLogDialog}
+ />
+ </>
}
{
@@ -207,6 +248,16 @@ class FaultApplicationComponent extends React.Component<FaultApplicationComponen
);
};
+ private onCloseRefreshAlarmLogDialog = () => {
+ this.setState({
+ refreshAlarmLogEditorMode: RefreshAlarmLogDialogMode.None
+ });
+ }
+ private onCloseRefreshCurrentProblemsDialog = () => {
+ this.setState({
+ refreshCurrentProblemsEditorMode: RefreshCurrentProblemsDialogMode.None
+ });
+ }
}
export const FaultApplication = withRouter(connect(mapProps, mapDisp)(FaultApplicationComponent));
diff --git a/sdnr/wt/odlux/apps/helpApp/package.json b/sdnr/wt/odlux/apps/helpApp/package.json
index 0a7593dcc..58e68dd03 100644
--- a/sdnr/wt/odlux/apps/helpApp/package.json
+++ b/sdnr/wt/odlux/apps/helpApp/package.json
@@ -29,17 +29,17 @@
"github-markdown-css": "2.10.0"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/inventoryApp/package.json b/sdnr/wt/odlux/apps/inventoryApp/package.json
index 1e11f78d0..0f6b40379 100644
--- a/sdnr/wt/odlux/apps/inventoryApp/package.json
+++ b/sdnr/wt/odlux/apps/inventoryApp/package.json
@@ -24,17 +24,17 @@
"@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/inventoryApp/src/components/refreshInventoryDialog.tsx b/sdnr/wt/odlux/apps/inventoryApp/src/components/refreshInventoryDialog.tsx
new file mode 100644
index 000000000..d2efb4e97
--- /dev/null
+++ b/sdnr/wt/odlux/apps/inventoryApp/src/components/refreshInventoryDialog.tsx
@@ -0,0 +1,117 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH 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 * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+import { inventoryElementsReloadAction } from '../handlers/inventoryElementsHandler';
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { InventoryType } from '../models/inventory';
+
+export enum RefreshInventoryDialogMode {
+ None = "none",
+ RefreshInventoryTable = "RefreshInventoryTable",
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ refreshInventory: () => dispatcher.dispatch(inventoryElementsReloadAction)
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ applyButtonText: string,
+ cancelButtonText: string,
+ enableMountIdEditor: boolean,
+ enableUsernameEditor: boolean,
+ enableExtendedEditor: boolean,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [RefreshInventoryDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ applyButtonText: "",
+ cancelButtonText: "",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ },
+ [RefreshInventoryDialogMode.RefreshInventoryTable]: {
+ dialogTitle: "Do you want to refresh the Inventory table?",
+ dialogDescription: "",
+ applyButtonText: "Yes",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: true,
+ enableUsernameEditor: true,
+ enableExtendedEditor: true,
+ }
+}
+
+type RefreshInventoryDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: RefreshInventoryDialogMode;
+ onClose: () => void;
+};
+
+type RefreshInventoryDialogComponentState = InventoryType & { isNameValid: boolean, isHostSet: boolean };
+
+class RefreshInventoryDialogComponent extends React.Component<RefreshInventoryDialogComponentProps, RefreshInventoryDialogComponentState> {
+ constructor(props: RefreshInventoryDialogComponentProps) {
+ super(props);
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ return (
+ <Dialog open={this.props.mode !== RefreshInventoryDialogMode.None}>
+ <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button aria-label="dialog-confirm-button" onClick={(event) => {
+ this.onRefresh();
+ }} > {setting.applyButtonText} </Button>
+ <Button aria-label="dialog-cancel-button" onClick={(event) => {
+ this.onCancel();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onRefresh = () => {
+ this.props.refreshInventory();
+ this.props.onClose();
+ };
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+}
+
+export const RefreshInventoryDialog = connect(undefined, mapDispatch)(RefreshInventoryDialogComponent);
+export default RefreshInventoryDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/inventoryApp/src/index.html b/sdnr/wt/odlux/apps/inventoryApp/src/index.html
index 75531ec1b..21f31300f 100644
--- a/sdnr/wt/odlux/apps/inventoryApp/src/index.html
+++ b/sdnr/wt/odlux/apps/inventoryApp/src/index.html
@@ -15,9 +15,10 @@
<script type="text/javascript" src="./config.js"></script>
<script>
// run the application
- require(["app", "inventoryApp", "connectApp"], function (app, inventoryApp, connectApp) {
+ require(["app", "inventoryApp", "connectApp", "configurationApp"], function (app, inventoryApp, connectApp, configurationApp) {
inventoryApp.register();
connectApp.register();
+ configurationApp.register();
app("./app.tsx").runApplication();
});
</script>
diff --git a/sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx b/sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx
index f5ada22ab..11427fba9 100644
--- a/sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx
+++ b/sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx
@@ -23,6 +23,7 @@ import connect, { IDispatcher, Connect } from "../../../../framework/src/flux/co
import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
import { MaterialTable, MaterialTableCtorType, ColumnType } from "../../../../framework/src/components/material-table";
import { AppBar, Tabs, Tab, MenuItem, Typography } from "@material-ui/core";
+import Refresh from '@material-ui/icons/Refresh';
import { PanelId } from "../models/panelId";
import { setPanelAction } from "../actions/panelActions";
@@ -36,6 +37,7 @@ import { InventoryType } from '../models/inventory';
import { createInventoryElementsProperties, createInventoryElementsActions } from "../handlers/inventoryElementsHandler";
import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
import { updateInventoryTreeAsyncAction } from '../actions/inventoryTreeActions';
+import RefreshInventoryDialog, { RefreshInventoryDialogMode } from '../components/refreshInventoryDialog';
const InventoryTable = MaterialTable as MaterialTableCtorType<InventoryType & { _id: string }>;
@@ -49,7 +51,7 @@ const mapProps = (state: IApplicationStoreState) => ({
const mapDispatch = (dispatcher: IDispatcher) => ({
connectedNetworkElementsActions: createConnectedNetworkElementsActions(dispatcher.dispatch),
switchActivePanel: (panelId: PanelId) => {
- dispatcher.dispatch(setPanelAction(panelId));
+ dispatcher.dispatch(setPanelAction(panelId));
},
inventoryElementsActions: createInventoryElementsActions(dispatcher.dispatch),
navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)),
@@ -62,8 +64,18 @@ let inventoryInitialSorted = false;
const ConnectedElementTable = MaterialTable as MaterialTableCtorType<NetworkElementConnection>;
type DashboardComponentProps = RouteComponentProps & Connect<typeof mapProps, typeof mapDispatch>;
+type DashboardComponentState = {
+ refreshInventoryEditorMode: RefreshInventoryDialogMode
+}
+
+class DashboardSelectorComponent extends React.Component<DashboardComponentProps, DashboardComponentState> {
+ constructor(props: DashboardComponentProps) {
+ super(props);
-class DashboardSelectorComponent extends React.Component<DashboardComponentProps> {
+ this.state = {
+ refreshInventoryEditorMode: RefreshInventoryDialogMode.None
+ };
+ }
private onHandleTabChange = (event: React.ChangeEvent<{}>, newValue: PanelId) => {
this.onTogglePanel(newValue);
@@ -111,6 +123,13 @@ class DashboardSelectorComponent extends React.Component<DashboardComponentProps
render() {
+ const refreshInventoryAction = {
+ icon: Refresh, tooltip: 'Refresh Inventory', onClick: () => {
+ this.setState({
+ refreshInventoryEditorMode: RefreshInventoryDialogMode.RefreshInventoryTable
+ });
+ }
+ };
const { panelId: activePanelId } = this.props;
return (
<>
@@ -124,32 +143,42 @@ class DashboardSelectorComponent extends React.Component<DashboardComponentProps
{
activePanelId === "InventoryElementsTable" &&
-
- <InventoryTable stickyHeader title="Inventory" idProperty="_id" tableId="inventory-table" columns={[
- { property: "nodeId", title: "Node Name" },
- { property: "manufacturerIdentifier", title: "Manufacturer" },
- { property: "parentUuid", title: "Parent" },
- { property: "uuid", title: "Name" },
- { property: "serial", title: "Serial" },
- { property: "version", title: "Version" },
- { property: "date", title: "Date" },
- { property: "description", title: "Description" },
- { property: "partTypeId", title: "Part Type Id" },
- { property: "modelIdentifier", title: "Model Identifier" },
- { property: "typeName", title: "Type" },
- { property: "treeLevel", title: "Containment Level" },
- ]} {...this.props.inventoryElementsActions} {...this.props.inventoryElementsProperties}
- createContextMenu={rowData => {
-
- return this.getContextMenu(rowData);
- }} >
- </InventoryTable>
+ <>
+ <InventoryTable stickyHeader title="Inventory" idProperty="_id" tableId="inventory-table" customActionButtons={[refreshInventoryAction]} columns={[
+ { property: "nodeId", title: "Node Name" },
+ { property: "manufacturerIdentifier", title: "Manufacturer" },
+ { property: "parentUuid", title: "Parent" },
+ { property: "uuid", title: "Name" },
+ { property: "serial", title: "Serial" },
+ { property: "version", title: "Version" },
+ { property: "date", title: "Date" },
+ { property: "description", title: "Description" },
+ { property: "partTypeId", title: "Part Type Id" },
+ { property: "modelIdentifier", title: "Model Identifier" },
+ { property: "typeName", title: "Type" },
+ { property: "treeLevel", title: "Containment Level" },
+ ]} {...this.props.inventoryElementsActions} {...this.props.inventoryElementsProperties}
+ createContextMenu={rowData => {
+
+ return this.getContextMenu(rowData);
+ }} >
+ </InventoryTable>
+ <RefreshInventoryDialog
+ mode={this.state.refreshInventoryEditorMode}
+ onClose={this.onCloseRefreshInventoryDialog}
+ />
+ </>
}
{
activePanelId === "TreeviewTable" &&
- <ConnectedElementTable stickyHeader tableId="treeview-networkelement-selection-table" onHandleClick={(e, row) => { this.props.history.push(`${this.props.match.path}/${row.nodeId}`) }} columns={[
+ <ConnectedElementTable stickyHeader tableId="treeview-networkelement-selection-table"
+ onHandleClick={(e, row) => {
+ this.props.history.push(`${this.props.match.path}/${row.nodeId}`);
+ this.props.updateInventoryTree(row.nodeId, '*');
+ }}
+ columns={[
{ property: "nodeId", title: "Node Name", type: ColumnType.text },
{ property: "isRequired", title: "Required", type: ColumnType.boolean },
{ property: "host", title: "Host", type: ColumnType.text },
@@ -163,6 +192,11 @@ class DashboardSelectorComponent extends React.Component<DashboardComponentProps
);
}
+ private onCloseRefreshInventoryDialog = () => {
+ this.setState({
+ refreshInventoryEditorMode: RefreshInventoryDialogMode.None
+ });
+ }
componentDidMount() {
if (this.props.panelId === null) { //set default tab if none is set
diff --git a/sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx b/sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx
index 5ba82abe7..9544861ef 100644
--- a/sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx
+++ b/sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx
@@ -24,7 +24,7 @@ import { TreeView, TreeViewCtorType, SearchMode } from '../../../../framework/sr
import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
-import { updateInventoryTreeAsyncAction, selectInventoryNodeAsyncAction, UpdateSelectedNodeAction, UpdateExpandedNodesAction, setSearchTermAction} from "../actions/inventoryTreeActions";
+import { updateInventoryTreeAsyncAction, selectInventoryNodeAsyncAction, UpdateSelectedNodeAction, UpdateExpandedNodesAction, setSearchTermAction } from "../actions/inventoryTreeActions";
import { TreeDemoItem } from "../models/inventory";
import { RouteComponentProps } from "react-router-dom";
@@ -66,7 +66,7 @@ const InventoryTree = TreeView as any as TreeViewCtorType<string>;
-type TreeviewComponentProps = RouteComponentProps<{ mountId: string}> & WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>
+type TreeviewComponentProps = RouteComponentProps<{ mountId: string }> & WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>
type TreeviewComponentState = {
[propsChache]: {
@@ -78,7 +78,7 @@ type TreeviewComponentState = {
class DashboardComponent extends React.Component<TreeviewComponentProps, TreeviewComponentState> {
- constructor (props: TreeviewComponentProps) {
+ constructor(props: TreeviewComponentProps) {
super(props);
this.state = {
@@ -89,15 +89,16 @@ class DashboardComponent extends React.Component<TreeviewComponentProps, Treevie
static getDerivedStateFromProps(props: TreeviewComponentProps, state: TreeviewComponentState) {
if (state[propsChache].rootNodes != props.rootNodes) {
- state = { ...state, rootNodes: props.rootNodes}
+ state = { ...state, rootNodes: props.rootNodes }
}
return state;
}
render() {
- const { classes, updateInventoryTree, updateExpendedNodes, expendedItems, selectedNode, selectTreeNode, searchTerm, match: { params: { mountId }} } = this.props;
+ const { classes, updateInventoryTree, updateExpendedNodes, expendedItems, selectedNode, selectTreeNode, searchTerm, match: { params: { mountId } } } = this.props;
+ const scrollbar = { overflow: "auto", paddingRight: "20px" }
return (
- <div className={classes.root}>
+ <div style={scrollbar} className={classes.root}>
<InventoryTree className={classes.tree} items={this.state.rootNodes} enableSearchBar initialSearchTerm={searchTerm} searchMode={SearchMode.OnEnter} searchTerm={searchTerm}
onSearch={(searchTerm) => updateInventoryTree(mountId, searchTerm)} expandedItems={expendedItems} onFolderClick={(item) => {
const indexOfItemToToggle = expendedItems.indexOf(item);
@@ -119,11 +120,11 @@ class DashboardComponent extends React.Component<TreeviewComponentProps, Treevie
}
componentDidMount() {
- const { updateInventoryTree, searchTerm, match: { params: { mountId } }} = this.props;
+ const { updateInventoryTree, searchTerm, match: { params: { mountId } } } = this.props;
updateInventoryTree(mountId, searchTerm);
}
- componentWillUnmount(){
+ componentWillUnmount() {
this.props.setSearchTerm("");
}
}
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/package.json b/sdnr/wt/odlux/apps/linkCalculationApp/package.json
index 22b2a6c0a..171770603 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/package.json
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/package.json
@@ -26,18 +26,18 @@
"yup": "^0.29.3"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
},
"devDependencies": {
"@types/yup": "^0.29.7",
diff --git a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx
index c498379b7..61a700c71 100644
--- a/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx
+++ b/sdnr/wt/odlux/apps/linkCalculationApp/src/views/linkCalculationComponent.tsx
@@ -324,16 +324,16 @@ class LinkCalculation extends React.Component<linkCalculationProps, initialState
<div >Site A
<form >
- <label>Latitude: <input className={this.state.latitude1Error.length>0 ? 'error' : 'input'} id='Lat1' type='number' onChange={(e: any) => {this.handleChange(e)} }/></label>
+ <label>Latitude: <input aria-label="site-a-latitude-input" className={this.state.latitude1Error.length>0 ? 'error' : 'input'} id='Lat1' type='number' onChange={(e: any) => {this.handleChange(e)} }/></label>
<div style={{fontSize:12, color:'red'}}> {this.state.latitude1Error} </div></form>
- <form><label>Longitude: <input className={this.state.longitude1Error.length>0 ? 'error' : 'input'} id='Lon1' type='number' onChange={(e: any) => this.handleChange(e) } /></label><div style={{fontSize:12, color:'red'}}> {this.state.longitude1Error} </div>
+ <form><label>Longitude: <input aria-label="site-a-longitude-input" className={this.state.longitude1Error.length>0 ? 'error' : 'input'} id='Lon1' type='number' onChange={(e: any) => this.handleChange(e) } /></label><div style={{fontSize:12, color:'red'}}> {this.state.longitude1Error} </div>
</form>
</div>
<div>Site B
<form>
- <label>Latitude: <input className={this.state.latitude2Error.length>0 ? 'error' : 'input'} id='Lat2' type='number' onChange={(e: any) => {this.handleChange(e) }} /></label><div style={{fontSize:12, color:'red'}}> {this.state.latitude2Error} </div></form>
- <form><label>Longitude: <input className={this.state.longitude2Error.length>0 ? 'error' : 'input'} id='Lon2' type='number' onChange={(e: any) => {this.handleChange(e) } }/></label><div style={{fontSize:12, color:'red'}}> {this.state.longitude2Error} </div></form>
+ <label>Latitude: <input aria-label="site-b-latitude-input" className={this.state.latitude2Error.length>0 ? 'error' : 'input'} id='Lat2' type='number' onChange={(e: any) => {this.handleChange(e) }} /></label><div style={{fontSize:12, color:'red'}}> {this.state.latitude2Error} </div></form>
+ <form><label>Longitude: <input aria-label="site-b-longitude-input" className={this.state.longitude2Error.length>0 ? 'error' : 'input'} id='Lon2' type='number' onChange={(e: any) => {this.handleChange(e) } }/></label><div style={{fontSize:12, color:'red'}}> {this.state.longitude2Error} </div></form>
</div>
</div>
@@ -341,8 +341,8 @@ class LinkCalculation extends React.Component<linkCalculationProps, initialState
<div className='container-1'>
- <div>{<form><input type='checkbox' id='Annual' value ="Annual" checked= {this.state.worstmonth===false} onClick= {(e: any) => this.setState ({worstmonth: false})}></input>Annual
- <input style={{marginLeft:10}} type='checkbox' id='Worst Month' value ="Worst" checked= {this.state.worstmonth===true} onClick= {(e:any)=>this.setState ({worstmonth: true})}></input>WM</form>}</div>
+ <div>{<form><input aria-label="annual" type='checkbox' id='Annual' value ="Annual" checked= {this.state.worstmonth===false} onClick= {(e: any) => this.setState ({worstmonth: false})}></input>Annual
+ <input aria-label="worst-month" style={{marginLeft:10}} type='checkbox' id='Worst Month' value ="Worst" checked= {this.state.worstmonth===true} onClick= {(e:any)=>this.setState ({worstmonth: true})}></input>WM</form>}</div>
<div className='column1'>
@@ -369,55 +369,55 @@ class LinkCalculation extends React.Component<linkCalculationProps, initialState
<div className='middlecolumn'>
<div >Site A</div>
{this.props.siteA.length>0 &&<div> {this.props.siteA }</div>}
- <div> {this.props.lat1 && this.LatLonToDMS(this.props.lat1)}</div>
- <div>{this.props.lon1 && this.LatLonToDMS(this.props.lon1)}</div>
+ <div aria-label="site-a-latitude-dms"> {this.props.lat1 && this.LatLonToDMS(this.props.lat1)}</div>
+ <div aria-label="site-a-longitude-dms">{this.props.lon1 && this.LatLonToDMS(this.props.lon1)}</div>
<div>0</div>
- <div>{this.props.amslA.toFixed(2)} m</div>
- <div>{this.props.aglA.toFixed(2)} m</div>
+ <div aria-label="site-a-amsl">{this.props.amslA.toFixed(2)} m</div>
+ <div aria-label="site-a-antenna-amsl">{this.props.aglA.toFixed(2)} m</div>
<div className='column2'>
- <div>{this.props.distance?.toFixed(3)} km</div>
- <div>{<form><input type='checkbox' id='Horizontal' value ="Horizontal" checked= {this.props.polarization==='Horizontal'} onClick= {(e: any) => this.props.updatePolarization(e.target.value)}></input>Horizontal
- <input style={{marginLeft:10}} type='checkbox' id='Vertical' value ="Vertical" checked= {this.props.polarization==='Vertical'} onClick= {(e:any)=>{this.props.updatePolarization(e.target.value)}}></input>Vertical</form>}</div>
+ <div aria-label="distance-between-sites">{this.props.distance?.toFixed(3)} km</div>
+ <div>{<form><input aria-label="polarization-horizontal" type='checkbox' id='Horizontal' value ="Horizontal" checked= {this.props.polarization==='Horizontal'} onClick= {(e: any) => this.props.updatePolarization(e.target.value)}></input>Horizontal
+ <input aria-label="polarization-vertical" style={{marginLeft:10}} type='checkbox' id='Vertical' value ="Vertical" checked= {this.props.polarization==='Vertical'} onClick= {(e:any)=>{this.props.updatePolarization(e.target.value)}}></input>Vertical</form>}</div>
- <div> {<select className={this.state.frequencyError.length>0 ? 'error' : 'input'} onChange={(e) => { this.props.updateFrequency(Number(e.target.value)); e.target.value==='0'? this.setState({frequencyError: 'select a frequency'}): this.setState({frequencyError:''})}}>
+ <div> {<select aria-label="select-frequency-in-ghz" className={this.state.frequencyError.length>0 ? 'error' : 'input'} onChange={(e) => { this.props.updateFrequency(Number(e.target.value)); e.target.value==='0'? this.setState({frequencyError: 'select a frequency'}): this.setState({frequencyError:''})}}>
- <option value='0' >Select Freq</option>
- <option value='7' >7 GHz</option>
- <option value='11' >11 GHz</option>
- <option value='15' >15 GHz</option>
- <option value='23' >23 GHz</option>
- <option value='26' >26 GHz</option>
- <option value='28' >28 GHz</option>
- <option value='38' >38 GHz</option>
- <option value='42' >42 GHz</option>
- <option value='80' >80 GHz</option>
+ <option value='0' aria-label="none-value" >Select Freq</option>
+ <option value='7' aria-label="7" >7 GHz</option>
+ <option value='11' aria-label="11" >11 GHz</option>
+ <option value='15' aria-label="15" >15 GHz</option>
+ <option value='23' aria-label="23">23 GHz</option>
+ <option value='26' aria-label="26">26 GHz</option>
+ <option value='28' aria-label="28">28 GHz</option>
+ <option value='38' aria-label="38">38 GHz</option>
+ <option value='42' aria-label="42">42 GHz</option>
+ <option value='80' aria-label="80">80 GHz</option>
</select>} <div style={{fontSize:12, color:'red'}}> {this.state.frequencyError} </div> </div>
- <div>{this.props.fsl.toFixed(3)} dB</div>
+ <div aria-label="fspl-value">{this.props.fsl.toFixed(3)} dB</div>
- <div> {<select className={this.state.rainMethodError.length>0 ? 'error' : 'input'} onChange = {(e) => {e.target.value === 'itu' ? this.setState({ rainMethodDisplay: false}):this.setState({ rainMethodDisplay: true}); e.target.value==='0'? this.setState({rainMethodError: 'select a Rain model'}): this.setState({rainMethodError:''}) }}>
- <option value='0' >Select Rain Method</option>
- <option value='itu' >ITU-R P.837-7</option>
- <option value='manual' >Specific Rain</option>
+ <div> {<select aria-label="select-rain-method" className={this.state.rainMethodError.length>0 ? 'error' : 'input'} onChange = {(e) => {e.target.value === 'itu' ? this.setState({ rainMethodDisplay: false}):this.setState({ rainMethodDisplay: true}); e.target.value==='0'? this.setState({rainMethodError: 'select a Rain model'}): this.setState({rainMethodError:''}) }}>
+ <option value='0' aria-label="none-value" >Select Rain Method</option>
+ <option value='itu' aria-label="itur8377">ITU-R P.837-7</option>
+ <option value='manual' aria-label="manual-entry">Specific Rain</option>
</select>} <div style={{fontSize:12,color:'red'}}>{this.state.rainMethodError}</div>
</div>
- <div> {<form><input type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => { this.props.updateRainValue(Number(e.target.value)) }}
+ <div> {<form><input aria-label="rain-value" type="number" style={{ width: 70, height: 15, fontSize: 14 }} onChange={(e) => { this.props.updateRainValue(Number(e.target.value)) }}
value={this.props.rainVal} disabled={this.state.rainMethodDisplay === false ? true : false}>
</input> mm/hr {this.state.showWM} {this.props.month}</form> } </div>
- <div>{this.props.rainAtt.toFixed(3)} dB</div>
+ <div aria-label="rain-attenuation-value">{this.props.rainAtt.toFixed(3)} dB</div>
- <div> {<select className={this.state.attenuationMethodError.length>0 ? 'error' : 'input'} onChange = {(e) => { if (e.target.value!== ''){ this.setState({absorptionMethod : e.target.value}); this.setState({attenuationMethodError:''}) }}}>
- <option value='0' >Select Absorption Method</option>
- <option value='ITURP67612' >ITU-R P.676-12</option>
- <option value='ITURP67611' >ITU-R P.676-11</option>
- <option value='ITURP67610' >ITU-R P.676-10</option>
+ <div> {<select aria-label="select-absorption-method" className={this.state.attenuationMethodError.length>0 ? 'error' : 'input'} onChange = {(e) => { if (e.target.value!== ''){ this.setState({absorptionMethod : e.target.value}); this.setState({attenuationMethodError:''}) }}}>
+ <option value='0' aria-label="none-value" >Select Absorption Method</option>
+ <option value='ITURP67612' aria-label="iturp67612" >ITU-R P.676-12</option>
+ <option value='ITURP67611' aria-label="iturp67611" >ITU-R P.676-11</option>
+ <option value='ITURP67610' aria-label="iturp67610" >ITU-R P.676-10</option>
</select>} <div style={{fontSize:12,color:'red'}}>{this.state.attenuationMethodError}</div>
</div>
- <div>{this.props.absorptionOxygen.toFixed(3)} dB</div>
- <div>{this.props.absorptionWater.toFixed(3)} dB</div>
- <div>{<button style={{color: '#222', fontFamily:'Arial', boxAlign: 'center', display:'inline-block', insetInlineStart: '20' , alignSelf:'center' }}
+ <div aria-label="absorption-oxygen-value">{this.props.absorptionOxygen.toFixed(3)} dB</div>
+ <div aria-label="absorption-water-value">{this.props.absorptionWater.toFixed(3)} dB</div>
+ <div>{<button aria-label="calculate-button" style={{color: '#222', fontFamily:'Arial', boxAlign: 'center', display:'inline-block', insetInlineStart: '20' , alignSelf:'center' }}
onClick = {(e) => this.buttonHandler()} >Calculate</button>} </div>
@@ -426,11 +426,11 @@ class LinkCalculation extends React.Component<linkCalculationProps, initialState
<div className= 'middlecolumn'>
<div >Site B</div>
{this.props.siteB.length>0 &&<div> {this.props.siteB}</div>}
- <div> {this.props.lat2 && this.LatLonToDMS(this.props.lat2)}</div>
- <div>{this.props.lon2 && this.LatLonToDMS(this.props.lon2)}</div>
+ <div aria-label="site-b-latitude-dms"> {this.props.lat2 && this.LatLonToDMS(this.props.lat2)}</div>
+ <div aria-label="site-b-longitude-dms">{this.props.lon2 && this.LatLonToDMS(this.props.lon2)}</div>
<div>0</div>
- <div>{this.props.amslB.toFixed(2)} m</div>
- <div>{this.props.aglB.toFixed(2)} m</div>
+ <div aria-label="site-b-asml">{this.props.amslB.toFixed(2)} m</div>
+ <div aria-label="site-b-antenna-asml">{this.props.aglB.toFixed(2)} m</div>
</div>
diff --git a/sdnr/wt/odlux/apps/maintenanceApp/package.json b/sdnr/wt/odlux/apps/maintenanceApp/package.json
index da5b3d288..d2980f1dc 100644
--- a/sdnr/wt/odlux/apps/maintenanceApp/package.json
+++ b/sdnr/wt/odlux/apps/maintenanceApp/package.json
@@ -25,17 +25,17 @@
"@odlux/connect-app": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/maintenanceApp/src/components/refreshMaintenanceEntries.tsx b/sdnr/wt/odlux/apps/maintenanceApp/src/components/refreshMaintenanceEntries.tsx
new file mode 100644
index 000000000..1a00c70c4
--- /dev/null
+++ b/sdnr/wt/odlux/apps/maintenanceApp/src/components/refreshMaintenanceEntries.tsx
@@ -0,0 +1,117 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH 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 * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { maintenanceEntriesReloadAction } from '../handlers/maintenenceEntriesHandler';
+import { MaintenenceEntry } from '../models/maintenenceEntryType';
+
+export enum RefreshMaintenanceEntriesDialogMode {
+ None = "none",
+ RefreshMaintenanceEntriesTable = "RefreshMaintenanceEntriesTable",
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ refreshMaintenanceEntries: () => dispatcher.dispatch(maintenanceEntriesReloadAction)
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ applyButtonText: string,
+ cancelButtonText: string,
+ enableMountIdEditor: boolean,
+ enableUsernameEditor: boolean,
+ enableExtendedEditor: boolean,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [RefreshMaintenanceEntriesDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ applyButtonText: "",
+ cancelButtonText: "",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ },
+ [RefreshMaintenanceEntriesDialogMode.RefreshMaintenanceEntriesTable]: {
+ dialogTitle: "Do you want to refresh Maintenance Entries?",
+ dialogDescription: "",
+ applyButtonText: "Yes",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: true,
+ enableUsernameEditor: true,
+ enableExtendedEditor: true,
+ }
+}
+
+type RefreshMaintenanceEntriesDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: RefreshMaintenanceEntriesDialogMode;
+ onClose: () => void;
+};
+
+type RefreshMaintenanceEntriesDialogComponentState = MaintenenceEntry & { isNameValid: boolean, isHostSet: boolean };
+
+class RefreshMaintenanceEntriesDialogComponent extends React.Component<RefreshMaintenanceEntriesDialogComponentProps, RefreshMaintenanceEntriesDialogComponentState> {
+ constructor(props: RefreshMaintenanceEntriesDialogComponentProps) {
+ super(props);
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ return (
+ <Dialog open={this.props.mode !== RefreshMaintenanceEntriesDialogMode.None}>
+ <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button aria-label="dialog-confirm-button" onClick={(event) => {
+ this.onRefresh();
+ }} > {setting.applyButtonText} </Button>
+ <Button aria-label="dialog-cancel-button" onClick={(event) => {
+ this.onCancel();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onRefresh = () => {
+ this.props.refreshMaintenanceEntries();
+ this.props.onClose();
+ };
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+}
+
+export const RefreshMaintenanceEntriesDialog = connect(undefined, mapDispatch)(RefreshMaintenanceEntriesDialogComponent);
+export default RefreshMaintenanceEntriesDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/maintenanceApp/src/views/maintenenceView.tsx b/sdnr/wt/odlux/apps/maintenanceApp/src/views/maintenenceView.tsx
index f52d46d81..6b5071d90 100644
--- a/sdnr/wt/odlux/apps/maintenanceApp/src/views/maintenenceView.tsx
+++ b/sdnr/wt/odlux/apps/maintenanceApp/src/views/maintenenceView.tsx
@@ -25,9 +25,8 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import AddIcon from '@material-ui/icons/Add';
import EditIcon from '@material-ui/icons/Edit';
import RemoveIcon from '@material-ui/icons/RemoveCircleOutline';
-
-import Button from '@material-ui/core/Button';
-import IconButton from '@material-ui/core/IconButton';
+import Refresh from '@material-ui/icons/Refresh';
+import { MenuItem, Divider, Typography } from '@material-ui/core';
import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect';
import MaterialTable, { MaterialTableCtorType, ColumnType } from '../../../../framework/src/components/material-table';
@@ -36,6 +35,7 @@ import { IApplicationStoreState } from '../../../../framework/src/store/applicat
import { MaintenenceEntry, spoofSymbol } from '../models/maintenenceEntryType';
import EditMaintenenceEntryDialog, { EditMaintenenceEntryDialogMode } from '../components/editMaintenenceEntryDialog';
+import RefreshMaintenanceEntriesDialog, { RefreshMaintenanceEntriesDialogMode } from '../components/refreshMaintenanceEntries';
import { convertToLocaleString } from '../utils/timeUtils';
import { createmaintenanceEntriesActions, createmaintenanceEntriesProperties, maintenanceEntriesReloadAction } from '../handlers/maintenenceEntriesHandler';
@@ -81,6 +81,7 @@ type MaintenenceViewComponentProps = Connect<typeof mapProps, typeof mapDispatch
type MaintenenceViewComponentState = {
maintenenceEntryToEdit: MaintenenceEntry;
maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode;
+ refreshMaintenenceEntriesEditorMode: RefreshMaintenanceEntriesDialogMode;
};
let initialSorted = false;
@@ -93,10 +94,22 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
this.state = {
maintenenceEntryToEdit: emptyMaintenenceEntry,
maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.None,
+ refreshMaintenenceEntriesEditorMode: RefreshMaintenanceEntriesDialogMode.None
};
}
+ getContextMenu(rowData: MaintenenceEntry): JSX.Element[] {
+ let buttonArray = [
+ <MenuItem aria-label={"1hr-from-now"} onClick={event => this.onOpenPlus1hEditMaintenenceEntryDialog(event, rowData)}><Typography>+1h</Typography></MenuItem>,
+ <MenuItem aria-label={"8hr-from-now"} onClick={event => this.onOpenPlus8hEditMaintenenceEntryDialog(event, rowData)}><Typography>+8h</Typography></MenuItem>,
+ <Divider />,
+ <MenuItem aria-label={"edit"} onClick={event => this.onOpenEditMaintenenceEntryDialog(event, rowData)}><EditIcon /><Typography>Edit</Typography></MenuItem>,
+ <MenuItem aria-label={"remove"} onClick={event => this.onOpenRemoveMaintenenceEntryDialog(event, rowData)}><RemoveIcon /><Typography>Remove</Typography></MenuItem>
+ ];
+ return buttonArray;
+ }
+
render() {
const { classes } = this.props;
const addMaintenenceEntryAction = {
@@ -113,10 +126,19 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
});
}
};
+
+ const refreshMaintenanceEntriesAction = {
+ icon: Refresh, tooltip: 'Refresh Maintenance Entries', onClick: () => {
+ this.setState({
+ refreshMaintenenceEntriesEditorMode: RefreshMaintenanceEntriesDialogMode.RefreshMaintenanceEntriesTable
+ });
+ }
+ };
+
const now = new Date().valueOf();
return (
<>
- <MaintenenceEntriesTable stickyHeader tableId="maintenance-table" title={"Maintenance"} customActionButtons={[addMaintenenceEntryAction]} columns={
+ <MaintenenceEntriesTable stickyHeader tableId="maintenance-table" title={"Maintenance"} customActionButtons={[refreshMaintenanceEntriesAction, addMaintenenceEntryAction]} columns={
[
{ property: "nodeId", title: "Node Name", type: ColumnType.text },
{
@@ -126,25 +148,16 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
},
{ property: "active", title: "Activation State", type: ColumnType.boolean, labels: { "true": "active", "false": "not active" }, },
{ property: "start", title: "Start Date (UTC)", type: ColumnType.text },
- { property: "end", title: "End Date (UTC)", type: ColumnType.text },
- {
- property: "actions", title: "Actions", type: ColumnType.custom, customControl: ({ rowData }) => (
- <>
- <div className={classes.spacer}>
- <Tooltip title={"1h from now"} ><Button className={classes.button} onClick={(event) => this.onOpenPlus1hEditMaintenenceEntryDialog(event, rowData)} >+1h</Button></Tooltip>
- <Tooltip title={"8h from now"} ><Button className={classes.button} onClick={(event) => this.onOpenPlus8hEditMaintenenceEntryDialog(event, rowData)} >+8h</Button></Tooltip>
- </div>
- <div className={classes.spacer}>
- <Tooltip title={"Edit"} ><IconButton className={classes.button} onClick={(event) => this.onOpenEditMaintenenceEntryDialog(event, rowData)} ><EditIcon /></IconButton></Tooltip>
- <Tooltip title={"Remove"} ><IconButton disabled={!!rowData[spoofSymbol]} className={classes.button} onClick={(event) => this.onOpenRemoveMaintenenceEntryDialog(event, rowData)} ><RemoveIcon /></IconButton></Tooltip>
- </div>
- </>
- )
- },
+ { property: "end", title: "End Date (UTC)", type: ColumnType.text }
]
- } idProperty={'_id'}{...this.props.maintenanceEntriesActions} {...this.props.maintenanceEntriesProperties} asynchronus > </MaintenenceEntriesTable>
+ } idProperty={'_id'}{...this.props.maintenanceEntriesActions} {...this.props.maintenanceEntriesProperties} asynchronus createContextMenu={rowData => {
+ return this.getContextMenu(rowData);
+ }} >
+ </MaintenenceEntriesTable>
<EditMaintenenceEntryDialog initialMaintenenceEntry={this.state.maintenenceEntryToEdit} mode={this.state.maintenenceEntryEditorMode}
onClose={this.onCloseEditMaintenenceEntryDialog} />
+ <RefreshMaintenanceEntriesDialog mode={this.state.refreshMaintenenceEntriesEditorMode}
+ onClose={this.onCloseRefreshMaintenenceEntryDialog} />
</>
);
}
@@ -162,8 +175,8 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
}
private onOpenPlus1hEditMaintenenceEntryDialog = (event: React.MouseEvent<HTMLElement>, entry: MaintenenceEntry) => {
- event.preventDefault();
- event.stopPropagation();
+ // event.preventDefault();
+ // event.stopPropagation();
const startTime = (new Date().valueOf());
const endTime = startTime + (1 * 60 * 60 * 1000);
this.setState({
@@ -177,8 +190,8 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
}
private onOpenPlus8hEditMaintenenceEntryDialog = (event: React.MouseEvent<HTMLElement>, entry: MaintenenceEntry) => {
- event.preventDefault();
- event.stopPropagation();
+ // event.preventDefault();
+ // event.stopPropagation();
const startTime = (new Date().valueOf());
const endTime = startTime + (8 * 60 * 60 * 1000);
this.setState({
@@ -192,8 +205,8 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
}
private onOpenEditMaintenenceEntryDialog = (event: React.MouseEvent<HTMLElement>, entry: MaintenenceEntry) => {
- event.preventDefault();
- event.stopPropagation();
+ // event.preventDefault();
+ // event.stopPropagation();
const startTime = (new Date().valueOf());
const endTime = startTime;
this.setState({
@@ -208,8 +221,8 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
}
private onOpenRemoveMaintenenceEntryDialog = (event: React.MouseEvent<HTMLElement>, entry: MaintenenceEntry) => {
- event.preventDefault();
- event.stopPropagation();
+ // event.preventDefault();
+ // event.stopPropagation();
const startTime = (new Date().valueOf());
const endTime = startTime;
this.setState({
@@ -229,7 +242,13 @@ class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentP
maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.None,
});
}
+
+ private onCloseRefreshMaintenenceEntryDialog = () => {
+ this.setState({
+ refreshMaintenenceEntriesEditorMode: RefreshMaintenanceEntriesDialogMode.None,
+ });
+ }
}
export const MaintenenceView = withStyles(styles)(connect(mapProps, mapDispatcher)(MaintenenceViewComponent));
-export default MaintenenceView; \ No newline at end of file
+export default MaintenenceView;
diff --git a/sdnr/wt/odlux/apps/mediatorApp/package.json b/sdnr/wt/odlux/apps/mediatorApp/package.json
index ddce56757..0f0e74673 100644
--- a/sdnr/wt/odlux/apps/mediatorApp/package.json
+++ b/sdnr/wt/odlux/apps/mediatorApp/package.json
@@ -25,17 +25,17 @@
},
"peerDependencies": {
"@fortawesome/free-solid-svg-icons": "5.6.3",
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/mediatorApp/src/components/refreshMediatorDialog.tsx b/sdnr/wt/odlux/apps/mediatorApp/src/components/refreshMediatorDialog.tsx
new file mode 100644
index 000000000..af94f5a32
--- /dev/null
+++ b/sdnr/wt/odlux/apps/mediatorApp/src/components/refreshMediatorDialog.tsx
@@ -0,0 +1,117 @@
+/**
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt odlux
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH 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 * as React from 'react';
+
+import Button from '@material-ui/core/Button';
+import Dialog from '@material-ui/core/Dialog';
+import DialogActions from '@material-ui/core/DialogActions';
+import DialogContent from '@material-ui/core/DialogContent';
+import DialogContentText from '@material-ui/core/DialogContentText';
+import DialogTitle from '@material-ui/core/DialogTitle';
+
+import { avaliableMediatorServersReloadAction } from '../handlers/avaliableMediatorServersHandler';
+import { IDispatcher, connect, Connect } from '../../../../framework/src/flux/connect';
+
+import { MediatorServer } from '../models/mediatorServer';
+
+export enum RefreshMediatorDialogMode {
+ None = "none",
+ RefreshMediatorTable = "RefreshMediatorTable",
+}
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ refreshMediator: () => dispatcher.dispatch(avaliableMediatorServersReloadAction)
+});
+
+type DialogSettings = {
+ dialogTitle: string,
+ dialogDescription: string,
+ applyButtonText: string,
+ cancelButtonText: string,
+ enableMountIdEditor: boolean,
+ enableUsernameEditor: boolean,
+ enableExtendedEditor: boolean,
+}
+
+const settings: { [key: string]: DialogSettings } = {
+ [RefreshMediatorDialogMode.None]: {
+ dialogTitle: "",
+ dialogDescription: "",
+ applyButtonText: "",
+ cancelButtonText: "",
+ enableMountIdEditor: false,
+ enableUsernameEditor: false,
+ enableExtendedEditor: false,
+ },
+ [RefreshMediatorDialogMode.RefreshMediatorTable]: {
+ dialogTitle: "Do you want to refresh the Mediator table?",
+ dialogDescription: "",
+ applyButtonText: "Yes",
+ cancelButtonText: "Cancel",
+ enableMountIdEditor: true,
+ enableUsernameEditor: true,
+ enableExtendedEditor: true,
+ }
+}
+
+type RefreshMediatorDialogComponentProps = Connect<undefined, typeof mapDispatch> & {
+ mode: RefreshMediatorDialogMode;
+ onClose: () => void;
+};
+
+type RefreshMediatorDialogComponentState = MediatorServer & { isNameValid: boolean, isHostSet: boolean };
+
+class RefreshMediatorDialogComponent extends React.Component<RefreshMediatorDialogComponentProps, RefreshMediatorDialogComponentState> {
+ constructor(props: RefreshMediatorDialogComponentProps) {
+ super(props);
+ }
+
+ render(): JSX.Element {
+ const setting = settings[this.props.mode];
+ return (
+ <Dialog open={this.props.mode !== RefreshMediatorDialogMode.None}>
+ <DialogTitle id="form-dialog-title" aria-label={`${setting.dialogTitle.replace(/ /g, "-").toLowerCase()}-dialog`}>{setting.dialogTitle}</DialogTitle>
+ <DialogContent>
+ <DialogContentText>
+ {setting.dialogDescription}
+ </DialogContentText>
+ </DialogContent>
+ <DialogActions>
+ <Button aria-label="dialog-confirm-button" onClick={(event) => {
+ this.onRefresh();
+ }} > {setting.applyButtonText} </Button>
+ <Button aria-label="dialog-cancel-button" onClick={(event) => {
+ this.onCancel();
+ }} color="secondary"> {setting.cancelButtonText} </Button>
+ </DialogActions>
+ </Dialog>
+ )
+ }
+
+ private onRefresh = () => {
+ this.props.refreshMediator();
+ this.props.onClose();
+ };
+
+ private onCancel = () => {
+ this.props.onClose();
+ }
+}
+
+export const RefreshMediatorDialog = connect(undefined, mapDispatch)(RefreshMediatorDialogComponent);
+export default RefreshMediatorDialog; \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorServerSelection.tsx b/sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorServerSelection.tsx
index c16906ad0..0f4ebbe0b 100644
--- a/sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorServerSelection.tsx
+++ b/sdnr/wt/odlux/apps/mediatorApp/src/views/mediatorServerSelection.tsx
@@ -22,6 +22,7 @@ import AddIcon from '@material-ui/icons/Add';
import IconButton from '@material-ui/core/IconButton';
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';
+import Refresh from '@material-ui/icons/Refresh';
import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect';
@@ -31,6 +32,7 @@ import { createAvaliableMediatorServersProperties, createAvaliableMediatorServer
import { MediatorServer } from '../models/mediatorServer';
import EditMediatorServerDialog, { EditMediatorServerDialogMode } from '../components/editMediatorServerDialog';
+import RefreshMediatorDialog, { RefreshMediatorDialogMode } from '../components/refreshMediatorDialog';
import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
const MediatorServersTable = MaterialTable as MaterialTableCtorType<MediatorServer>;
@@ -67,7 +69,8 @@ type MediatorServerSelectionComponentProps = Connect<typeof mapProps, typeof map
type MediatorServerSelectionComponentState = {
mediatorServerToEdit: MediatorServer,
- mediatorServerEditorMode: EditMediatorServerDialogMode
+ mediatorServerEditorMode: EditMediatorServerDialogMode,
+ refreshMediatorEditorMode: RefreshMediatorDialogMode
}
let initialSorted = false;
@@ -80,11 +83,19 @@ class MediatorServerSelectionComponent extends React.Component<MediatorServerSel
this.state = {
mediatorServerEditorMode: EditMediatorServerDialogMode.None,
mediatorServerToEdit: emptyMediatorServer,
+ refreshMediatorEditorMode: RefreshMediatorDialogMode.None
}
}
render() {
const { classes } = this.props;
+ const refreshMediatorAction = {
+ icon: Refresh, tooltip: 'Refresh Mediator Server Table', onClick: () => {
+ this.setState({
+ refreshMediatorEditorMode: RefreshMediatorDialogMode.RefreshMediatorTable
+ });
+ }
+ };
const addMediatorServerActionButton = {
icon: AddIcon, tooltip: 'Add', onClick: () => {
@@ -96,7 +107,7 @@ class MediatorServerSelectionComponent extends React.Component<MediatorServerSel
};
return (
<>
- <MediatorServersTable stickyHeader title={"Mediator"} customActionButtons={[addMediatorServerActionButton]} idProperty={"id"}
+ <MediatorServersTable stickyHeader title={"Mediator"} customActionButtons={[refreshMediatorAction, addMediatorServerActionButton]} idProperty={"id"}
{...this.props.mediatorServersActions} {...this.props.mediatorServersProperties} columns={[
{ property: "name", title: "Name", type: ColumnType.text },
{ property: "url", title: "Url", type: ColumnType.text },
@@ -113,6 +124,10 @@ class MediatorServerSelectionComponent extends React.Component<MediatorServerSel
mediatorServer={this.state.mediatorServerToEdit}
mode={this.state.mediatorServerEditorMode}
onClose={this.onCloseEditMediatorServerDialog} />
+ <RefreshMediatorDialog
+ mode={this.state.refreshMediatorEditorMode}
+ onClose={this.onCloseRefreshMediatorDialog}
+ />
</>
);
}
@@ -158,6 +173,11 @@ class MediatorServerSelectionComponent extends React.Component<MediatorServerSel
mediatorServerToEdit: emptyMediatorServer,
});
}
+ private onCloseRefreshMediatorDialog = () => {
+ this.setState({
+ refreshMediatorEditorMode: RefreshMediatorDialogMode.None
+ });
+ }
}
diff --git a/sdnr/wt/odlux/apps/minimumApp/package.json b/sdnr/wt/odlux/apps/minimumApp/package.json
index 069cb138c..bcda2fb58 100644
--- a/sdnr/wt/odlux/apps/minimumApp/package.json
+++ b/sdnr/wt/odlux/apps/minimumApp/package.json
@@ -24,17 +24,17 @@
"@odlux/framework": "*"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/apps/networkMapApp/package.json b/sdnr/wt/odlux/apps/networkMapApp/package.json
index 7119f1b38..cde312ce3 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/package.json
+++ b/sdnr/wt/odlux/apps/networkMapApp/package.json
@@ -27,18 +27,18 @@
"object.values": "^1.1.1"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
}
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx
index b2c724636..57091aebf 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/components/details/linkDetails.tsx
@@ -68,7 +68,9 @@ const LinkDetails: React.FunctionComponent<props> = (props) => {
const distance = props.link.length > 0 ? props.link.length : props.link.calculatedLength;
const azimuthA = props.link.azimuthA;
const azimuthB = props.link.azimuthB;
- window.open(`/#/linkCalculation?lat1=${siteA.lat}&lon1=${siteA.lon}&lat2=${siteB.lat}&lon2=${siteB.lon}&siteA=${nameA}&siteB=${nameB}&azimuthA=${azimuthA}&azimuthB=${azimuthB}&distance=${distance}&amslSiteA=${siteA.amsl}&AGLsiteA=${siteA.antennaHeight}&amslSiteB=${siteB.amsl}&AGLsiteB=${siteB.antennaHeight}`)
+
+ const baseUrl = window.location.pathname.split('#')[0];
+ window.open(`${baseUrl}#/linkCalculation?lat1=${siteA.lat}&lon1=${siteA.lon}&lat2=${siteB.lat}&lon2=${siteB.lon}&siteA=${nameA}&siteB=${nameB}&azimuthA=${azimuthA}&azimuthB=${azimuthB}&distance=${distance}&amslSiteA=${siteA.amsl}&AGLsiteA=${siteA.antennaHeight}&amslSiteB=${siteB.amsl}&AGLsiteB=${siteB.antennaHeight}`)
}
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/handlers/mapReducer.ts b/sdnr/wt/odlux/apps/networkMapApp/src/handlers/mapReducer.ts
index b820746b5..442a5083c 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/handlers/mapReducer.ts
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/handlers/mapReducer.ts
@@ -56,12 +56,12 @@ export const MapReducer: IActionHandler<mapState> = (state=initialState, action:
}
else if(action instanceof HighlightSiteAction){
- state = Object.assign({}, state, {selectedLink: null, selectedSite:{type: "Feature", properties: {id: action.site.name, type:action.site.type}, geometry:{type:"Point", coordinates:[action.site.location.lon,action.site.location.lat ]}}})
+ state = Object.assign({}, state, {selectedLink: null, selectedSite:{type: "Feature", properties: {id: action.site.id, type:action.site.type}, geometry:{type:"Point", coordinates:[action.site.location.lon,action.site.location.lat ]}}})
}else if (action instanceof ZoomToSearchResultAction){
state = Object.assign({}, state, {zoomToElement:{lat: action.lat, lon: action.lon}});
}else if (action instanceof AddAlarmAction){
- state = Object.assign({}, state, {alarmlement:{type: "Feature", properties: {id: action.site.name, type:action.site.type}, geometry:{type:"Point", coordinates:[action.site.location.lon,action.site.location.lat ]}}});
+ state = Object.assign({}, state, {alarmlement:{type: "Feature", properties: {id: action.site.id, type:action.site.type}, geometry:{type:"Point", coordinates:[action.site.location.lon,action.site.location.lat ]}}});
}else if(action instanceof SetCoordinatesAction){
state = Object.assign({}, state, {lat:action.lat, lon: action.lon, zoom:action.zoom});
diff --git a/sdnr/wt/odlux/apps/networkMapApp/src/index.html b/sdnr/wt/odlux/apps/networkMapApp/src/index.html
index 9a7f77a29..e64c08c1e 100644
--- a/sdnr/wt/odlux/apps/networkMapApp/src/index.html
+++ b/sdnr/wt/odlux/apps/networkMapApp/src/index.html
@@ -20,8 +20,8 @@
require(["app","connectApp","faultApp", "networkMapApp", "configurationApp", "linkCalculationApp"], function (app, connectApp, faultApp, networkMapApp, configurationApp, linkCalculationApp) {
connectApp.register();
//faultApp.register();
- configurationApp.register();
- linkCalculationApp.register();
+ //configurationApp.register();
+ //linkCalculationApp.register();
networkMapApp.register();
app("./app.tsx").runApplication();
});
diff --git a/sdnr/wt/odlux/apps/performanceHistoryApp/package.json b/sdnr/wt/odlux/apps/performanceHistoryApp/package.json
index 2b69cc3c7..305fc07f4 100644
--- a/sdnr/wt/odlux/apps/performanceHistoryApp/package.json
+++ b/sdnr/wt/odlux/apps/performanceHistoryApp/package.json
@@ -27,17 +27,17 @@
"chart.js": "2.8.0"
},
"peerDependencies": {
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0"
}
} \ No newline at end of file
diff --git a/sdnr/wt/odlux/framework/package.json b/sdnr/wt/odlux/framework/package.json
index 3ecd34c23..345fc8b4c 100644
--- a/sdnr/wt/odlux/framework/package.json
+++ b/sdnr/wt/odlux/framework/package.json
@@ -25,18 +25,18 @@
"license": "Apache-2.0",
"peerDependencies": {
"@types/node": "11.11.6",
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@material-ui/core": "4.11.0",
"@material-ui/icons": "4.9.1",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
"@types/jquery": "3.3.10",
"jquery": "3.3.1",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1",
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0",
"@fortawesome/react-fontawesome": "0.1.3",
"@fortawesome/fontawesome-svg-core": "1.2.12",
"@fortawesome/free-solid-svg-icons": "5.6.3",
diff --git a/sdnr/wt/odlux/framework/pom.xml b/sdnr/wt/odlux/framework/pom.xml
index 3f9ecbee6..9d648b52d 100644
--- a/sdnr/wt/odlux/framework/pom.xml
+++ b/sdnr/wt/odlux/framework/pom.xml
@@ -46,7 +46,7 @@
<properties>
<buildtime>${maven.build.timestamp}</buildtime>
<distversion>ONAP Frankfurt (Neon, mdsal ${odl.mdsal.version})</distversion>
- <buildno>90.49cc396(21/02/17)</buildno>
+ <buildno>96.078ad12(21/03/25)</buildno>
<odlux.version>ONAP SDN-R | ONF Wireless for ${distversion} - Build: ${buildtime} ${buildno} ${project.version}</odlux.version>
</properties>
@@ -126,7 +126,7 @@
</goals>
<phase>initialize</phase>
<configuration>
- <arguments>add lerna@3.13.1 -W --exact</arguments>
+ <arguments>add lerna@3.22.1 -W --exact</arguments>
<installDirectory>${project.basedir}</installDirectory>
<workingDirectory>${project.basedir}/../</workingDirectory>
</configuration>
diff --git a/sdnr/wt/odlux/framework/src/app.tsx b/sdnr/wt/odlux/framework/src/app.tsx
index 23ae2fbc9..2d913be1b 100644
--- a/sdnr/wt/odlux/framework/src/app.tsx
+++ b/sdnr/wt/odlux/framework/src/app.tsx
@@ -68,6 +68,10 @@ export const runApplication = () => {
const initialToken = localStorage.getItem("userToken");
const applicationStore = applicationStoreCreator();
+ if (initialToken) {
+ applicationStore.dispatch(new UpdateUser(User.fromString(initialToken) || undefined));
+ }
+
window.onerror = function (msg: string, url: string, line: number, col: number, error: Error) {
// Note that col & error are new to the HTML 5 spec and may not be
// supported in every browser. It worked for me in Chrome.
@@ -98,9 +102,7 @@ export const runApplication = () => {
ReactDOM.render(<App />, document.getElementById('app'));
- if (initialToken) {
- applicationStore.dispatch(new UpdateUser(User.fromString(initialToken) || undefined));
- }
+
};
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/index.tsx b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx
index 7d4633bc6..c74fd1a38 100644
--- a/sdnr/wt/odlux/framework/src/components/material-table/index.tsx
+++ b/sdnr/wt/odlux/framework/src/components/material-table/index.tsx
@@ -32,13 +32,14 @@ import { EnhancedTableHead } from './tableHead';
import { EnhancedTableFilter } from './tableFilter';
import { ColumnModel, ColumnType } from './columnModel';
-import { Omit, Menu } from '@material-ui/core';
+import { Omit, Menu, makeStyles } from '@material-ui/core';
import { SvgIconProps } from '@material-ui/core/SvgIcon/SvgIcon';
import { DividerTypeMap } from '@material-ui/core/Divider';
import { MenuItemProps } from '@material-ui/core/MenuItem';
import { flexbox } from '@material-ui/system';
+import { RowDisabled } from './utilities';
export { ColumnModel, ColumnType } from './columnModel';
type propType = string | number | null | undefined | (string | number)[];
@@ -103,6 +104,34 @@ const styles = (theme: Theme) => createStyles({
}
});
+const useTableRowExtStyles = makeStyles((theme: Theme) => createStyles({
+ disabled: {
+ color: "rgba(180, 180, 180, 0.7)",
+ },
+}));
+
+type GetStatelessComponentProps<T> = T extends (props: infer P & { children?: React.ReactNode }) => any ? P : any;
+type TableRowExtProps = GetStatelessComponentProps<typeof TableRow> & { disabled: boolean };
+const TableRowExt : React.FC<TableRowExtProps> = (props) => {
+ const [disabled, setDisabled] = React.useState(true);
+ const classes = useTableRowExtStyles();
+
+ const onMouseDown = (ev: React.MouseEvent<HTMLElement>) => {
+ if (ev.button ===1){
+ setDisabled(!disabled);
+ ev.preventDefault();
+ ev.stopPropagation();
+ } else if (props.disabled && disabled) {
+ ev.preventDefault();
+ ev.stopPropagation();
+ }
+ };
+
+ return (
+ <TableRow {...{...props, color: props.disabled && disabled ? '#a0a0a0' : undefined , className: props.disabled && disabled ? classes.disabled : '', onMouseDown, onContextMenu: props.disabled && disabled ? onMouseDown : props.onContextMenu } } />
+ );
+};
+
export type MaterialTableComponentState<TData = {}> = {
order: 'asc' | 'desc';
orderBy: string | null;
@@ -130,7 +159,7 @@ type MaterialTableComponentBaseProps<TData> = WithStyles<typeof styles> & {
enableSelection?: boolean;
disableSorting?: boolean;
disableFilter?: boolean;
- customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void }[];
+ customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void, disabled?: boolean }[];
onHandleClick?(event: React.MouseEvent<HTMLTableRowElement>, rowData: TData): void;
createContextMenu?: (row: TData) => React.ReactElement<MenuItemProps | DividerTypeMap<{}, "hr">, React.ComponentType<MenuItemProps | DividerTypeMap<{}, "hr">>>[];
};
@@ -222,12 +251,12 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
<TableBody>
{showFilter && <EnhancedTableFilter columns={columns} filter={filter} onFilterChanged={this.onFilterChanged} enableSelection={this.props.enableSelection} /> || null}
{rows // may need ordering here
- .map((entry: TData & { [key: string]: any }, index) => {
+ .map((entry: TData & { [RowDisabled]?: boolean, [kex: string]: any }, index) => {
const entryId = getId(entry);
const isSelected = this.isSelected(entryId);
const contextMenu = (this.props.createContextMenu && this.state.contextMenuInfo.index === index && this.props.createContextMenu(entry)) || null;
return (
- <TableRow
+ <TableRowExt
hover
onClick={event => {
if (this.props.createContextMenu) {
@@ -252,9 +281,10 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
tabIndex={-1}
key={entryId}
selected={isSelected}
+ disabled={entry[RowDisabled] || false}
>
{this.props.enableSelection
- ? <TableCell padding="checkbox" style={{ width: "50px" }}>
+ ? <TableCell padding="checkbox" style={{ width: "50px", color: entry[RowDisabled] || false ? "inherit" : undefined } }>
<Checkbox checked={isSelected} />
</TableCell>
: null
@@ -264,7 +294,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
col => {
const style = col.width ? { width: col.width } : {};
return (
- <TableCell aria-label={col.title? col.title.toLowerCase().replace(/\s/g, "-") : col.property.toLowerCase().replace(/\s/g, "-")} key={col.property} align={col.type === ColumnType.numeric && !col.align ? "right" : col.align} style={style}>
+ <TableCell style={ entry[RowDisabled] || false ? { ...style, color: "inherit" } : style } aria-label={col.title? col.title.toLowerCase().replace(/\s/g, "-") : col.property.toLowerCase().replace(/\s/g, "-")} key={col.property} align={col.type === ColumnType.numeric && !col.align ? "right" : col.align} >
{col.type === ColumnType.custom && col.customControl
? <col.customControl className={col.className} style={col.style} rowData={entry} />
: col.type === ColumnType.boolean
@@ -280,7 +310,7 @@ class MaterialTableComponent<TData extends {} = {}> extends React.Component<Mate
anchorPosition={this.state.contextMenuInfo.mouseY != null && this.state.contextMenuInfo.mouseX != null ? { top: this.state.contextMenuInfo.mouseY, left: this.state.contextMenuInfo.mouseX } : undefined}>
{contextMenu}
</Menu> || null}
- </TableRow>
+ </TableRowExt>
);
})}
{emptyRows > 0 && (
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
index 3b2f8e0a8..f7de0a062 100644
--- a/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
+++ b/sdnr/wt/odlux/framework/src/components/material-table/tableToolbar.tsx
@@ -67,7 +67,7 @@ interface ITableToolbarComponentProps extends WithStyles<typeof styles> {
numSelected: number | null;
title?: string;
tableId?: string;
- customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void }[];
+ customActionButtons?: { icon: React.ComponentType<SvgIconProps>, tooltip?: string, onClick: () => void, disabled?: boolean }[];
onToggleFilter: () => void;
onExportToCsv: () => void;
}
@@ -110,7 +110,7 @@ class TableToolbarComponent extends React.Component<ITableToolbarComponentProps,
{this.props.customActionButtons
? this.props.customActionButtons.map((action, ind) => (
<Tooltip key={`custom-action-${ind}`} title={action.tooltip || ''}>
- <IconButton aria-label={buttonPrefix + `custom-action-${ind}`} onClick={() => action.onClick()}>
+ <IconButton disabled={action.disabled} aria-label={buttonPrefix + `custom-action-${ind}`} onClick={() => action.onClick()}>
<action.icon />
</IconButton>
</Tooltip>
diff --git a/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts
index 07ffe2ff5..544e14e01 100644
--- a/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts
+++ b/sdnr/wt/odlux/framework/src/components/material-table/utilities.ts
@@ -21,12 +21,14 @@ import { Dispatch } from '../../flux/store';
import { AddErrorInfoAction } from '../../actions/errorActions';
import { IApplicationStoreState } from '../../store/applicationStore';
+export const RowDisabled = Symbol("RowDisabled");
import { DataCallback } from ".";
+
export interface IExternalTableState<TData> {
order: 'asc' | 'desc';
orderBy: string | null;
selected: any[] | null;
- rows: TData[];
+ rows: (TData & { [RowDisabled]?: boolean })[];
total: number;
page: number;
rowsPerPage: number;
@@ -36,8 +38,31 @@ export interface IExternalTableState<TData> {
preFilter: { [property: string]: string };
}
+export type ExternalMethodes<TData> = {
+ reloadAction: (dispatch: Dispatch, getAppState: () => IApplicationStoreState) => Promise<void | AddErrorInfoAction>;
+ createActions: (dispatch: Dispatch, skipRefresh?: boolean) => {
+ onRefresh: () => void;
+ onHandleRequestSort: (orderBy: string) => void;
+ onHandleExplicitRequestSort: (property: string, sortOrder: "asc" | "desc") => void;
+ onToggleFilter: (refresh?: boolean | undefined) => void;
+ onFilterChanged: (property: string, filterTerm: string) => void;
+ onHandleChangePage: (page: number) => void;
+ onHandleChangeRowsPerPage: (rowsPerPage: number | null) => void;
+ };
+ createPreActions: (dispatch: Dispatch, skipRefresh?: boolean) => {
+ onPreFilterChanged: (preFilter: {
+ [key: string]: string;
+ }) => void;
+ };
+ createProperties: (state: IApplicationStoreState) => IExternalTableState<TData>;
+ actionHandler: IActionHandler<IExternalTableState<TData>, Action>;
+}
+
+
/** Create an actionHandler and actions for external table states. */
-export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>) {
+export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>) : ExternalMethodes<TData> ;
+export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>, disableRow: (data: TData) => boolean) : ExternalMethodes<TData>;
+export function createExternal<TData>(callback: DataCallback<TData>, selectState: (appState: IApplicationStoreState) => IExternalTableState<TData>, disableRow?: (data: TData) => boolean) : ExternalMethodes<TData> {
//#region Actions
abstract class TableAction extends Action { }
@@ -131,7 +156,9 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState
state = {
...state,
loading: false,
- rows: action.result.rows,
+ rows: disableRow
+ ? action.result.rows.map((row: TData) => ({...row, [RowDisabled]: disableRow(row) }))
+ : action.result.rows,
total: action.result.total,
page: action.result.page,
}
@@ -191,7 +218,7 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState
dispatch(new RefreshAction());
const ownState = selectState(getAppState());
const filter = { ...ownState.preFilter, ...(ownState.showFilter && ownState.filter || {}) };
- Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)).then(result => {
+ return Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter)).then(result => {
if (ownState.page > 0 && ownState.rowsPerPage * ownState.page > result.total) { //if result is smaller than the currently shown page, new search and repaginate
@@ -207,30 +234,7 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState
}
- }).catch(error => new AddErrorInfoAction(error));
- };
-
- const reloadActionAsync = async (dispatch: Dispatch, getAppState: () => IApplicationStoreState) => {
- dispatch(new RefreshAction());
- const ownState = selectState(getAppState());
- const filter = { ...ownState.preFilter, ...(ownState.showFilter && ownState.filter || {}) };
-
- try {
- const result = await Promise.resolve(callback(ownState.page, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter));
-
-
- if (ownState.page > 0 && ownState.rowsPerPage * ownState.page > result.total) { //if result is smaller than the currently shown page, new search and repaginate
-
- let newPage = Math.floor(result.total / ownState.rowsPerPage);
-
- const repaginationResult = await Promise.resolve(callback(newPage, ownState.rowsPerPage, ownState.orderBy, ownState.order, filter));
- dispatch(new SetResultAction(repaginationResult));
- } else {
- dispatch(new SetResultAction(result));
- }
- } catch (error) {
- new AddErrorInfoAction(error);
- }
+ }).catch(error => dispatch(new AddErrorInfoAction(error)));
};
const createPreActions = (dispatch: Dispatch, skipRefresh: boolean = false) => {
@@ -303,6 +307,6 @@ export function createExternal<TData>(callback: DataCallback<TData>, selectState
createProperties: createProperties,
createPreActions: createPreActions,
actionHandler: externalTableStateActionHandler,
- reloadActionAsync: reloadActionAsync,
}
-} \ No newline at end of file
+}
+
diff --git a/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts b/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts
index b5c1ee7b1..06df6709f 100644
--- a/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts
+++ b/sdnr/wt/odlux/framework/src/handlers/applicationStateHandler.ts
@@ -58,7 +58,7 @@ const applicationStateInit: IApplicationState = {
export const configureApplication = (config: ApplicationConfig) => {
applicationStateInit.authentication = config.authentication === "oauth" ? "oauth" : "basic";
- applicationStateInit.enablePolicy = config.authentication ? true : false;
+ applicationStateInit.enablePolicy = config.enablePolicy ? true : false;
}
export const applicationStateHandler: IActionHandler<IApplicationState> = (state = applicationStateInit, action) => {
diff --git a/sdnr/wt/odlux/framework/src/services/notificationService.ts b/sdnr/wt/odlux/framework/src/services/notificationService.ts
index 30091b574..5625b1f55 100644
--- a/sdnr/wt/odlux/framework/src/services/notificationService.ts
+++ b/sdnr/wt/odlux/framework/src/services/notificationService.ts
@@ -15,7 +15,6 @@
* the License.
* ============LICENSE_END==========================================================================
*/
-import * as X2JS from 'x2js';
import { ApplicationStore } from '../store/applicationStore';
import { SetWebsocketAction } from '../actions/websocketAction';
@@ -26,81 +25,95 @@ let userLoggedOut = false;
let wasWebsocketConnectionEstablished: undefined | boolean;
let applicationStore: ApplicationStore | null;
-
export interface IFormatedMessage {
- notifType: string | null;
- time: string;
+ "event-time": string,
+ "data": {
+ "counter": number,
+ "attribute-name": string,
+ "time-stamp": string,
+ "object-id-ref": string,
+ "new-value": string
+ },
+ "node-id": string,
+ "type": {
+ "namespace": string,
+ "revision": string,
+ "type": string
+ }
}
export type SubscriptionCallback<TMessage extends IFormatedMessage = IFormatedMessage> = (msg: TMessage) => void;
-function formatData(event: MessageEvent): IFormatedMessage | undefined {
-
- var x2js = new X2JS();
- var jsonObj: { [key: string]: IFormatedMessage } = x2js.xml2js(event.data);
- if (jsonObj && typeof (jsonObj) === 'object') {
-
- const notifType = Object.keys(jsonObj)[0];
- const formated = jsonObj[notifType];
- formated.notifType = notifType;
- formated.time = new Date().toISOString();
- return formated;
- }
- return undefined;
-
+function setCurrentSubscriptions(notificationSocket: WebSocket) {
+ const scopesToSubscribe = Object.keys(subscriptions);
+ if (notificationSocket.readyState === notificationSocket.OPEN) {
+ const data = {
+ 'data': 'scopes',
+ 'scopes':[{
+ "schema":{
+ "namespace":"*",
+ "revision":"*",
+ "notification": scopesToSubscribe
+ }
+ }]
+ };
+ notificationSocket.send(JSON.stringify(data));
+ return true;
+ };
+ return false;
}
-export function subscribe<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>): boolean {
+function addScope<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>) {
const scopes = scope instanceof Array ? scope : [scope];
- // send all new scopes to subscribe
- const newScopesToSubscribe: string[] = scopes.reduce((acc: string[], cur: string) => {
- const currentCallbacks = subscriptions[cur];
- if (currentCallbacks) {
- if (!currentCallbacks.some(c => c === callback)) {
- currentCallbacks.push(callback);
+ // send all new scopes to subscribe
+ const newScopesToSubscribe: string[] = scopes.reduce((acc: string[], cur: string) => {
+ const currentCallbacks = subscriptions[cur];
+ if (currentCallbacks) {
+ if (!currentCallbacks.some(c => c === callback)) {
+ currentCallbacks.push(callback);
+ }
+ } else {
+ subscriptions[cur] = [callback];
+ acc.push(cur);
}
- } else {
- subscriptions[cur] = [callback];
- acc.push(cur);
- }
- return acc;
- }, []);
+ return acc;
+ }, []);
- if (newScopesToSubscribe.length === 0) {
- return true;
- }
+ if (newScopesToSubscribe.length === 0) {
+ return true;
+ }
+ return false;
+}
- return true;
+function removeScope<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>) {
+ const scopes = scope instanceof Array ? scope : [scope];
+ scopes.forEach(s => {
+ const callbacks = subscriptions[s];
+ const index = callbacks && callbacks.indexOf(callback);
+ if (index > -1) {
+ callbacks.splice(index, 1);
+ }
+ if (callbacks.length === 0) {
+ subscriptions[s] === undefined;
+ }
+ });
}
+export function subscribe<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>): Promise<boolean> {
+ addScope(scope, callback)
+ return socketReady && socketReady.then((notificationSocket) => {
+ // send a subscription to all active scopes
+ return setCurrentSubscriptions(notificationSocket);
+ }) || true;
+}
export function unsubscribe<TMessage extends IFormatedMessage = IFormatedMessage>(scope: string | string[], callback: SubscriptionCallback<TMessage>): Promise<boolean> {
- return socketReady.then((notificationSocket) => {
- const scopes = scope instanceof Array ? scope : [scope];
- scopes.forEach(s => {
- const callbacks = subscriptions[s];
- const index = callbacks && callbacks.indexOf(callback);
- if (index > -1) {
- callbacks.splice(index, 1);
- }
- if (callbacks.length === 0) {
- subscriptions[s] === undefined;
- }
- });
-
+ removeScope(scope, callback);
+ return socketReady && socketReady.then((notificationSocket) => {
// send a subscription to all active scopes
- const scopesToSubscribe = Object.keys(subscriptions);
- if (notificationSocket.readyState === notificationSocket.OPEN) {
- const data = {
- 'data': 'scopes',
- 'scopes': scopesToSubscribe
- };
- notificationSocket.send(JSON.stringify(data));
- return true;
- }
- return false;
- });
+ return setCurrentSubscriptions(notificationSocket);
+ }) || true;
}
export const startNotificationService = (store: ApplicationStore) => {
@@ -111,24 +124,24 @@ const connect = (): Promise<WebSocket> => {
return new Promise((resolve, reject) => {
const notificationSocket = new WebSocket(socketUrl);
- notificationSocket.onmessage = (event) => {
+ notificationSocket.onmessage = (event: MessageEvent<string>) => {
// process received event
- if (typeof event.data === 'string') {
- const formated = formatData(event);
- if (formated && formated.notifType) {
- const callbacks = subscriptions[formated.notifType];
+
+ if (event.data && typeof event.data === "string" ) {
+ const msg = JSON.parse(event.data) as IFormatedMessage;
+ const callbacks = msg?.type?.type && subscriptions[msg.type.type];
if (callbacks) {
callbacks.forEach(cb => {
// ensure all callbacks will be called
try {
- return cb(formated);
+ return cb(msg);
} catch (reason) {
console.error(reason);
}
});
}
}
- }
+
};
notificationSocket.onerror = function (error) {
@@ -148,14 +161,7 @@ const connect = (): Promise<WebSocket> => {
resolve(notificationSocket);
// send a subscription to all active scopes
- const scopesToSubscribe = Object.keys(subscriptions);
- if (notificationSocket.readyState === notificationSocket.OPEN) {
- const data = {
- 'data': 'scopes',
- 'scopes': scopesToSubscribe
- };
- notificationSocket.send(JSON.stringify(data));
- };
+ setCurrentSubscriptions(notificationSocket);
};
notificationSocket.onclose = function (event) {
@@ -171,8 +177,6 @@ const connect = (): Promise<WebSocket> => {
}
-
-
export const startWebsocketSession = () => {
socketReady = connect();
userLoggedOut = false;
diff --git a/sdnr/wt/odlux/framework/src/services/restService.ts b/sdnr/wt/odlux/framework/src/services/restService.ts
index f05c7b89f..c7b122449 100644
--- a/sdnr/wt/odlux/framework/src/services/restService.ts
+++ b/sdnr/wt/odlux/framework/src/services/restService.ts
@@ -15,6 +15,8 @@
* the License.
* ============LICENSE_END==========================================================================
*/
+
+
import { ApplicationStore } from "../store/applicationStore";
import { ReplaceAction } from "../actions/navigationActions";
@@ -30,6 +32,46 @@ export const formEncode = (params: { [key: string]: string | number }) => Object
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key].toString());
}).join('&');
+const wildcardToRegexp = (pattern: string) => {
+ return new RegExp('^' + pattern.split(/\*\*/).map((p) => p.split(/\*+/).map((i) => i.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')).join('^[/]')).join('.*') + '$');
+};
+
+export const getAccessPolicyByUrl = (url: string) => {
+ const result = {
+ GET : false,
+ POST: false,
+ PUT: false,
+ PATCH: false,
+ DELETE: false,
+ };
+
+ if (!applicationStore) return result;
+
+ const { state: { framework: { applicationState: { enablePolicy }, authenticationState: { policies }}} } = applicationStore!;
+
+ result.GET = true;
+ result.POST = true;
+ result.PUT = true;
+ result.PATCH = true;
+ result.DELETE = true;
+
+ if (!enablePolicy || !policies || policies.length === 0) return result;
+
+ policies.forEach(p => {
+ const re = wildcardToRegexp(p.path);
+ if (re.test(url)) {
+ result.GET = p.methods.get != null ? p.methods.get : result.GET ;
+ result.POST = p.methods.post != null ? p.methods.post : result.POST ;
+ result.PUT = p.methods.put != null ? p.methods.put : result.PUT ;
+ result.PATCH = p.methods.patch != null ? p.methods.patch : result.PATCH ;
+ result.DELETE = p.methods.delete != null ? p.methods.delete : result.DELETE ;
+ }
+ });
+
+ return result;
+
+}
+
/** Sends a rest request to the given path.
* @returns The data, or null it there was any error
*/
diff --git a/sdnr/wt/odlux/framework/src/views/about.tsx b/sdnr/wt/odlux/framework/src/views/about.tsx
index f97d6ffb3..5d2257a3f 100644
--- a/sdnr/wt/odlux/framework/src/views/about.tsx
+++ b/sdnr/wt/odlux/framework/src/views/about.tsx
@@ -20,6 +20,7 @@ import * as marked from 'marked';
import * as hljs from 'highlight.js';
import { requestRestExt } from '../services/restService';
import { Button, Typography } from '@material-ui/core';
+import createBreakpoints from '@material-ui/core/styles/createBreakpoints';
const defaultRenderer = new marked.Renderer();
defaultRenderer.link = (href, title, text) => (
`<a target="_blank" rel="noopener noreferrer" href="${href}" title="${title}">${text}</a>`
@@ -30,6 +31,23 @@ interface AboutState {
isContentLoadedSucessfully: boolean;
}
+type odluxVersion= {version:string,build:string, framework: string,
+ applications:{
+ configurationApp: string,
+ connectApp: string,
+ eventLogApp: string,
+ faultApp: string,
+ helpApp: string,
+ inventoryApp: string,
+ linkCalculationApp: string,
+ maintenanceApp: string,
+ mediatorApp: string,
+ networkMapApp: string,
+ permanceHistoryApp: string
+ }};
+
+type topologyVersion = {version: string};
+
class AboutComponent extends React.Component<any, AboutState> {
textarea: React.RefObject<HTMLTextAreaElement>;
@@ -40,23 +58,58 @@ class AboutComponent extends React.Component<any, AboutState> {
this.textarea = React.createRef();
this.loadAboutContent();
}
- private getMarkOdluxVersionMarkdownTable(data:{version:string,build:string}|null|undefined):string{
+
+ private getMarkOdluxVersionMarkdownTable(data:odluxVersion|null|undefined):string{
if(!data) {
return "";
+ }else{
+ let applicationVersions= '';
+ if(data.applications){
+
+ applicationVersions = `| Framework | ${data.framework}|\n `+
+ `| ConnectApp | ${data.applications.connectApp}|\n `+
+ `| FaultApp | ${data.applications.faultApp}|\n `+
+ `| MaintenanceApp | ${data.applications.maintenanceApp}|\n `+
+ `| ConfigurationApp | ${data.applications.configurationApp}|\n `+
+ `| PerformanceHistoryApp | ${data.applications.permanceHistoryApp}|\n `+
+ `| InventoryApp | ${data.applications.inventoryApp}|\n `+
+ `| EventLogApp | ${data.applications.eventLogApp}|\n `+
+ `| MediatorApp | ${data.applications.mediatorApp}|\n `+
+ `| NetworkMapApp | ${data.applications.networkMapApp}|\n `+
+ `| LinkCalculatorApp | ${data.applications.linkCalculationApp}|\n `+
+ `| HelpApp | ${data.applications.helpApp}|\n `;
+ }
+
+ return `| | |\n| --- | --- |\n| Version | ${data.version} |\n| Build timestamp | ${data.build}|\n`+
+ applicationVersions;
}
- return `| | |\n| --- | --- |\n| Version | ${data.version} |\n| Build timestamp | ${data.build}|`
}
+
+ private getTopologyVersionMarkdownTable(data: topologyVersion|null|undefined){
+ if(!data){
+ return "No version";
+ }
+ else
+ {
+ return `| | |\n| --- | --- |\n| Version | ${data.version} |\n`
+ }
+ }
+
private loadAboutContent(): void {
const baseUri = window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/")+1);
const p1 = requestRestExt<string>('/about');
- const p2 = requestRestExt<{version:string,build:string}>(`${baseUri}version.json`);
- Promise.all([p1,p2]).then((responses) => {
+ const p2 = requestRestExt<odluxVersion>(`${baseUri}version.json`);
+ const p3 = requestRestExt<any>(`/topology/info/version`);
+
+ Promise.all([p1,p2, p3]).then((responses) => {
const response = responses[0];
- const response2 = responses[1];
+ const response2 = responses[1];
+ const response3 = responses[2];
const content = response.status == 200 ? response.data : `${response.status} ${response.message}` || "Server error";
- const content2 = `\n## ODLUX Version Info\n`+(response2.status == 200 ? this.getMarkOdluxVersionMarkdownTable(response2.data) : `${response2.status} ${response2.message}` || "ODLUX Server error");
+ const content2 = `\n## ODLUX Version Info\n`+(response2.status == 200 ? this.getMarkOdluxVersionMarkdownTable(response2.data) : `${response2.message}` || "ODLUX Server error");
+ const content3 = `\n## Topology API Version Info\n`+(response3.status == 200 ? this.getTopologyVersionMarkdownTable(response3.data): `Topology API not available`);
const loadedSucessfully = response.status == 200 ? true : false;
- this.setState({ content: (content + content2) || null, isContentLoadedSucessfully: loadedSucessfully });
+ this.setState({ content: (content + content2 + content3 ) || null, isContentLoadedSucessfully: loadedSucessfully });
}).catch((error) => {
this.setState({ content: error })
})
diff --git a/sdnr/wt/odlux/framework/tsconfig.json b/sdnr/wt/odlux/framework/tsconfig.json
index d801f7c8e..cb36bc81a 100644
--- a/sdnr/wt/odlux/framework/tsconfig.json
+++ b/sdnr/wt/odlux/framework/tsconfig.json
@@ -4,7 +4,7 @@
"outDir": "./dist",
"sourceMap": true,
"forceConsistentCasingInFileNames": true,
- "allowSyntheticDefaultImports": false,
+ "allowSyntheticDefaultImports": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"noFallthroughCasesInSwitch": true,
diff --git a/sdnr/wt/odlux/framework/webpack.config.js b/sdnr/wt/odlux/framework/webpack.config.js
index 5d0d8fc9a..b5d31c262 100644
--- a/sdnr/wt/odlux/framework/webpack.config.js
+++ b/sdnr/wt/odlux/framework/webpack.config.js
@@ -201,55 +201,55 @@ module.exports = (env) => {
proxy: {
"/about": {
// target: "http://10.20.6.29:48181",
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/yang-schema/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/oauth/": {
// target: "https://10.20.35.188:30205",
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/oauth2/": {
// target: "https://10.20.35.188:30205",
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/database/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/restconf/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/rests/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/help/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/about/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/tree/": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
secure: false
},
"/websocket": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
ws: true,
changeOrigin: true,
secure: false
},
"/apidoc": {
- target: "http://sdnr:8181",
+ target: "http://localhost:18181",
ws: true,
changeOrigin: true,
secure: false
diff --git a/sdnr/wt/odlux/installer/pom.xml b/sdnr/wt/odlux/installer/pom.xml
index 919c0a01b..50a90da9b 100644
--- a/sdnr/wt/odlux/installer/pom.xml
+++ b/sdnr/wt/odlux/installer/pom.xml
@@ -20,7 +20,8 @@
~
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
diff --git a/sdnr/wt/odlux/odlux.properties b/sdnr/wt/odlux/odlux.properties
index e4d7fdc01..e2cc41d3a 100644
--- a/sdnr/wt/odlux/odlux.properties
+++ b/sdnr/wt/odlux/odlux.properties
@@ -1,12 +1,12 @@
-odlux.framework.buildno=90.49cc396(21/02/17)
-odlux.apps.configurationApp.buildno=89.977e4de(21/02/10)
-odlux.apps.connectApp.buildno=89.977e4de(21/02/10)
-odlux.apps.eventLogApp.buildno=81.1c38886(20/12/04)
-odlux.apps.faultApp.buildno=81.1c38886(20/12/04)
-odlux.apps.helpApp.buildno=81.1c38886(20/12/04)
-odlux.apps.inventoryApp.buildno=89.977e4de(21/02/10)
-odlux.apps.linkCalculationApp.buildno=90.49cc396(21/02/17)
-odlux.apps.maintenanceApp.buildno=81.1c38886(20/12/04)
-odlux.apps.mediatorApp.buildno=81.1c38886(20/12/04)
-odlux.apps.networkMapApp.buildno=90.49cc396(21/02/17)
+odlux.framework.buildno=96.078ad12(21/03/25)
+odlux.apps.configurationApp.buildno=96.078ad12(21/03/25)
+odlux.apps.connectApp.buildno=96.078ad12(21/03/25)
+odlux.apps.eventLogApp.buildno=96.078ad12(21/03/25)
+odlux.apps.faultApp.buildno=96.078ad12(21/03/25)
+odlux.apps.helpApp.buildno=96.078ad12(21/03/25)
+odlux.apps.inventoryApp.buildno=96.078ad12(21/03/25)
+odlux.apps.linkCalculationApp.buildno=96.078ad12(21/03/25)
+odlux.apps.maintenanceApp.buildno=96.078ad12(21/03/25)
+odlux.apps.mediatorApp.buildno=96.078ad12(21/03/25)
+odlux.apps.networkMapApp.buildno=96.078ad12(21/03/25)
odlux.apps.permanceHistoryApp.buildno=81.1c38886(20/12/04)
diff --git a/sdnr/wt/odlux/package.json b/sdnr/wt/odlux/package.json
index c208224cf..5bfcf74a0 100644
--- a/sdnr/wt/odlux/package.json
+++ b/sdnr/wt/odlux/package.json
@@ -19,34 +19,34 @@
"@material-ui/lab": "4.0.0-alpha.41",
"@types/classnames": "2.2.6",
"@types/flux": "3.1.8",
+ "@types/glob-to-regexp": "0.4.0",
"@types/jquery": "3.3.10",
"@types/jsonwebtoken": "7.2.8",
- "@types/minimatch": "3.0.3",
"@types/node": "11.11.6",
- "@types/react": "16.9.19",
- "@types/react-dom": "16.9.5",
- "@types/react-router-dom": "4.3.1",
+ "@types/react": "17.0.3",
+ "@types/react-dom": "17.0.2",
+ "@types/react-router-dom": "5.1.7",
"@types/react-transition-group": "2.0.15",
"classnames": "2.2.6",
"csstype": "2.6.8",
"jquery": "3.3.1",
"jsonwebtoken": "8.3.0",
"jss": "10.0.3",
- "lerna": "3.13.1",
+ "lerna": "3.22.1",
"material-ui-confirm": "2.1.1",
"notistack": "0.9.6",
"prop-types": "15.7.2",
- "react": "16.12.0",
- "react-dom": "16.12.0",
- "react-router-dom": "4.3.1",
- "react-transition-group": "4.3.0",
- "x2js": "3.2.3"
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-router-dom": "5.2.0",
+ "react-transition-group": "4.3.0"
},
"devDependencies": {
"@babel/core": "7.1.0",
"@babel/polyfill": "7.0.0",
"@babel/preset-env": "7.1.0",
"@babel/preset-react": "7.0.0",
+ "@octokit/core": "3.0.0",
"@types/jest": "23.3.12",
"autoprefixer": "9.1.5",
"babel-loader": "8.0.4",
@@ -54,12 +54,12 @@
"css-loader": "1.0.0",
"extract-text-webpack-plugin": "next",
"file-loader": "2.0.0",
+ "glob-to-regexp": "0.4.1",
"html-webpack-include-assets-plugin": "1.0.5",
"html-webpack-plugin": "3.2.0",
"jest": "23.6.0",
"less": "3.8.1",
"less-loader": "4.1.0",
- "minimatch": "3.0.4",
"node-sass": "4.12.0",
"postcss-loader": "3.0.0",
"requirejs": "2.3.6",
@@ -77,7 +77,7 @@
"tslint-eslint-rules": "4.1.1",
"tslint-react": "3.6.0",
"tslint-react-recommended": "1.0.15",
- "typescript": "3.7.2",
+ "typescript": "4.1.4",
"typings-for-css-modules-loader": "1.7.0",
"url-loader": "1.1.2",
"webpack": "4.28.4",
diff --git a/sdnr/wt/odlux/yarn.lock b/sdnr/wt/odlux/yarn.lock
index cedbf4c7f..842aebb5a 100644
--- a/sdnr/wt/odlux/yarn.lock
+++ b/sdnr/wt/odlux/yarn.lock
@@ -648,6 +648,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.12.1":
+ version "7.13.10"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
+ integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
"@babel/template@^7.1.0", "@babel/template@^7.10.4":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
@@ -686,6 +693,80 @@
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
+"@evocateur/libnpmaccess@^3.1.2":
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz#ecf7f6ce6b004e9f942b098d92200be4a4b1c845"
+ integrity sha512-KSCAHwNWro0CF2ukxufCitT9K5LjL/KuMmNzSu8wuwN2rjyKHD8+cmOsiybK+W5hdnwc5M1SmRlVCaMHQo+3rg==
+ dependencies:
+ "@evocateur/npm-registry-fetch" "^4.0.0"
+ aproba "^2.0.0"
+ figgy-pudding "^3.5.1"
+ get-stream "^4.0.0"
+ npm-package-arg "^6.1.0"
+
+"@evocateur/libnpmpublish@^1.2.2":
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz#55df09d2dca136afba9c88c759ca272198db9f1a"
+ integrity sha512-MJrrk9ct1FeY9zRlyeoyMieBjGDG9ihyyD9/Ft6MMrTxql9NyoEx2hw9casTIP4CdqEVu+3nQ2nXxoJ8RCXyFg==
+ dependencies:
+ "@evocateur/npm-registry-fetch" "^4.0.0"
+ aproba "^2.0.0"
+ figgy-pudding "^3.5.1"
+ get-stream "^4.0.0"
+ lodash.clonedeep "^4.5.0"
+ normalize-package-data "^2.4.0"
+ npm-package-arg "^6.1.0"
+ semver "^5.5.1"
+ ssri "^6.0.1"
+
+"@evocateur/npm-registry-fetch@^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/@evocateur/npm-registry-fetch/-/npm-registry-fetch-4.0.0.tgz#8c4c38766d8d32d3200fcb0a83f064b57365ed66"
+ integrity sha512-k1WGfKRQyhJpIr+P17O5vLIo2ko1PFLKwoetatdduUSt/aQ4J2sJrJwwatdI5Z3SiYk/mRH9S3JpdmMFd/IK4g==
+ dependencies:
+ JSONStream "^1.3.4"
+ bluebird "^3.5.1"
+ figgy-pudding "^3.4.1"
+ lru-cache "^5.1.1"
+ make-fetch-happen "^5.0.0"
+ npm-package-arg "^6.1.0"
+ safe-buffer "^5.1.2"
+
+"@evocateur/pacote@^9.6.3":
+ version "9.6.5"
+ resolved "https://registry.yarnpkg.com/@evocateur/pacote/-/pacote-9.6.5.tgz#33de32ba210b6f17c20ebab4d497efc6755f4ae5"
+ integrity sha512-EI552lf0aG2nOV8NnZpTxNo2PcXKPmDbF9K8eCBFQdIZwHNGN/mi815fxtmUMa2wTa1yndotICIDt/V0vpEx2w==
+ dependencies:
+ "@evocateur/npm-registry-fetch" "^4.0.0"
+ bluebird "^3.5.3"
+ cacache "^12.0.3"
+ chownr "^1.1.2"
+ figgy-pudding "^3.5.1"
+ get-stream "^4.1.0"
+ glob "^7.1.4"
+ infer-owner "^1.0.4"
+ lru-cache "^5.1.1"
+ make-fetch-happen "^5.0.0"
+ minimatch "^3.0.4"
+ minipass "^2.3.5"
+ mississippi "^3.0.0"
+ mkdirp "^0.5.1"
+ normalize-package-data "^2.5.0"
+ npm-package-arg "^6.1.0"
+ npm-packlist "^1.4.4"
+ npm-pick-manifest "^3.0.0"
+ osenv "^0.1.5"
+ promise-inflight "^1.0.1"
+ promise-retry "^1.1.1"
+ protoduck "^5.0.1"
+ rimraf "^2.6.3"
+ safe-buffer "^5.2.0"
+ semver "^5.7.0"
+ ssri "^6.0.1"
+ tar "^4.4.10"
+ unique-filename "^1.1.1"
+ which "^1.3.1"
+
"@fimbul/bifrost@^0.21.0":
version "0.21.0"
resolved "https://registry.yarnpkg.com/@fimbul/bifrost/-/bifrost-0.21.0.tgz#d0fafa25938fda475657a6a1e407a21bbe02c74e"
@@ -732,235 +813,239 @@
humps "^2.0.1"
prop-types "^15.5.10"
-"@lerna/add@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.13.1.tgz#2cd7838857edb3b43ed73e3c21f69a20beb9b702"
- integrity sha512-cXk42YbuhzEnADCK8Qte5laC9Qo03eJLVnr0qKY85jQUM/T4URe3IIUemqpg0CpVATrB+Vz+iNdeqw9ng1iALw==
+"@lerna/add@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.21.0.tgz#27007bde71cc7b0a2969ab3c2f0ae41578b4577b"
+ integrity sha512-vhUXXF6SpufBE1EkNEXwz1VLW03f177G9uMOFMQkp6OJ30/PWg4Ekifuz9/3YfgB2/GH8Tu4Lk3O51P2Hskg/A==
dependencies:
- "@lerna/bootstrap" "3.13.1"
- "@lerna/command" "3.13.1"
- "@lerna/filter-options" "3.13.0"
- "@lerna/npm-conf" "3.13.0"
+ "@evocateur/pacote" "^9.6.3"
+ "@lerna/bootstrap" "3.21.0"
+ "@lerna/command" "3.21.0"
+ "@lerna/filter-options" "3.20.0"
+ "@lerna/npm-conf" "3.16.0"
"@lerna/validation-error" "3.13.0"
dedent "^0.7.0"
npm-package-arg "^6.1.0"
- p-map "^1.2.0"
- pacote "^9.5.0"
- semver "^5.5.0"
-
-"@lerna/batch-packages@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/batch-packages/-/batch-packages-3.13.0.tgz#697fde5be28822af9d9dca2f750250b90a89a000"
- integrity sha512-TgLBTZ7ZlqilGnzJ3xh1KdAHcySfHytgNRTdG9YomfriTU6kVfp1HrXxKJYVGs7ClPUNt2CTFEOkw0tMBronjw==
- dependencies:
- "@lerna/package-graph" "3.13.0"
- "@lerna/validation-error" "3.13.0"
- npmlog "^4.1.2"
-
-"@lerna/bootstrap@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.13.1.tgz#f2edd7c8093c8b139e78b0ca5f845f23efd01f08"
- integrity sha512-mKdi5Ds5f82PZwEFyB9/W60I3iELobi1i87sTeVrbJh/um7GvqpSPy7kG/JPxyOdMpB2njX6LiJgw+7b6BEPWw==
- dependencies:
- "@lerna/batch-packages" "3.13.0"
- "@lerna/command" "3.13.1"
- "@lerna/filter-options" "3.13.0"
- "@lerna/has-npm-version" "3.13.0"
- "@lerna/npm-install" "3.13.0"
- "@lerna/package-graph" "3.13.0"
+ p-map "^2.1.0"
+ semver "^6.2.0"
+
+"@lerna/bootstrap@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.21.0.tgz#bcd1b651be5b0970b20d8fae04c864548123aed6"
+ integrity sha512-mtNHlXpmvJn6JTu0KcuTTPl2jLsDNud0QacV/h++qsaKbhAaJr/FElNZ5s7MwZFUM3XaDmvWzHKaszeBMHIbBw==
+ dependencies:
+ "@lerna/command" "3.21.0"
+ "@lerna/filter-options" "3.20.0"
+ "@lerna/has-npm-version" "3.16.5"
+ "@lerna/npm-install" "3.16.5"
+ "@lerna/package-graph" "3.18.5"
"@lerna/pulse-till-done" "3.13.0"
- "@lerna/rimraf-dir" "3.13.0"
- "@lerna/run-lifecycle" "3.13.0"
- "@lerna/run-parallel-batches" "3.13.0"
- "@lerna/symlink-binary" "3.13.0"
- "@lerna/symlink-dependencies" "3.13.0"
+ "@lerna/rimraf-dir" "3.16.5"
+ "@lerna/run-lifecycle" "3.16.2"
+ "@lerna/run-topologically" "3.18.5"
+ "@lerna/symlink-binary" "3.17.0"
+ "@lerna/symlink-dependencies" "3.17.0"
"@lerna/validation-error" "3.13.0"
dedent "^0.7.0"
- get-port "^3.2.0"
- multimatch "^2.1.0"
+ get-port "^4.2.0"
+ multimatch "^3.0.0"
npm-package-arg "^6.1.0"
npmlog "^4.1.2"
p-finally "^1.0.0"
- p-map "^1.2.0"
+ p-map "^2.1.0"
p-map-series "^1.0.0"
p-waterfall "^1.0.0"
read-package-tree "^5.1.6"
- semver "^5.5.0"
+ semver "^6.2.0"
-"@lerna/changed@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.13.1.tgz#dc92476aad43c932fe741969bbd0bcf6146a4c52"
- integrity sha512-BRXitEJGOkoudbxEewW7WhjkLxFD+tTk4PrYpHLyCBk63pNTWtQLRE6dc1hqwh4emwyGncoyW6RgXfLgMZgryw==
+"@lerna/changed@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.21.0.tgz#108e15f679bfe077af500f58248c634f1044ea0b"
+ integrity sha512-hzqoyf8MSHVjZp0gfJ7G8jaz+++mgXYiNs9iViQGA8JlN/dnWLI5sWDptEH3/B30Izo+fdVz0S0s7ydVE3pWIw==
dependencies:
- "@lerna/collect-updates" "3.13.0"
- "@lerna/command" "3.13.1"
- "@lerna/listable" "3.13.0"
+ "@lerna/collect-updates" "3.20.0"
+ "@lerna/command" "3.21.0"
+ "@lerna/listable" "3.18.5"
"@lerna/output" "3.13.0"
- "@lerna/version" "3.13.1"
-"@lerna/check-working-tree@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.13.0.tgz#1ddcd4d9b1aceb65efaaa4cd1333a66706d67c9c"
- integrity sha512-dsdO15NXX5To+Q53SYeCrBEpiqv4m5VkaPZxbGQZNwoRen1MloXuqxSymJANQn+ZLEqarv5V56gydebeROPH5A==
+"@lerna/check-working-tree@3.16.5":
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.16.5.tgz#b4f8ae61bb4523561dfb9f8f8d874dd46bb44baa"
+ integrity sha512-xWjVBcuhvB8+UmCSb5tKVLB5OuzSpw96WEhS2uz6hkWVa/Euh1A0/HJwn2cemyK47wUrCQXtczBUiqnq9yX5VQ==
dependencies:
- "@lerna/describe-ref" "3.13.0"
+ "@lerna/collect-uncommitted" "3.16.5"
+ "@lerna/describe-ref" "3.16.5"
"@lerna/validation-error" "3.13.0"
-"@lerna/child-process@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-3.13.0.tgz#84e35adf3217a6983edd28080657b9596a052674"
- integrity sha512-0iDS8y2jiEucD4fJHEzKoc8aQJgm7s+hG+0RmDNtfT0MM3n17pZnf5JOMtS1FJp+SEXOjMKQndyyaDIPFsnp6A==
+"@lerna/child-process@3.16.5":
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-3.16.5.tgz#38fa3c18064aa4ac0754ad80114776a7b36a69b2"
+ integrity sha512-vdcI7mzei9ERRV4oO8Y1LHBZ3A5+ampRKg1wq5nutLsUA4mEBN6H7JqjWOMY9xZemv6+kATm2ofjJ3lW5TszQg==
dependencies:
chalk "^2.3.1"
execa "^1.0.0"
strong-log-transformer "^2.0.0"
-"@lerna/clean@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.13.1.tgz#9a7432efceccd720a51da5c76f849fc59c5a14ce"
- integrity sha512-myGIaXv7RUO2qCFZXvx8SJeI+eN6y9SUD5zZ4/LvNogbOiEIlujC5lUAqK65rAHayQ9ltSa/yK6Xv510xhZXZQ==
+"@lerna/clean@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.21.0.tgz#c0b46b5300cc3dae2cda3bec14b803082da3856d"
+ integrity sha512-b/L9l+MDgE/7oGbrav6rG8RTQvRiZLO1zTcG17zgJAAuhlsPxJExMlh2DFwJEVi2les70vMhHfST3Ue1IMMjpg==
dependencies:
- "@lerna/command" "3.13.1"
- "@lerna/filter-options" "3.13.0"
- "@lerna/prompt" "3.13.0"
+ "@lerna/command" "3.21.0"
+ "@lerna/filter-options" "3.20.0"
+ "@lerna/prompt" "3.18.5"
"@lerna/pulse-till-done" "3.13.0"
- "@lerna/rimraf-dir" "3.13.0"
- p-map "^1.2.0"
+ "@lerna/rimraf-dir" "3.16.5"
+ p-map "^2.1.0"
p-map-series "^1.0.0"
p-waterfall "^1.0.0"
-"@lerna/cli@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-3.13.0.tgz#3d7b357fdd7818423e9681a7b7f2abd106c8a266"
- integrity sha512-HgFGlyCZbYaYrjOr3w/EsY18PdvtsTmDfpUQe8HwDjXlPeCCUgliZjXLOVBxSjiOvPeOSwvopwIHKWQmYbwywg==
+"@lerna/cli@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-3.18.5.tgz#c90c461542fcd35b6d5b015a290fb0dbfb41d242"
+ integrity sha512-erkbxkj9jfc89vVs/jBLY/fM0I80oLmJkFUV3Q3wk9J3miYhP14zgVEBsPZY68IZlEjT6T3Xlq2xO1AVaatHsA==
dependencies:
"@lerna/global-options" "3.13.0"
dedent "^0.7.0"
npmlog "^4.1.2"
- yargs "^12.0.1"
+ yargs "^14.2.2"
-"@lerna/collect-updates@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.13.0.tgz#f0828d84ff959ff153d006765659ffc4d68cdefc"
- integrity sha512-uR3u6uTzrS1p46tHQ/mlHog/nRJGBqskTHYYJbgirujxm6FqNh7Do+I1Q/7zSee407G4lzsNxZdm8IL927HemQ==
+"@lerna/collect-uncommitted@3.16.5":
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/@lerna/collect-uncommitted/-/collect-uncommitted-3.16.5.tgz#a494d61aac31cdc7aec4bbe52c96550274132e63"
+ integrity sha512-ZgqnGwpDZiWyzIQVZtQaj9tRizsL4dUOhuOStWgTAw1EMe47cvAY2kL709DzxFhjr6JpJSjXV5rZEAeU3VE0Hg==
dependencies:
- "@lerna/child-process" "3.13.0"
- "@lerna/describe-ref" "3.13.0"
+ "@lerna/child-process" "3.16.5"
+ chalk "^2.3.1"
+ figgy-pudding "^3.5.1"
+ npmlog "^4.1.2"
+
+"@lerna/collect-updates@3.20.0":
+ version "3.20.0"
+ resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.20.0.tgz#62f9d76ba21a25b7d9fbf31c02de88744a564bd1"
+ integrity sha512-qBTVT5g4fupVhBFuY4nI/3FSJtQVcDh7/gEPOpRxoXB/yCSnT38MFHXWl+y4einLciCjt/+0x6/4AG80fjay2Q==
+ dependencies:
+ "@lerna/child-process" "3.16.5"
+ "@lerna/describe-ref" "3.16.5"
minimatch "^3.0.4"
npmlog "^4.1.2"
- slash "^1.0.0"
+ slash "^2.0.0"
-"@lerna/command@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.13.1.tgz#b60dda2c0d9ffbb6030d61ddf7cceedc1e8f7e6e"
- integrity sha512-SYWezxX+iheWvzRoHCrbs8v5zHPaxAx3kWvZhqi70vuGsdOVAWmaG4IvHLn11ztS+Vpd5PM+ztBWSbnykpLFKQ==
+"@lerna/command@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.21.0.tgz#9a2383759dc7b700dacfa8a22b2f3a6e190121f7"
+ integrity sha512-T2bu6R8R3KkH5YoCKdutKv123iUgUbW8efVjdGCDnCMthAQzoentOJfDeodBwn0P2OqCl3ohsiNVtSn9h78fyQ==
dependencies:
- "@lerna/child-process" "3.13.0"
- "@lerna/package-graph" "3.13.0"
- "@lerna/project" "3.13.1"
+ "@lerna/child-process" "3.16.5"
+ "@lerna/package-graph" "3.18.5"
+ "@lerna/project" "3.21.0"
"@lerna/validation-error" "3.13.0"
"@lerna/write-log-file" "3.13.0"
+ clone-deep "^4.0.1"
dedent "^0.7.0"
execa "^1.0.0"
- is-ci "^1.0.10"
- lodash "^4.17.5"
+ is-ci "^2.0.0"
npmlog "^4.1.2"
-"@lerna/conventional-commits@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-3.13.0.tgz#877aa225ca34cca61c31ea02a5a6296af74e1144"
- integrity sha512-BeAgcNXuocmLhPxnmKU2Vy8YkPd/Uo+vu2i/p3JGsUldzrPC8iF3IDxH7fuXpEFN2Nfogu7KHachd4tchtOppA==
+"@lerna/conventional-commits@3.22.0":
+ version "3.22.0"
+ resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-3.22.0.tgz#2798f4881ee2ef457bdae027ab7d0bf0af6f1e09"
+ integrity sha512-z4ZZk1e8Mhz7+IS8NxHr64wyklHctCJyWpJKEZZPJiLFJ8yKto/x38O80R10pIzC0rr8Sy/OsjSH4bl0TbbgqA==
dependencies:
"@lerna/validation-error" "3.13.0"
conventional-changelog-angular "^5.0.3"
conventional-changelog-core "^3.1.6"
- conventional-recommended-bump "^4.0.4"
- fs-extra "^7.0.0"
+ conventional-recommended-bump "^5.0.0"
+ fs-extra "^8.1.0"
get-stream "^4.0.0"
+ lodash.template "^4.5.0"
npm-package-arg "^6.1.0"
npmlog "^4.1.2"
- pify "^3.0.0"
- semver "^5.5.0"
+ pify "^4.0.1"
+ semver "^6.2.0"
-"@lerna/create-symlink@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-3.13.0.tgz#e01133082fe040779712c960683cb3a272b67809"
- integrity sha512-PTvg3jAAJSAtLFoZDsuTMv1wTOC3XYIdtg54k7uxIHsP8Ztpt+vlilY/Cni0THAqEMHvfiToel76Xdta4TU21Q==
+"@lerna/create-symlink@3.16.2":
+ version "3.16.2"
+ resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-3.16.2.tgz#412cb8e59a72f5a7d9463e4e4721ad2070149967"
+ integrity sha512-pzXIJp6av15P325sgiIRpsPXLFmkisLhMBCy4764d+7yjf2bzrJ4gkWVMhsv4AdF0NN3OyZ5jjzzTtLNqfR+Jw==
dependencies:
- cmd-shim "^2.0.2"
- fs-extra "^7.0.0"
+ "@zkochan/cmd-shim" "^3.1.0"
+ fs-extra "^8.1.0"
npmlog "^4.1.2"
-"@lerna/create@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.13.1.tgz#2c1284cfdc59f0d2b88286d78bc797f4ab330f79"
- integrity sha512-pLENMXgTkQuvKxAopjKeoLOv9fVUCnpTUD7aLrY5d95/1xqSZlnsOcQfUYcpMf3GpOvHc8ILmI5OXkPqjAf54g==
+"@lerna/create@3.22.0":
+ version "3.22.0"
+ resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.22.0.tgz#d6bbd037c3dc5b425fe5f6d1b817057c278f7619"
+ integrity sha512-MdiQQzCcB4E9fBF1TyMOaAEz9lUjIHp1Ju9H7f3lXze5JK6Fl5NYkouAvsLgY6YSIhXMY8AHW2zzXeBDY4yWkw==
dependencies:
- "@lerna/child-process" "3.13.0"
- "@lerna/command" "3.13.1"
- "@lerna/npm-conf" "3.13.0"
+ "@evocateur/pacote" "^9.6.3"
+ "@lerna/child-process" "3.16.5"
+ "@lerna/command" "3.21.0"
+ "@lerna/npm-conf" "3.16.0"
"@lerna/validation-error" "3.13.0"
camelcase "^5.0.0"
dedent "^0.7.0"
- fs-extra "^7.0.0"
- globby "^8.0.1"
+ fs-extra "^8.1.0"
+ globby "^9.2.0"
init-package-json "^1.10.3"
npm-package-arg "^6.1.0"
p-reduce "^1.0.0"
- pacote "^9.5.0"
- pify "^3.0.0"
- semver "^5.5.0"
- slash "^1.0.0"
+ pify "^4.0.1"
+ semver "^6.2.0"
+ slash "^2.0.0"
validate-npm-package-license "^3.0.3"
validate-npm-package-name "^3.0.0"
whatwg-url "^7.0.0"
-"@lerna/describe-ref@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.13.0.tgz#fb4c3863fd6bcccad67ce7b183887a5fc1942bb6"
- integrity sha512-UJefF5mLxLae9I2Sbz5RLYGbqbikRuMqdgTam0MS5OhXnyuuKYBUpwBshCURNb1dPBXTQhSwc7+oUhORx8ojCg==
+"@lerna/describe-ref@3.16.5":
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.16.5.tgz#a338c25aaed837d3dc70b8a72c447c5c66346ac0"
+ integrity sha512-c01+4gUF0saOOtDBzbLMFOTJDHTKbDFNErEY6q6i9QaXuzy9LNN62z+Hw4acAAZuJQhrVWncVathcmkkjvSVGw==
dependencies:
- "@lerna/child-process" "3.13.0"
+ "@lerna/child-process" "3.16.5"
npmlog "^4.1.2"
-"@lerna/diff@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.13.1.tgz#5c734321b0f6c46a3c87f55c99afef3b01d46520"
- integrity sha512-cKqmpONO57mdvxtp8e+l5+tjtmF04+7E+O0QEcLcNUAjC6UR2OSM77nwRCXDukou/1h72JtWs0jjcdYLwAmApg==
+"@lerna/diff@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.21.0.tgz#e6df0d8b9916167ff5a49fcb02ac06424280a68d"
+ integrity sha512-5viTR33QV3S7O+bjruo1SaR40m7F2aUHJaDAC7fL9Ca6xji+aw1KFkpCtVlISS0G8vikUREGMJh+c/VMSc8Usw==
dependencies:
- "@lerna/child-process" "3.13.0"
- "@lerna/command" "3.13.1"
+ "@lerna/child-process" "3.16.5"
+ "@lerna/command" "3.21.0"
"@lerna/validation-error" "3.13.0"
npmlog "^4.1.2"
-"@lerna/exec@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.13.1.tgz#4439e90fb0877ec38a6ef933c86580d43eeaf81b"
- integrity sha512-I34wEP9lrAqqM7tTXLDxv/6454WFzrnXDWpNDbiKQiZs6SIrOOjmm6I4FiQsx+rU3o9d+HkC6tcUJRN5mlJUgA==
+"@lerna/exec@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.21.0.tgz#17f07533893cb918a17b41bcc566dc437016db26"
+ integrity sha512-iLvDBrIE6rpdd4GIKTY9mkXyhwsJ2RvQdB9ZU+/NhR3okXfqKc6py/24tV111jqpXTtZUW6HNydT4dMao2hi1Q==
dependencies:
- "@lerna/batch-packages" "3.13.0"
- "@lerna/child-process" "3.13.0"
- "@lerna/command" "3.13.1"
- "@lerna/filter-options" "3.13.0"
- "@lerna/run-parallel-batches" "3.13.0"
+ "@lerna/child-process" "3.16.5"
+ "@lerna/command" "3.21.0"
+ "@lerna/filter-options" "3.20.0"
+ "@lerna/profiler" "3.20.0"
+ "@lerna/run-topologically" "3.18.5"
"@lerna/validation-error" "3.13.0"
+ p-map "^2.1.0"
-"@lerna/filter-options@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.13.0.tgz#976e3d8b9fcd47001ab981d276565c1e9f767868"
- integrity sha512-SRp7DCo9zrf+7NkQxZMkeyO1GRN6GICoB9UcBAbXhLbWisT37Cx5/6+jh49gYB63d/0/WYHSEPMlheUrpv1Srw==
+"@lerna/filter-options@3.20.0":
+ version "3.20.0"
+ resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.20.0.tgz#0f0f5d5a4783856eece4204708cc902cbc8af59b"
+ integrity sha512-bmcHtvxn7SIl/R9gpiNMVG7yjx7WyT0HSGw34YVZ9B+3xF/83N3r5Rgtjh4hheLZ+Q91Or0Jyu5O3Nr+AwZe2g==
dependencies:
- "@lerna/collect-updates" "3.13.0"
- "@lerna/filter-packages" "3.13.0"
+ "@lerna/collect-updates" "3.20.0"
+ "@lerna/filter-packages" "3.18.0"
dedent "^0.7.0"
+ figgy-pudding "^3.5.1"
+ npmlog "^4.1.2"
-"@lerna/filter-packages@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-3.13.0.tgz#f5371249e7e1a15928e5e88c544a242e0162c21c"
- integrity sha512-RWiZWyGy3Mp7GRVBn//CacSnE3Kw82PxE4+H6bQ3pDUw/9atXn7NRX+gkBVQIYeKamh7HyumJtyOKq3Pp9BADQ==
+"@lerna/filter-packages@3.18.0":
+ version "3.18.0"
+ resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-3.18.0.tgz#6a7a376d285208db03a82958cfb8172e179b4e70"
+ integrity sha512-6/0pMM04bCHNATIOkouuYmPg6KH3VkPCIgTfQmdkPJTullERyEQfNUKikrefjxo1vHOoCACDpy65JYyKiAbdwQ==
dependencies:
"@lerna/validation-error" "3.13.0"
- multimatch "^2.1.0"
+ multimatch "^3.0.0"
npmlog "^4.1.2"
"@lerna/get-npm-exec-opts@3.13.0":
@@ -970,157 +1055,186 @@
dependencies:
npmlog "^4.1.2"
-"@lerna/get-packed@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-3.13.0.tgz#335e40d77f3c1855aa248587d3e0b2d8f4b06e16"
- integrity sha512-EgSim24sjIjqQDC57bgXD9l22/HCS93uQBbGpkzEOzxAVzEgpZVm7Fm1t8BVlRcT2P2zwGnRadIvxTbpQuDPTg==
+"@lerna/get-packed@3.16.0":
+ version "3.16.0"
+ resolved "https://registry.yarnpkg.com/@lerna/get-packed/-/get-packed-3.16.0.tgz#1b316b706dcee86c7baa55e50b087959447852ff"
+ integrity sha512-AjsFiaJzo1GCPnJUJZiTW6J1EihrPkc2y3nMu6m3uWFxoleklsSCyImumzVZJssxMi3CPpztj8LmADLedl9kXw==
dependencies:
- fs-extra "^7.0.0"
+ fs-extra "^8.1.0"
ssri "^6.0.1"
tar "^4.4.8"
-"@lerna/github-client@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-3.13.1.tgz#cb9bf9f01685a0cee0fac63f287f6c3673e45aa3"
- integrity sha512-iPLUp8FFoAKGURksYEYZzfuo9TRA+NepVlseRXFaWlmy36dCQN20AciINpoXiXGoHcEUHXUKHQvY3ARFdMlf3w==
+"@lerna/github-client@3.22.0":
+ version "3.22.0"
+ resolved "https://registry.yarnpkg.com/@lerna/github-client/-/github-client-3.22.0.tgz#5d816aa4f76747ed736ae64ff962b8f15c354d95"
+ integrity sha512-O/GwPW+Gzr3Eb5bk+nTzTJ3uv+jh5jGho9BOqKlajXaOkMYGBELEAqV5+uARNGWZFvYAiF4PgqHb6aCUu7XdXg==
dependencies:
- "@lerna/child-process" "3.13.0"
- "@octokit/plugin-enterprise-rest" "^2.1.1"
- "@octokit/rest" "^16.16.0"
+ "@lerna/child-process" "3.16.5"
+ "@octokit/plugin-enterprise-rest" "^6.0.1"
+ "@octokit/rest" "^16.28.4"
git-url-parse "^11.1.2"
npmlog "^4.1.2"
+"@lerna/gitlab-client@3.15.0":
+ version "3.15.0"
+ resolved "https://registry.yarnpkg.com/@lerna/gitlab-client/-/gitlab-client-3.15.0.tgz#91f4ec8c697b5ac57f7f25bd50fe659d24aa96a6"
+ integrity sha512-OsBvRSejHXUBMgwWQqNoioB8sgzL/Pf1pOUhHKtkiMl6aAWjklaaq5HPMvTIsZPfS6DJ9L5OK2GGZuooP/5c8Q==
+ dependencies:
+ node-fetch "^2.5.0"
+ npmlog "^4.1.2"
+ whatwg-url "^7.0.0"
+
"@lerna/global-options@3.13.0":
version "3.13.0"
resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-3.13.0.tgz#217662290db06ad9cf2c49d8e3100ee28eaebae1"
integrity sha512-SlZvh1gVRRzYLVluz9fryY1nJpZ0FHDGB66U9tFfvnnxmueckRQxLopn3tXj3NU1kc3QANT2I5BsQkOqZ4TEFQ==
-"@lerna/has-npm-version@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-3.13.0.tgz#6e1f7e9336cce3e029066f0175f06dd9d51ad09f"
- integrity sha512-Oqu7DGLnrMENPm+bPFGOHnqxK8lCnuYr6bk3g/CoNn8/U0qgFvHcq6Iv8/Z04TsvleX+3/RgauSD2kMfRmbypg==
+"@lerna/has-npm-version@3.16.5":
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-3.16.5.tgz#ab83956f211d8923ea6afe9b979b38cc73b15326"
+ integrity sha512-WL7LycR9bkftyqbYop5rEGJ9sRFIV55tSGmbN1HLrF9idwOCD7CLrT64t235t3t4O5gehDnwKI5h2U3oxTrF8Q==
dependencies:
- "@lerna/child-process" "3.13.0"
- semver "^5.5.0"
+ "@lerna/child-process" "3.16.5"
+ semver "^6.2.0"
-"@lerna/import@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.13.1.tgz#69d641341a38b79bd379129da1c717d51dd728c7"
- integrity sha512-A1Vk1siYx1XkRl6w+zkaA0iptV5TIynVlHPR9S7NY0XAfhykjztYVvwtxarlh6+VcNrO9We6if0+FXCrfDEoIg==
+"@lerna/import@3.22.0":
+ version "3.22.0"
+ resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.22.0.tgz#1a5f0394f38e23c4f642a123e5e1517e70d068d2"
+ integrity sha512-uWOlexasM5XR6tXi4YehODtH9Y3OZrFht3mGUFFT3OIl2s+V85xIGFfqFGMTipMPAGb2oF1UBLL48kR43hRsOg==
dependencies:
- "@lerna/child-process" "3.13.0"
- "@lerna/command" "3.13.1"
- "@lerna/prompt" "3.13.0"
+ "@lerna/child-process" "3.16.5"
+ "@lerna/command" "3.21.0"
+ "@lerna/prompt" "3.18.5"
"@lerna/pulse-till-done" "3.13.0"
"@lerna/validation-error" "3.13.0"
dedent "^0.7.0"
- fs-extra "^7.0.0"
+ fs-extra "^8.1.0"
p-map-series "^1.0.0"
-"@lerna/init@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.13.1.tgz#0392c822abb3d63a75be4916c5e761cfa7b34dda"
- integrity sha512-M59WACqim8WkH5FQEGOCEZ89NDxCKBfFTx4ZD5ig3LkGyJ8RdcJq5KEfpW/aESuRE9JrZLzVr0IjKbZSxzwEMA==
- dependencies:
- "@lerna/child-process" "3.13.0"
- "@lerna/command" "3.13.1"
- fs-extra "^7.0.0"
- p-map "^1.2.0"
- write-json-file "^2.3.0"
-
-"@lerna/link@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.13.1.tgz#7d8ed4774bfa198d1780f790a14abb8722a3aad1"
- integrity sha512-N3h3Fj1dcea+1RaAoAdy4g2m3fvU7m89HoUn5X/Zcw5n2kPoK8kTO+NfhNAatfRV8VtMXst8vbNrWQQtfm0FFw==
- dependencies:
- "@lerna/command" "3.13.1"
- "@lerna/package-graph" "3.13.0"
- "@lerna/symlink-dependencies" "3.13.0"
- p-map "^1.2.0"
- slash "^1.0.0"
+"@lerna/info@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/info/-/info-3.21.0.tgz#76696b676fdb0f35d48c83c63c1e32bb5e37814f"
+ integrity sha512-0XDqGYVBgWxUquFaIptW2bYSIu6jOs1BtkvRTWDDhw4zyEdp6q4eaMvqdSap1CG+7wM5jeLCi6z94wS0AuiuwA==
+ dependencies:
+ "@lerna/command" "3.21.0"
+ "@lerna/output" "3.13.0"
+ envinfo "^7.3.1"
+
+"@lerna/init@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.21.0.tgz#1e810934dc8bf4e5386c031041881d3b4096aa5c"
+ integrity sha512-6CM0z+EFUkFfurwdJCR+LQQF6MqHbYDCBPyhu/d086LRf58GtYZYj49J8mKG9ktayp/TOIxL/pKKjgLD8QBPOg==
+ dependencies:
+ "@lerna/child-process" "3.16.5"
+ "@lerna/command" "3.21.0"
+ fs-extra "^8.1.0"
+ p-map "^2.1.0"
+ write-json-file "^3.2.0"
+
+"@lerna/link@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.21.0.tgz#8be68ff0ccee104b174b5bbd606302c2f06e9d9b"
+ integrity sha512-tGu9GxrX7Ivs+Wl3w1+jrLi1nQ36kNI32dcOssij6bg0oZ2M2MDEFI9UF2gmoypTaN9uO5TSsjCFS7aR79HbdQ==
+ dependencies:
+ "@lerna/command" "3.21.0"
+ "@lerna/package-graph" "3.18.5"
+ "@lerna/symlink-dependencies" "3.17.0"
+ p-map "^2.1.0"
+ slash "^2.0.0"
-"@lerna/list@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.13.1.tgz#f9513ed143e52156c10ada4070f903c5847dcd10"
- integrity sha512-635iRbdgd9gNvYLLIbYdQCQLr+HioM5FGJLFS0g3DPGygr6iDR8KS47hzCRGH91LU9NcM1mD1RoT/AChF+QbiA==
+"@lerna/list@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.21.0.tgz#42f76fafa56dea13b691ec8cab13832691d61da2"
+ integrity sha512-KehRjE83B1VaAbRRkRy6jLX1Cin8ltsrQ7FHf2bhwhRHK0S54YuA6LOoBnY/NtA8bHDX/Z+G5sMY78X30NS9tg==
dependencies:
- "@lerna/command" "3.13.1"
- "@lerna/filter-options" "3.13.0"
- "@lerna/listable" "3.13.0"
+ "@lerna/command" "3.21.0"
+ "@lerna/filter-options" "3.20.0"
+ "@lerna/listable" "3.18.5"
"@lerna/output" "3.13.0"
-"@lerna/listable@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-3.13.0.tgz#babc18442c590b549cf0966d20d75fea066598d4"
- integrity sha512-liYJ/WBUYP4N4MnSVZuLUgfa/jy3BZ02/1Om7xUY09xGVSuNVNEeB8uZUMSC+nHqFHIsMPZ8QK9HnmZb1E/eTA==
+"@lerna/listable@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-3.18.5.tgz#e82798405b5ed8fc51843c8ef1e7a0e497388a1a"
+ integrity sha512-Sdr3pVyaEv5A7ZkGGYR7zN+tTl2iDcinryBPvtuv20VJrXBE8wYcOks1edBTcOWsPjCE/rMP4bo1pseyk3UTsg==
dependencies:
- "@lerna/batch-packages" "3.13.0"
+ "@lerna/query-graph" "3.18.5"
chalk "^2.3.1"
columnify "^1.5.4"
-"@lerna/log-packed@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-3.13.0.tgz#497b5f692a8d0e3f669125da97b0dadfd9e480f3"
- integrity sha512-Rmjrcz+6aM6AEcEVWmurbo8+AnHOvYtDpoeMMJh9IZ9SmZr2ClXzmD7wSvjTQc8BwOaiWjjC/ukcT0UYA2m7wg==
+"@lerna/log-packed@3.16.0":
+ version "3.16.0"
+ resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-3.16.0.tgz#f83991041ee77b2495634e14470b42259fd2bc16"
+ integrity sha512-Fp+McSNBV/P2mnLUYTaSlG8GSmpXM7krKWcllqElGxvAqv6chk2K3c2k80MeVB4WvJ9tRjUUf+i7HUTiQ9/ckQ==
dependencies:
- byte-size "^4.0.3"
+ byte-size "^5.0.1"
columnify "^1.5.4"
has-unicode "^2.0.1"
npmlog "^4.1.2"
-"@lerna/npm-conf@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-3.13.0.tgz#6b434ed75ff757e8c14381b9bbfe5d5ddec134a7"
- integrity sha512-Jg2kANsGnhg+fbPEzE0X9nX5oviEAvWj0nYyOkcE+cgWuT7W0zpnPXC4hA4C5IPQGhwhhh0IxhWNNHtjTuw53g==
+"@lerna/npm-conf@3.16.0":
+ version "3.16.0"
+ resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-3.16.0.tgz#1c10a89ae2f6c2ee96962557738685300d376827"
+ integrity sha512-HbO3DUrTkCAn2iQ9+FF/eisDpWY5POQAOF1m7q//CZjdC2HSW3UYbKEGsSisFxSfaF9Z4jtrV+F/wX6qWs3CuA==
dependencies:
config-chain "^1.1.11"
- pify "^3.0.0"
+ pify "^4.0.1"
-"@lerna/npm-dist-tag@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-3.13.0.tgz#49ecbe0e82cbe4ad4a8ea6de112982bf6c4e6cd4"
- integrity sha512-mcuhw34JhSRFrbPn0vedbvgBTvveG52bR2lVE3M3tfE8gmR/cKS/EJFO4AUhfRKGCTFn9rjaSEzlFGYV87pemQ==
+"@lerna/npm-dist-tag@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-3.18.5.tgz#9ef9abb7c104077b31f6fab22cc73b314d54ac55"
+ integrity sha512-xw0HDoIG6HreVsJND9/dGls1c+lf6vhu7yJoo56Sz5bvncTloYGLUppIfDHQr4ZvmPCK8rsh0euCVh2giPxzKQ==
dependencies:
+ "@evocateur/npm-registry-fetch" "^4.0.0"
+ "@lerna/otplease" "3.18.5"
figgy-pudding "^3.5.1"
npm-package-arg "^6.1.0"
- npm-registry-fetch "^3.9.0"
npmlog "^4.1.2"
-"@lerna/npm-install@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.13.0.tgz#88f4cc39f4f737c8a8721256b915ea1bcc6a7227"
- integrity sha512-qNyfts//isYQxore6fsPorNYJmPVKZ6tOThSH97tP0aV91zGMtrYRqlAoUnDwDdAjHPYEM16hNujg2wRmsqqIw==
+"@lerna/npm-install@3.16.5":
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.16.5.tgz#d6bfdc16f81285da66515ae47924d6e278d637d3"
+ integrity sha512-hfiKk8Eku6rB9uApqsalHHTHY+mOrrHeWEs+gtg7+meQZMTS3kzv4oVp5cBZigndQr3knTLjwthT/FX4KvseFg==
dependencies:
- "@lerna/child-process" "3.13.0"
+ "@lerna/child-process" "3.16.5"
"@lerna/get-npm-exec-opts" "3.13.0"
- fs-extra "^7.0.0"
+ fs-extra "^8.1.0"
npm-package-arg "^6.1.0"
npmlog "^4.1.2"
signal-exit "^3.0.2"
write-pkg "^3.1.0"
-"@lerna/npm-publish@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.13.0.tgz#5c74808376e778865ffdc5885fe83935e15e60c3"
- integrity sha512-y4WO0XTaf9gNRkI7as6P2ItVDOxmYHwYto357fjybcnfXgMqEA94c3GJ++jU41j0A9vnmYC6/XxpTd9sVmH9tA==
+"@lerna/npm-publish@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.18.5.tgz#240e4039959fd9816b49c5b07421e11b5cb000af"
+ integrity sha512-3etLT9+2L8JAx5F8uf7qp6iAtOLSMj+ZYWY6oUgozPi/uLqU0/gsMsEXh3F0+YVW33q0M61RpduBoAlOOZnaTg==
dependencies:
- "@lerna/run-lifecycle" "3.13.0"
+ "@evocateur/libnpmpublish" "^1.2.2"
+ "@lerna/otplease" "3.18.5"
+ "@lerna/run-lifecycle" "3.16.2"
figgy-pudding "^3.5.1"
- fs-extra "^7.0.0"
- libnpmpublish "^1.1.1"
+ fs-extra "^8.1.0"
+ npm-package-arg "^6.1.0"
npmlog "^4.1.2"
- pify "^3.0.0"
+ pify "^4.0.1"
read-package-json "^2.0.13"
-"@lerna/npm-run-script@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-3.13.0.tgz#e5997f045402b9948bdc066033ebb36bf94fc9e4"
- integrity sha512-hiL3/VeVp+NFatBjkGN8mUdX24EfZx9rQlSie0CMgtjc7iZrtd0jCguLomSCRHYjJuvqgbp+LLYo7nHVykfkaQ==
+"@lerna/npm-run-script@3.16.5":
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-3.16.5.tgz#9c2ec82453a26c0b46edc0bb7c15816c821f5c15"
+ integrity sha512-1asRi+LjmVn3pMjEdpqKJZFT/3ZNpb+VVeJMwrJaV/3DivdNg7XlPK9LTrORuKU4PSvhdEZvJmSlxCKyDpiXsQ==
dependencies:
- "@lerna/child-process" "3.13.0"
+ "@lerna/child-process" "3.16.5"
"@lerna/get-npm-exec-opts" "3.13.0"
npmlog "^4.1.2"
+"@lerna/otplease@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/otplease/-/otplease-3.18.5.tgz#b77b8e760b40abad9f7658d988f3ea77d4fd0231"
+ integrity sha512-S+SldXAbcXTEDhzdxYLU0ZBKuYyURP/ND2/dK6IpKgLxQYh/z4ScljPDMyKymmEvgiEJmBsPZAAPfmNPEzxjog==
+ dependencies:
+ "@lerna/prompt" "3.18.5"
+ figgy-pudding "^3.5.1"
+
"@lerna/output@3.13.0":
version "3.13.0"
resolved "https://registry.yarnpkg.com/@lerna/output/-/output-3.13.0.tgz#3ded7cc908b27a9872228a630d950aedae7a4989"
@@ -1128,99 +1242,118 @@
dependencies:
npmlog "^4.1.2"
-"@lerna/pack-directory@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-3.13.1.tgz#5ad4d0945f86a648f565e24d53c1e01bb3a912d1"
- integrity sha512-kXnyqrkQbCIZOf1054N88+8h0ItC7tUN5v9ca/aWpx298gsURpxUx/1TIKqijL5TOnHMyIkj0YJmnH/PyBVLKA==
+"@lerna/pack-directory@3.16.4":
+ version "3.16.4"
+ resolved "https://registry.yarnpkg.com/@lerna/pack-directory/-/pack-directory-3.16.4.tgz#3eae5f91bdf5acfe0384510ed53faddc4c074693"
+ integrity sha512-uxSF0HZeGyKaaVHz5FroDY9A5NDDiCibrbYR6+khmrhZtY0Bgn6hWq8Gswl9iIlymA+VzCbshWIMX4o2O8C8ng==
dependencies:
- "@lerna/get-packed" "3.13.0"
- "@lerna/package" "3.13.0"
- "@lerna/run-lifecycle" "3.13.0"
+ "@lerna/get-packed" "3.16.0"
+ "@lerna/package" "3.16.0"
+ "@lerna/run-lifecycle" "3.16.2"
figgy-pudding "^3.5.1"
- npm-packlist "^1.4.1"
+ npm-packlist "^1.4.4"
npmlog "^4.1.2"
- tar "^4.4.8"
+ tar "^4.4.10"
temp-write "^3.4.0"
-"@lerna/package-graph@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-3.13.0.tgz#607062f8d2ce22b15f8d4a0623f384736e67f760"
- integrity sha512-3mRF1zuqFE1HEFmMMAIggXy+f+9cvHhW/jzaPEVyrPNLKsyfJQtpTNzeI04nfRvbAh+Gd2aNksvaW/w3xGJnnw==
+"@lerna/package-graph@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-3.18.5.tgz#c740e2ea3578d059e551633e950690831b941f6b"
+ integrity sha512-8QDrR9T+dBegjeLr+n9WZTVxUYUhIUjUgZ0gvNxUBN8S1WB9r6H5Yk56/MVaB64tA3oGAN9IIxX6w0WvTfFudA==
dependencies:
+ "@lerna/prerelease-id-from-version" "3.16.0"
"@lerna/validation-error" "3.13.0"
npm-package-arg "^6.1.0"
- semver "^5.5.0"
+ npmlog "^4.1.2"
+ semver "^6.2.0"
-"@lerna/package@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.13.0.tgz#4baeebc49a57fc9b31062cc59f5ee38384429fc8"
- integrity sha512-kSKO0RJQy093BufCQnkhf1jB4kZnBvL7kK5Ewolhk5gwejN+Jofjd8DGRVUDUJfQ0CkW1o6GbUeZvs8w8VIZDg==
+"@lerna/package@3.16.0":
+ version "3.16.0"
+ resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.16.0.tgz#7e0a46e4697ed8b8a9c14d59c7f890e0d38ba13c"
+ integrity sha512-2lHBWpaxcBoiNVbtyLtPUuTYEaB/Z+eEqRS9duxpZs6D+mTTZMNy6/5vpEVSCBmzvdYpyqhqaYjjSLvjjr5Riw==
dependencies:
- load-json-file "^4.0.0"
+ load-json-file "^5.3.0"
npm-package-arg "^6.1.0"
write-pkg "^3.1.0"
-"@lerna/project@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.13.1.tgz#bce890f60187bd950bcf36c04b5260642e295e79"
- integrity sha512-/GoCrpsCCTyb9sizk1+pMBrIYchtb+F1uCOn3cjn9yenyG/MfYEnlfrbV5k/UDud0Ei75YBLbmwCbigHkAKazQ==
+"@lerna/prerelease-id-from-version@3.16.0":
+ version "3.16.0"
+ resolved "https://registry.yarnpkg.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-3.16.0.tgz#b24bfa789f5e1baab914d7b08baae9b7bd7d83a1"
+ integrity sha512-qZyeUyrE59uOK8rKdGn7jQz+9uOpAaF/3hbslJVFL1NqF9ELDTqjCPXivuejMX/lN4OgD6BugTO4cR7UTq/sZA==
+ dependencies:
+ semver "^6.2.0"
+
+"@lerna/profiler@3.20.0":
+ version "3.20.0"
+ resolved "https://registry.yarnpkg.com/@lerna/profiler/-/profiler-3.20.0.tgz#0f6dc236f4ea8f9ea5f358c6703305a4f32ad051"
+ integrity sha512-bh8hKxAlm6yu8WEOvbLENm42i2v9SsR4WbrCWSbsmOElx3foRnMlYk7NkGECa+U5c3K4C6GeBbwgqs54PP7Ljg==
+ dependencies:
+ figgy-pudding "^3.5.1"
+ fs-extra "^8.1.0"
+ npmlog "^4.1.2"
+ upath "^1.2.0"
+
+"@lerna/project@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.21.0.tgz#5d784d2d10c561a00f20320bcdb040997c10502d"
+ integrity sha512-xT1mrpET2BF11CY32uypV2GPtPVm6Hgtha7D81GQP9iAitk9EccrdNjYGt5UBYASl4CIDXBRxwmTTVGfrCx82A==
dependencies:
- "@lerna/package" "3.13.0"
+ "@lerna/package" "3.16.0"
"@lerna/validation-error" "3.13.0"
cosmiconfig "^5.1.0"
dedent "^0.7.0"
dot-prop "^4.2.0"
- glob-parent "^3.1.0"
- globby "^8.0.1"
- load-json-file "^4.0.0"
+ glob-parent "^5.0.0"
+ globby "^9.2.0"
+ load-json-file "^5.3.0"
npmlog "^4.1.2"
- p-map "^1.2.0"
+ p-map "^2.1.0"
resolve-from "^4.0.0"
- write-json-file "^2.3.0"
+ write-json-file "^3.2.0"
-"@lerna/prompt@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-3.13.0.tgz#53571462bb3f5399cc1ca6d335a411fe093426a5"
- integrity sha512-P+lWSFokdyvYpkwC3it9cE0IF2U5yy2mOUbGvvE4iDb9K7TyXGE+7lwtx2thtPvBAfIb7O13POMkv7df03HJeA==
+"@lerna/prompt@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-3.18.5.tgz#628cd545f225887d060491ab95df899cfc5218a1"
+ integrity sha512-rkKj4nm1twSbBEb69+Em/2jAERK8htUuV8/xSjN0NPC+6UjzAwY52/x9n5cfmpa9lyKf/uItp7chCI7eDmNTKQ==
dependencies:
inquirer "^6.2.0"
npmlog "^4.1.2"
-"@lerna/publish@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.13.1.tgz#217e401dcb5824cdd6d36555a36303fb7520c514"
- integrity sha512-KhCJ9UDx76HWCF03i5TD7z5lX+2yklHh5SyO8eDaLptgdLDQ0Z78lfGj3JhewHU2l46FztmqxL/ss0IkWHDL+g==
- dependencies:
- "@lerna/batch-packages" "3.13.0"
- "@lerna/check-working-tree" "3.13.0"
- "@lerna/child-process" "3.13.0"
- "@lerna/collect-updates" "3.13.0"
- "@lerna/command" "3.13.1"
- "@lerna/describe-ref" "3.13.0"
- "@lerna/log-packed" "3.13.0"
- "@lerna/npm-conf" "3.13.0"
- "@lerna/npm-dist-tag" "3.13.0"
- "@lerna/npm-publish" "3.13.0"
+"@lerna/publish@3.22.1":
+ version "3.22.1"
+ resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.22.1.tgz#b4f7ce3fba1e9afb28be4a1f3d88222269ba9519"
+ integrity sha512-PG9CM9HUYDreb1FbJwFg90TCBQooGjj+n/pb3gw/eH5mEDq0p8wKdLFe0qkiqUkm/Ub5C8DbVFertIo0Vd0zcw==
+ dependencies:
+ "@evocateur/libnpmaccess" "^3.1.2"
+ "@evocateur/npm-registry-fetch" "^4.0.0"
+ "@evocateur/pacote" "^9.6.3"
+ "@lerna/check-working-tree" "3.16.5"
+ "@lerna/child-process" "3.16.5"
+ "@lerna/collect-updates" "3.20.0"
+ "@lerna/command" "3.21.0"
+ "@lerna/describe-ref" "3.16.5"
+ "@lerna/log-packed" "3.16.0"
+ "@lerna/npm-conf" "3.16.0"
+ "@lerna/npm-dist-tag" "3.18.5"
+ "@lerna/npm-publish" "3.18.5"
+ "@lerna/otplease" "3.18.5"
"@lerna/output" "3.13.0"
- "@lerna/pack-directory" "3.13.1"
- "@lerna/prompt" "3.13.0"
+ "@lerna/pack-directory" "3.16.4"
+ "@lerna/prerelease-id-from-version" "3.16.0"
+ "@lerna/prompt" "3.18.5"
"@lerna/pulse-till-done" "3.13.0"
- "@lerna/run-lifecycle" "3.13.0"
- "@lerna/run-parallel-batches" "3.13.0"
+ "@lerna/run-lifecycle" "3.16.2"
+ "@lerna/run-topologically" "3.18.5"
"@lerna/validation-error" "3.13.0"
- "@lerna/version" "3.13.1"
+ "@lerna/version" "3.22.1"
figgy-pudding "^3.5.1"
- fs-extra "^7.0.0"
- libnpmaccess "^3.0.1"
+ fs-extra "^8.1.0"
npm-package-arg "^6.1.0"
- npm-registry-fetch "^3.9.0"
npmlog "^4.1.2"
p-finally "^1.0.0"
- p-map "^1.2.0"
+ p-map "^2.1.0"
p-pipe "^1.2.0"
- p-reduce "^1.0.0"
- pacote "^9.5.0"
- semver "^5.5.0"
+ semver "^6.2.0"
"@lerna/pulse-till-done@3.13.0":
version "3.13.0"
@@ -1229,79 +1362,88 @@
dependencies:
npmlog "^4.1.2"
-"@lerna/resolve-symlink@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-3.13.0.tgz#3e6809ef53b63fe914814bfa071cd68012e22fbb"
- integrity sha512-Lc0USSFxwDxUs5JvIisS8JegjA6SHSAWJCMvi2osZx6wVRkEDlWG2B1JAfXUzCMNfHoZX0/XX9iYZ+4JIpjAtg==
+"@lerna/query-graph@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/query-graph/-/query-graph-3.18.5.tgz#df4830bb5155273003bf35e8dda1c32d0927bd86"
+ integrity sha512-50Lf4uuMpMWvJ306be3oQDHrWV42nai9gbIVByPBYJuVW8dT8O8pA3EzitNYBUdLL9/qEVbrR0ry1HD7EXwtRA==
dependencies:
- fs-extra "^7.0.0"
+ "@lerna/package-graph" "3.18.5"
+ figgy-pudding "^3.5.1"
+
+"@lerna/resolve-symlink@3.16.0":
+ version "3.16.0"
+ resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-3.16.0.tgz#37fc7095fabdbcf317c26eb74e0d0bde8efd2386"
+ integrity sha512-Ibj5e7njVHNJ/NOqT4HlEgPFPtPLWsO7iu59AM5bJDcAJcR96mLZ7KGVIsS2tvaO7akMEJvt2P+ErwCdloG3jQ==
+ dependencies:
+ fs-extra "^8.1.0"
npmlog "^4.1.2"
read-cmd-shim "^1.0.1"
-"@lerna/rimraf-dir@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-3.13.0.tgz#bb1006104b4aabcb6985624273254648f872b278"
- integrity sha512-kte+pMemulre8cmPqljxIYjCmdLByz8DgHBHXB49kz2EiPf8JJ+hJFt0PzEubEyJZ2YE2EVAx5Tv5+NfGNUQyQ==
+"@lerna/rimraf-dir@3.16.5":
+ version "3.16.5"
+ resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-3.16.5.tgz#04316ab5ffd2909657aaf388ea502cb8c2f20a09"
+ integrity sha512-bQlKmO0pXUsXoF8lOLknhyQjOZsCc0bosQDoX4lujBXSWxHVTg1VxURtWf2lUjz/ACsJVDfvHZbDm8kyBk5okA==
dependencies:
- "@lerna/child-process" "3.13.0"
+ "@lerna/child-process" "3.16.5"
npmlog "^4.1.2"
path-exists "^3.0.0"
rimraf "^2.6.2"
-"@lerna/run-lifecycle@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-3.13.0.tgz#d8835ee83425edee40f687a55f81b502354d3261"
- integrity sha512-oyiaL1biZdjpmjh6X/5C4w07wNFyiwXSSHH5GQB4Ay4BPwgq9oNhCcxRoi0UVZlZ1YwzSW8sTwLgj8emkIo3Yg==
+"@lerna/run-lifecycle@3.16.2":
+ version "3.16.2"
+ resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-3.16.2.tgz#67b288f8ea964db9ea4fb1fbc7715d5bbb0bce00"
+ integrity sha512-RqFoznE8rDpyyF0rOJy3+KjZCeTkO8y/OB9orPauR7G2xQ7PTdCpgo7EO6ZNdz3Al+k1BydClZz/j78gNCmL2A==
dependencies:
- "@lerna/npm-conf" "3.13.0"
+ "@lerna/npm-conf" "3.16.0"
figgy-pudding "^3.5.1"
- npm-lifecycle "^2.1.0"
+ npm-lifecycle "^3.1.2"
npmlog "^4.1.2"
-"@lerna/run-parallel-batches@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/run-parallel-batches/-/run-parallel-batches-3.13.0.tgz#0276bb4e7cd0995297db82d134ca2bd08d63e311"
- integrity sha512-bICFBR+cYVF1FFW+Tlm0EhWDioTUTM6dOiVziDEGE1UZha1dFkMYqzqdSf4bQzfLS31UW/KBd/2z8jy2OIjEjg==
+"@lerna/run-topologically@3.18.5":
+ version "3.18.5"
+ resolved "https://registry.yarnpkg.com/@lerna/run-topologically/-/run-topologically-3.18.5.tgz#3cd639da20e967d7672cb88db0f756b92f2fdfc3"
+ integrity sha512-6N1I+6wf4hLOnPW+XDZqwufyIQ6gqoPfHZFkfWlvTQ+Ue7CuF8qIVQ1Eddw5HKQMkxqN10thKOFfq/9NQZ4NUg==
dependencies:
- p-map "^1.2.0"
- p-map-series "^1.0.0"
+ "@lerna/query-graph" "3.18.5"
+ figgy-pudding "^3.5.1"
+ p-queue "^4.0.0"
-"@lerna/run@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.13.1.tgz#87e174c1d271894ddd29adc315c068fb7b1b0117"
- integrity sha512-nv1oj7bsqppWm1M4ifN+/IIbVu9F4RixrbQD2okqDGYne4RQPAXyb5cEZuAzY/wyGTWWiVaZ1zpj5ogPWvH0bw==
+"@lerna/run@3.21.0":
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.21.0.tgz#2a35ec84979e4d6e42474fe148d32e5de1cac891"
+ integrity sha512-fJF68rT3veh+hkToFsBmUJ9MHc9yGXA7LSDvhziAojzOb0AI/jBDp6cEcDQyJ7dbnplba2Lj02IH61QUf9oW0Q==
dependencies:
- "@lerna/batch-packages" "3.13.0"
- "@lerna/command" "3.13.1"
- "@lerna/filter-options" "3.13.0"
- "@lerna/npm-run-script" "3.13.0"
+ "@lerna/command" "3.21.0"
+ "@lerna/filter-options" "3.20.0"
+ "@lerna/npm-run-script" "3.16.5"
"@lerna/output" "3.13.0"
- "@lerna/run-parallel-batches" "3.13.0"
+ "@lerna/profiler" "3.20.0"
+ "@lerna/run-topologically" "3.18.5"
"@lerna/timer" "3.13.0"
"@lerna/validation-error" "3.13.0"
- p-map "^1.2.0"
+ p-map "^2.1.0"
-"@lerna/symlink-binary@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-3.13.0.tgz#36a9415d468afcb8105750296902f6f000a9680d"
- integrity sha512-obc4Y6jxywkdaCe+DB0uTxYqP0IQ8mFWvN+k/YMbwH4G2h7M7lCBWgPy8e7xw/50+1II9tT2sxgx+jMus1sTJg==
+"@lerna/symlink-binary@3.17.0":
+ version "3.17.0"
+ resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-3.17.0.tgz#8f8031b309863814883d3f009877f82e38aef45a"
+ integrity sha512-RLpy9UY6+3nT5J+5jkM5MZyMmjNHxZIZvXLV+Q3MXrf7Eaa1hNqyynyj4RO95fxbS+EZc4XVSk25DGFQbcRNSQ==
dependencies:
- "@lerna/create-symlink" "3.13.0"
- "@lerna/package" "3.13.0"
- fs-extra "^7.0.0"
- p-map "^1.2.0"
+ "@lerna/create-symlink" "3.16.2"
+ "@lerna/package" "3.16.0"
+ fs-extra "^8.1.0"
+ p-map "^2.1.0"
-"@lerna/symlink-dependencies@3.13.0":
- version "3.13.0"
- resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-3.13.0.tgz#76c23ecabda7824db98a0561364f122b457509cf"
- integrity sha512-7CyN5WYEPkbPLbqHBIQg/YiimBzb5cIGQB0E9IkLs3+racq2vmUNQZn38LOaazQacAA83seB+zWSxlI6H+eXSg==
+"@lerna/symlink-dependencies@3.17.0":
+ version "3.17.0"
+ resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-3.17.0.tgz#48d6360e985865a0e56cd8b51b308a526308784a"
+ integrity sha512-KmjU5YT1bpt6coOmdFueTJ7DFJL4H1w5eF8yAQ2zsGNTtZ+i5SGFBWpb9AQaw168dydc3s4eu0W0Sirda+F59Q==
dependencies:
- "@lerna/create-symlink" "3.13.0"
- "@lerna/resolve-symlink" "3.13.0"
- "@lerna/symlink-binary" "3.13.0"
- fs-extra "^7.0.0"
+ "@lerna/create-symlink" "3.16.2"
+ "@lerna/resolve-symlink" "3.16.0"
+ "@lerna/symlink-binary" "3.17.0"
+ fs-extra "^8.1.0"
p-finally "^1.0.0"
- p-map "^1.2.0"
+ p-map "^2.1.0"
p-map-series "^1.0.0"
"@lerna/timer@3.13.0":
@@ -1316,33 +1458,37 @@
dependencies:
npmlog "^4.1.2"
-"@lerna/version@3.13.1":
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.13.1.tgz#5e919d13abb13a663dcc7922bb40931f12fb137b"
- integrity sha512-WpfKc5jZBBOJ6bFS4atPJEbHSiywQ/Gcd+vrwaEGyQHWHQZnPTvhqLuq3q9fIb9sbuhH5pSY6eehhuBrKqTnjg==
- dependencies:
- "@lerna/batch-packages" "3.13.0"
- "@lerna/check-working-tree" "3.13.0"
- "@lerna/child-process" "3.13.0"
- "@lerna/collect-updates" "3.13.0"
- "@lerna/command" "3.13.1"
- "@lerna/conventional-commits" "3.13.0"
- "@lerna/github-client" "3.13.1"
+"@lerna/version@3.22.1":
+ version "3.22.1"
+ resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.22.1.tgz#9805a9247a47ee62d6b81bd9fa5fb728b24b59e2"
+ integrity sha512-PSGt/K1hVqreAFoi3zjD0VEDupQ2WZVlVIwesrE5GbrL2BjXowjCsTDPqblahDUPy0hp6h7E2kG855yLTp62+g==
+ dependencies:
+ "@lerna/check-working-tree" "3.16.5"
+ "@lerna/child-process" "3.16.5"
+ "@lerna/collect-updates" "3.20.0"
+ "@lerna/command" "3.21.0"
+ "@lerna/conventional-commits" "3.22.0"
+ "@lerna/github-client" "3.22.0"
+ "@lerna/gitlab-client" "3.15.0"
"@lerna/output" "3.13.0"
- "@lerna/prompt" "3.13.0"
- "@lerna/run-lifecycle" "3.13.0"
+ "@lerna/prerelease-id-from-version" "3.16.0"
+ "@lerna/prompt" "3.18.5"
+ "@lerna/run-lifecycle" "3.16.2"
+ "@lerna/run-topologically" "3.18.5"
"@lerna/validation-error" "3.13.0"
chalk "^2.3.1"
dedent "^0.7.0"
+ load-json-file "^5.3.0"
minimatch "^3.0.4"
npmlog "^4.1.2"
- p-map "^1.2.0"
+ p-map "^2.1.0"
p-pipe "^1.2.0"
p-reduce "^1.0.0"
p-waterfall "^1.0.0"
- semver "^5.5.0"
- slash "^1.0.0"
+ semver "^6.2.0"
+ slash "^2.0.0"
temp-write "^3.4.0"
+ write-json-file "^3.2.0"
"@lerna/write-log-file@3.13.0":
version "3.13.0"
@@ -1504,6 +1650,18 @@
dependencies:
"@octokit/types" "^5.0.0"
+"@octokit/core@3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.0.0.tgz#4b7bf2a9e744a49abcbb3aca7b4dfc219513e4f9"
+ integrity sha512-FGUUqZbIwl5UPvuUTWq8ly2B12gJGWjYh1DviBzZLXp5LzHUgyzL+NDGsXeE4vszXoGsD/JfpZS+kjkLiD2T9w==
+ dependencies:
+ "@octokit/auth-token" "^2.4.0"
+ "@octokit/graphql" "^4.3.1"
+ "@octokit/request" "^5.4.0"
+ "@octokit/types" "^5.0.0"
+ before-after-hook "^2.1.0"
+ universal-user-agent "^5.0.0"
+
"@octokit/endpoint@^6.0.1":
version "6.0.9"
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-6.0.9.tgz#c6a772e024202b1bd19ab69f90e0536a2598b13e"
@@ -1513,10 +1671,24 @@
is-plain-object "^5.0.0"
universal-user-agent "^6.0.0"
-"@octokit/plugin-enterprise-rest@^2.1.1":
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-2.2.2.tgz#c0e22067a043e19f96ff9c7832e2a3019f9be75c"
- integrity sha512-CTZr64jZYhGWNTDGlSJ2mvIlFsm9OEO3LqWn9I/gmoHI4jRBp4kpHoFYNemG4oA75zUAcmbuWblb7jjP877YZw==
+"@octokit/graphql@^4.3.1":
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.6.1.tgz#f975486a46c94b7dbe58a0ca751935edc7e32cc9"
+ integrity sha512-2lYlvf4YTDgZCTXTW4+OX+9WTLFtEUc6hGm4qM1nlZjzxj+arizM4aHWzBVBCxY9glh7GIs0WEuiSgbVzv8cmA==
+ dependencies:
+ "@octokit/request" "^5.3.0"
+ "@octokit/types" "^6.0.3"
+ universal-user-agent "^6.0.0"
+
+"@octokit/openapi-types@^5.3.2":
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-5.3.2.tgz#b8ac43c5c3d00aef61a34cf744e315110c78deb4"
+ integrity sha512-NxF1yfYOUO92rCx3dwvA2onF30Vdlg7YUkMVXkeptqpzA3tRLplThhFleV/UKWFgh7rpKu1yYRbvNDUtzSopKA==
+
+"@octokit/plugin-enterprise-rest@^6.0.1":
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437"
+ integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==
"@octokit/plugin-paginate-rest@^1.1.1":
version "1.1.2"
@@ -1570,7 +1742,21 @@
once "^1.4.0"
universal-user-agent "^6.0.0"
-"@octokit/rest@^16.16.0":
+"@octokit/request@^5.3.0", "@octokit/request@^5.4.0":
+ version "5.4.14"
+ resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.14.tgz#ec5f96f78333bb2af390afa5ff66f114b063bc96"
+ integrity sha512-VkmtacOIQp9daSnBmDI92xNIeLuSRDOIuplp/CJomkvzt7M18NXgG044Cx/LFKLgjKt9T2tZR6AtJayba9GTSA==
+ dependencies:
+ "@octokit/endpoint" "^6.0.1"
+ "@octokit/request-error" "^2.0.0"
+ "@octokit/types" "^6.7.1"
+ deprecation "^2.0.0"
+ is-plain-object "^5.0.0"
+ node-fetch "^2.6.1"
+ once "^1.4.0"
+ universal-user-agent "^6.0.0"
+
+"@octokit/rest@^16.28.4":
version "16.43.2"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.43.2.tgz#c53426f1e1d1044dee967023e3279c50993dd91b"
integrity sha512-ngDBevLbBTFfrHZeiS7SAMAZ6ssuVmXuya+F/7RaVvlysgGa1JKJkKWY+jV6TCJYcW0OALfJ7nTIGXcBXzycfQ==
@@ -1606,6 +1792,13 @@
dependencies:
"@types/node" ">= 8"
+"@octokit/types@^6.0.3", "@octokit/types@^6.7.1":
+ version "6.12.2"
+ resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.12.2.tgz#5b44add079a478b8eb27d78cf384cc47e4411362"
+ integrity sha512-kCkiN8scbCmSq+gwdJV0iLgHc0O/GTPY1/cffo9kECu1MvatLPh9E+qFhfRIktKfHEA6ZYvv6S1B4Wnv3bi3pA==
+ dependencies:
+ "@octokit/openapi-types" "^5.3.2"
+
"@types/classnames@2.2.6":
version "2.2.6"
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.6.tgz#dbe8a666156d556ed018e15a4c65f08937c3f628"
@@ -1629,6 +1822,19 @@
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad"
integrity sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==
+"@types/glob-to-regexp@0.4.0":
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/@types/glob-to-regexp/-/glob-to-regexp-0.4.0.tgz#a295047724f4554be8192b4c779c5e44920a2fdc"
+ integrity sha512-unszpTzAknG612PxqtoNUkLM0T3rIAXT8oE9Dyhhbl4eew91jLqcgJZOu5j7GztHg09R8LWCMocRU1ohDFY7Pw==
+
+"@types/glob@^7.1.1":
+ version "7.1.3"
+ resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
+ integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==
+ dependencies:
+ "@types/minimatch" "*"
+ "@types/node" "*"
+
"@types/highlight.js@9.12.3":
version "9.12.3"
resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.3.tgz#b672cfaac25cbbc634a0fd92c515f66faa18dbca"
@@ -1673,7 +1879,7 @@
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.6.0.tgz#e4ac316144a84afda5c2474488d7b9fef3ab9995"
integrity sha512-TxwhgR9VsIfRDJ3WwFokG8Xu+ea0nYGDRHdI783WJ983uffatz0ytIeUEIBOwPvRy241KRSNVyywQltuTqDh0w==
-"@types/minimatch@3.0.3":
+"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
@@ -1703,17 +1909,17 @@
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
-"@types/react-dom@16.9.5":
- version "16.9.5"
- resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.5.tgz#5de610b04a35d07ffd8f44edad93a71032d9aaa7"
- integrity sha512-BX6RQ8s9D+2/gDhxrj8OW+YD4R+8hj7FEM/OJHGNR0KipE1h1mSsf39YeyC81qafkq+N3rU3h3RFbLSwE5VqUg==
+"@types/react-dom@17.0.2":
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.2.tgz#35654cf6c49ae162d5bc90843d5437dc38008d43"
+ integrity sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg==
dependencies:
"@types/react" "*"
-"@types/react-router-dom@4.3.1":
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-4.3.1.tgz#71fe2918f8f60474a891520def40a63997dafe04"
- integrity sha512-GbztJAScOmQ/7RsQfO4cd55RuH1W4g6V1gDW3j4riLlt+8yxYLqqsiMzmyuXBLzdFmDtX/uU2Bpcm0cmudv44A==
+"@types/react-router-dom@5.1.7":
+ version "5.1.7"
+ resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.7.tgz#a126d9ea76079ffbbdb0d9225073eb5797ab7271"
+ integrity sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==
dependencies:
"@types/history" "*"
"@types/react" "*"
@@ -1749,13 +1955,19 @@
"@types/prop-types" "*"
csstype "^3.0.2"
-"@types/react@16.9.19":
- version "16.9.19"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.19.tgz#c842aa83ea490007d29938146ff2e4d9e4360c40"
- integrity sha512-LJV97//H+zqKWMms0kvxaKYJDG05U2TtQB3chRLF8MPNs+MQh/H1aGlyDUxjaHvu08EAGerdX2z4LTBc7ns77A==
+"@types/react@17.0.3":
+ version "17.0.3"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79"
+ integrity sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==
dependencies:
"@types/prop-types" "*"
- csstype "^2.2.0"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
+"@types/scheduler@*":
+ version "0.16.1"
+ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275"
+ integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==
"@types/x2js@^3.1.0":
version "3.1.0"
@@ -2072,6 +2284,15 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
+"@zkochan/cmd-shim@^3.1.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@zkochan/cmd-shim/-/cmd-shim-3.1.0.tgz#2ab8ed81f5bb5452a85f25758eb9b8681982fd2e"
+ integrity sha512-o8l0+x7C7sMZU3v9GuJIAU10qQLtwR1dtRQIOmlNMtyaqhmpXOzx1HWiYoWfmmf9HHZoAkXpc9TM9PQYF9d4Jg==
+ dependencies:
+ is-windows "^1.0.0"
+ mkdirp-promise "^5.0.1"
+ mz "^2.5.0"
+
JSONStream@^1.0.4, JSONStream@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
@@ -2216,6 +2437,11 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
+any-promise@^1.0.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
+ integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
+
anymatch@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb"
@@ -2286,10 +2512,10 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
-array-differ@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031"
- integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=
+array-differ@^2.0.3:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-2.1.0.tgz#4b9c1c3f14b906757082925769e8ab904f4801b1"
+ integrity sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==
array-equal@^1.0.0:
version "1.0.0"
@@ -2316,7 +2542,7 @@ array-ify@^1.0.0:
resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece"
integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=
-array-union@^1.0.1:
+array-union@^1.0.1, array-union@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=
@@ -2338,7 +2564,7 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
-arrify@^1.0.0, arrify@^1.0.1:
+arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
@@ -2665,6 +2891,11 @@ before-after-hook@^2.0.0:
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==
+before-after-hook@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.0.tgz#09c40d92e936c64777aa385c4e9b904f8147eaf0"
+ integrity sha512-jH6rKQIfroBbhEXVmI7XmXe3ix5S/PgJqpzdDPnR8JGLHWNYLsYZ6tK5iWOF/Ra3oqEX0NobXGlzbiylIzVphQ==
+
big.js@^3.1.3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
@@ -2944,10 +3175,10 @@ byline@^5.0.0:
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=
-byte-size@^4.0.3:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.4.tgz#29d381709f41aae0d89c631f1c81aec88cd40b23"
- integrity sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw==
+byte-size@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191"
+ integrity sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw==
bytes@3.0.0:
version "3.0.0"
@@ -2978,7 +3209,7 @@ cacache@^10.0.4:
unique-filename "^1.1.0"
y18n "^4.0.0"
-cacache@^11.0.2, cacache@^11.3.3:
+cacache@^11.0.2:
version "11.3.3"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc"
integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==
@@ -2998,7 +3229,7 @@ cacache@^11.0.2, cacache@^11.3.3:
unique-filename "^1.1.1"
y18n "^4.0.0"
-cacache@^12.0.0, cacache@^12.0.2:
+cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.3:
version "12.0.4"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c"
integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==
@@ -3236,6 +3467,11 @@ ci-info@^1.5.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
+ci-info@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
+ integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
+
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@@ -3315,6 +3551,15 @@ clone-deep@^2.0.1:
kind-of "^6.0.0"
shallow-clone "^1.0.0"
+clone-deep@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
+ integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
+ dependencies:
+ is-plain-object "^2.0.4"
+ kind-of "^6.0.2"
+ shallow-clone "^3.0.0"
+
clone@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
@@ -3330,14 +3575,6 @@ clsx@^1.0.4:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
-cmd-shim@^2.0.2:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.1.0.tgz#e59a08d4248dda3bb502044083a4db4ac890579a"
- integrity sha512-A5C0Cyf2H8sKsHqX0tvIWRXw5/PK++3Dc0lDbsugr90nOECLLuSPahVQBG8pgmgiXgm/TzBWMqI2rWdZwHduAw==
- dependencies:
- graceful-fs "^4.1.2"
- mkdirp "~0.5.0"
-
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@@ -3577,7 +3814,7 @@ conventional-commits-filter@^2.0.2, conventional-commits-filter@^2.0.7:
lodash.ismatch "^4.4.0"
modify-values "^1.0.0"
-conventional-commits-parser@^3.0.2, conventional-commits-parser@^3.0.3:
+conventional-commits-parser@^3.0.3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.0.tgz#9e261b139ca4b7b29bcebbc54460da36894004ca"
integrity sha512-XmJiXPxsF0JhAKyfA2Nn+rZwYKJ60nanlbSWwwkGwLQFbugsc0gv1rzc7VbbUWAzJfR1qR87/pNgv9NgmxtBMQ==
@@ -3590,17 +3827,17 @@ conventional-commits-parser@^3.0.2, conventional-commits-parser@^3.0.3:
through2 "^4.0.0"
trim-off-newlines "^1.0.0"
-conventional-recommended-bump@^4.0.4:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-4.1.1.tgz#37014fadeda267d0607e2fc81124da840a585127"
- integrity sha512-JT2vKfSP9kR18RXXf55BRY1O3AHG8FPg5btP3l7LYfcWJsiXI6MCf30DepQ98E8Qhowvgv7a8iev0J1bEDkTFA==
+conventional-recommended-bump@^5.0.0:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-5.0.1.tgz#5af63903947b6e089e77767601cb592cabb106ba"
+ integrity sha512-RVdt0elRcCxL90IrNP0fYCpq1uGt2MALko0eyeQ+zQuDVWtMGAy9ng6yYn3kax42lCj9+XBxQ8ZN6S9bdKxDhQ==
dependencies:
concat-stream "^2.0.0"
conventional-changelog-preset-loader "^2.1.1"
conventional-commits-filter "^2.0.2"
- conventional-commits-parser "^3.0.2"
+ conventional-commits-parser "^3.0.3"
git-raw-commits "2.0.0"
- git-semver-tags "^2.0.2"
+ git-semver-tags "^2.0.3"
meow "^4.0.0"
q "^1.5.1"
@@ -3820,7 +4057,7 @@ csstype@2.6.8:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.8.tgz#0fb6fc2417ffd2816a418c9336da74d7f07db431"
integrity sha512-msVS9qTuMT5zwAGCVm4mxfrZ18BNc6Csd0oJAtiFMZ1FAx1CCvy2+5MDmYoix63LM/6NDbNtodCiGYGmFgO0dA==
-csstype@^2.2.0, csstype@^2.5.2, csstype@^2.6.5:
+csstype@^2.5.2, csstype@^2.6.5:
version "2.6.13"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f"
integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==
@@ -4100,15 +4337,7 @@ diffie-hellman@^5.0.0:
miller-rabin "^4.0.0"
randombytes "^2.0.0"
-dir-glob@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034"
- integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==
- dependencies:
- arrify "^1.0.1"
- path-type "^3.0.0"
-
-dir-glob@^2.0.0:
+dir-glob@^2.0.0, dir-glob@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4"
integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==
@@ -4346,6 +4575,16 @@ entities@^2.0.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
+env-paths@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43"
+ integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==
+
+envinfo@^7.3.1:
+ version "7.7.3"
+ resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.7.3.tgz#4b2d8622e3e7366afb8091b23ed95569ea0208cc"
+ integrity sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==
+
err-code@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
@@ -4493,6 +4732,11 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
+eventemitter3@^3.1.0:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
+ integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==
+
eventemitter3@^4.0.0:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
@@ -4713,7 +4957,7 @@ fast-deep-equal@^3.1.1:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
-fast-glob@^2.0.2:
+fast-glob@^2.2.6:
version "2.2.7"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d"
integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==
@@ -4993,12 +5237,12 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
-fs-extra@^7.0.0:
- version "7.0.1"
- resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
- integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
+fs-extra@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
+ integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
- graceful-fs "^4.1.2"
+ graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
@@ -5113,10 +5357,10 @@ get-pkg-repo@^1.0.0:
parse-github-repo-url "^1.3.0"
through2 "^2.0.0"
-get-port@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc"
- integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=
+get-port@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119"
+ integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==
get-stdin@^4.0.1:
version "4.0.1"
@@ -5166,7 +5410,7 @@ git-remote-origin-url@^2.0.0:
gitconfiglocal "^1.0.0"
pify "^2.3.0"
-git-semver-tags@^2.0.2, git-semver-tags@^2.0.3:
+git-semver-tags@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-2.0.3.tgz#48988a718acf593800f99622a952a77c405bfa34"
integrity sha512-tj4FD4ww2RX2ae//jSrXZzrocla9db5h0V7ikPl1P/WwoZar9epdUhwR7XHXSgc+ZkNq72BEEerqQuicoEQfzA==
@@ -5229,13 +5473,18 @@ glob-parent@^3.1.0:
is-glob "^3.1.0"
path-dirname "^1.0.0"
-glob-parent@~5.1.0:
+glob-parent@^5.0.0, glob-parent@~5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
dependencies:
is-glob "^4.0.1"
+glob-to-regexp@0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
+ integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
+
glob-to-regexp@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
@@ -5311,18 +5560,19 @@ globby@^7.1.1:
pify "^3.0.0"
slash "^1.0.0"
-globby@^8.0.1:
- version "8.0.2"
- resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d"
- integrity sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==
+globby@^9.2.0:
+ version "9.2.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d"
+ integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==
dependencies:
- array-union "^1.0.1"
- dir-glob "2.0.0"
- fast-glob "^2.0.2"
- glob "^7.1.2"
- ignore "^3.3.5"
- pify "^3.0.0"
- slash "^1.0.0"
+ "@types/glob" "^7.1.1"
+ array-union "^1.0.2"
+ dir-glob "^2.2.2"
+ fast-glob "^2.2.6"
+ glob "^7.1.3"
+ ignore "^4.0.3"
+ pify "^4.0.1"
+ slash "^2.0.0"
globule@^1.0.0:
version "1.3.2"
@@ -5338,7 +5588,7 @@ graceful-fs@4.1.4:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.4.tgz#ef089d2880f033b011823ce5c8fae798da775dbd"
integrity sha1-7widKIDwM7ARgjzlyPrnmNp3Xb0=
-graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
+graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2:
version "4.2.4"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
@@ -5480,7 +5730,7 @@ highlight.js@9.13.1:
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e"
integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A==
-history@^4.7.2:
+history@^4.9.0:
version "4.10.1"
resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
@@ -5501,12 +5751,7 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
-hoist-non-react-statics@^2.5.0:
- version "2.5.5"
- resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47"
- integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==
-
-hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
+hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -5711,7 +5956,7 @@ https-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
-https-proxy-agent@^2.2.1, https-proxy-agent@^2.2.3:
+https-proxy-agent@^2.2.3:
version "2.2.4"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==
@@ -5784,6 +6029,11 @@ ignore@^3.3.5:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==
+ignore@^4.0.3:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
+ integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
+
image-size@~0.5.0:
version "0.5.5"
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c"
@@ -6025,6 +6275,13 @@ is-ci@^1.0.10:
dependencies:
ci-info "^1.5.0"
+is-ci@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
+ integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
+ dependencies:
+ ci-info "^2.0.0"
+
is-core-module@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.1.0.tgz#a4cc031d9b1aca63eecbd18a650e13cb4eeab946"
@@ -6284,7 +6541,7 @@ is-utf8@^0.2.0:
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
-is-windows@^1.0.1, is-windows@^1.0.2:
+is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
@@ -7044,27 +7301,28 @@ left-pad@^1.3.0:
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==
-lerna@3.13.1:
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.13.1.tgz#feaff562176f304bd82329ca29ce46ab6c033463"
- integrity sha512-7kSz8LLozVsoUNTJzJzy+b8TnV9YdviR2Ee2PwGZSlVw3T1Rn7kOAPZjEi+3IWnOPC96zMPHVmjCmzQ4uubalw==
- dependencies:
- "@lerna/add" "3.13.1"
- "@lerna/bootstrap" "3.13.1"
- "@lerna/changed" "3.13.1"
- "@lerna/clean" "3.13.1"
- "@lerna/cli" "3.13.0"
- "@lerna/create" "3.13.1"
- "@lerna/diff" "3.13.1"
- "@lerna/exec" "3.13.1"
- "@lerna/import" "3.13.1"
- "@lerna/init" "3.13.1"
- "@lerna/link" "3.13.1"
- "@lerna/list" "3.13.1"
- "@lerna/publish" "3.13.1"
- "@lerna/run" "3.13.1"
- "@lerna/version" "3.13.1"
- import-local "^1.0.0"
+lerna@3.22.1:
+ version "3.22.1"
+ resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.22.1.tgz#82027ac3da9c627fd8bf02ccfeff806a98e65b62"
+ integrity sha512-vk1lfVRFm+UuEFA7wkLKeSF7Iz13W+N/vFd48aW2yuS7Kv0RbNm2/qcDPV863056LMfkRlsEe+QYOw3palj5Lg==
+ dependencies:
+ "@lerna/add" "3.21.0"
+ "@lerna/bootstrap" "3.21.0"
+ "@lerna/changed" "3.21.0"
+ "@lerna/clean" "3.21.0"
+ "@lerna/cli" "3.18.5"
+ "@lerna/create" "3.22.0"
+ "@lerna/diff" "3.21.0"
+ "@lerna/exec" "3.21.0"
+ "@lerna/import" "3.22.0"
+ "@lerna/info" "3.21.0"
+ "@lerna/init" "3.21.0"
+ "@lerna/link" "3.21.0"
+ "@lerna/list" "3.21.0"
+ "@lerna/publish" "3.22.1"
+ "@lerna/run" "3.21.0"
+ "@lerna/version" "3.22.1"
+ import-local "^2.0.0"
npmlog "^4.1.2"
less-loader@4.1.0:
@@ -7105,31 +7363,6 @@ levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
-libnpmaccess@^3.0.1:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.2.tgz#8b2d72345ba3bef90d3b4f694edd5c0417f58923"
- integrity sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ==
- dependencies:
- aproba "^2.0.0"
- get-stream "^4.0.0"
- npm-package-arg "^6.1.0"
- npm-registry-fetch "^4.0.0"
-
-libnpmpublish@^1.1.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-1.1.3.tgz#e3782796722d79eef1a0a22944c117e0c4ca4280"
- integrity sha512-/3LsYqVc52cHXBmu26+J8Ed7sLs/hgGVFMH1mwYpL7Qaynb9RenpKqIKu0sJ130FB9PMkpMlWjlbtU8A4m7CQw==
- dependencies:
- aproba "^2.0.0"
- figgy-pudding "^3.5.1"
- get-stream "^4.0.0"
- lodash.clonedeep "^4.5.0"
- normalize-package-data "^2.4.0"
- npm-package-arg "^6.1.0"
- npm-registry-fetch "^4.0.0"
- semver "^5.5.1"
- ssri "^6.0.1"
-
lightercollective@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/lightercollective/-/lightercollective-0.1.0.tgz#70df102c530dcb8d0ccabfe6175a8d00d5f61300"
@@ -7161,6 +7394,17 @@ load-json-file@^4.0.0:
pify "^3.0.0"
strip-bom "^3.0.0"
+load-json-file@^5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-5.3.0.tgz#4d3c1e01fa1c03ea78a60ac7af932c9ce53403f3"
+ integrity sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==
+ dependencies:
+ graceful-fs "^4.1.15"
+ parse-json "^4.0.0"
+ pify "^4.0.1"
+ strip-bom "^3.0.0"
+ type-fest "^0.3.0"
+
loader-runner@^2.3.0, loader-runner@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
@@ -7307,7 +7551,7 @@ lodash.tail@^4.1.1:
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
integrity sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=
-lodash.template@^4.0.2:
+lodash.template@^4.0.2, lodash.template@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
@@ -7391,7 +7635,7 @@ make-dir@^1.0.0:
dependencies:
pify "^3.0.0"
-make-dir@^2.0.0:
+make-dir@^2.0.0, make-dir@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
@@ -7404,23 +7648,6 @@ make-error@1.x:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
-make-fetch-happen@^4.0.2:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.2.tgz#2d156b11696fb32bffbafe1ac1bc085dd6c78a79"
- integrity sha512-YMJrAjHSb/BordlsDEcVcPyTbiJKkzqMf48N8dAJZT9Zjctrkb6Yg4TY9Sq2AwSIQJFn5qBBKVTYt3vP5FMIHA==
- dependencies:
- agentkeepalive "^3.4.1"
- cacache "^11.3.3"
- http-cache-semantics "^3.8.1"
- http-proxy-agent "^2.1.0"
- https-proxy-agent "^2.2.1"
- lru-cache "^5.1.1"
- mississippi "^3.0.0"
- node-fetch-npm "^2.0.2"
- promise-retry "^1.1.1"
- socks-proxy-agent "^4.0.0"
- ssri "^6.0.0"
-
make-fetch-happen@^5.0.0:
version "5.0.2"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd"
@@ -7725,6 +7952,14 @@ min-indent@^1.0.0:
resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869"
integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
+mini-create-react-context@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e"
+ integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==
+ dependencies:
+ "@babel/runtime" "^7.12.1"
+ tiny-warning "^1.0.3"
+
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
@@ -7735,7 +7970,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
-minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
+minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -7832,6 +8067,18 @@ mixin-object@^2.0.1:
for-in "^0.1.3"
is-extendable "^0.1.1"
+mkdirp-promise@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1"
+ integrity sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=
+ dependencies:
+ mkdirp "*"
+
+mkdirp@*:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
+ integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+
mkdirp@0.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.0:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
@@ -7889,15 +8136,15 @@ multicast-dns@^6.0.1:
dns-packet "^1.3.1"
thunky "^1.0.2"
-multimatch@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
- integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=
+multimatch@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-3.0.0.tgz#0e2534cc6bc238d9ab67e1b9cd5fcd85a6dbf70b"
+ integrity sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==
dependencies:
- array-differ "^1.0.0"
- array-union "^1.0.1"
- arrify "^1.0.0"
- minimatch "^3.0.0"
+ array-differ "^2.0.3"
+ array-union "^1.0.2"
+ arrify "^1.0.1"
+ minimatch "^3.0.4"
murmurhash-js@^1.0.0:
version "1.0.0"
@@ -7914,6 +8161,15 @@ mute-stream@~0.0.4:
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
+mz@^2.5.0:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
+ integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
+ dependencies:
+ any-promise "^1.0.0"
+ object-assign "^4.0.1"
+ thenify-all "^1.0.0"
+
nan@^2.12.1, nan@^2.13.2:
version "2.14.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
@@ -7972,7 +8228,7 @@ node-fetch-npm@^2.0.2:
json-parse-better-errors "^1.0.0"
safe-buffer "^5.1.1"
-node-fetch@^2.6.1:
+node-fetch@^2.5.0, node-fetch@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
@@ -8000,22 +8256,22 @@ node-gyp@^3.8.0:
tar "^2.0.0"
which "1"
-node-gyp@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-4.0.0.tgz#972654af4e5dd0cd2a19081b4b46fe0442ba6f45"
- integrity sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==
+node-gyp@^5.0.2:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e"
+ integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==
dependencies:
- glob "^7.0.3"
- graceful-fs "^4.1.2"
- mkdirp "^0.5.0"
- nopt "2 || 3"
- npmlog "0 || 1 || 2 || 3 || 4"
- osenv "0"
- request "^2.87.0"
- rimraf "2"
- semver "~5.3.0"
- tar "^4.4.8"
- which "1"
+ env-paths "^2.2.0"
+ glob "^7.1.4"
+ graceful-fs "^4.2.2"
+ mkdirp "^0.5.1"
+ nopt "^4.0.1"
+ npmlog "^4.1.2"
+ request "^2.88.0"
+ rimraf "^2.6.3"
+ semver "^5.7.1"
+ tar "^4.4.12"
+ which "^1.3.1"
node-int64@^0.4.0:
version "0.4.0"
@@ -8120,6 +8376,14 @@ node-sass@^4.14.1:
dependencies:
abbrev "1"
+nopt@^4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
+ integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
+ dependencies:
+ abbrev "1"
+ osenv "^0.1.4"
+
normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@@ -8179,14 +8443,14 @@ npm-bundled@^1.0.1:
dependencies:
npm-normalize-package-bin "^1.0.1"
-npm-lifecycle@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-2.1.1.tgz#0027c09646f0fd346c5c93377bdaba59c6748fdf"
- integrity sha512-+Vg6I60Z75V/09pdcH5iUo/99Q/vop35PaI99elvxk56azSVVsdsSsS/sXqKDNwbRRNN1qSxkcO45ZOu0yOWew==
+npm-lifecycle@^3.1.2:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309"
+ integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==
dependencies:
byline "^5.0.0"
graceful-fs "^4.1.15"
- node-gyp "^4.0.0"
+ node-gyp "^5.0.2"
resolve-from "^4.0.0"
slide "^1.1.6"
uid-number "0.0.6"
@@ -8208,7 +8472,7 @@ npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1:
semver "^5.6.0"
validate-npm-package-name "^3.0.0"
-npm-packlist@^1.1.12, npm-packlist@^1.4.1:
+npm-packlist@^1.4.4:
version "1.4.8"
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
@@ -8226,31 +8490,6 @@ npm-pick-manifest@^3.0.0:
npm-package-arg "^6.0.0"
semver "^5.4.1"
-npm-registry-fetch@^3.9.0:
- version "3.9.1"
- resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.9.1.tgz#00ff6e4e35d3f75a172b332440b53e93f4cb67de"
- integrity sha512-VQCEZlydXw4AwLROAXWUR7QDfe2Y8Id/vpAgp6TI1/H78a4SiQ1kQrKZALm5/zxM5n4HIi+aYb+idUAV/RuY0Q==
- dependencies:
- JSONStream "^1.3.4"
- bluebird "^3.5.1"
- figgy-pudding "^3.4.1"
- lru-cache "^5.1.1"
- make-fetch-happen "^4.0.2"
- npm-package-arg "^6.1.0"
-
-npm-registry-fetch@^4.0.0:
- version "4.0.7"
- resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.7.tgz#57951bf6541e0246b34c9f9a38ab73607c9449d7"
- integrity sha512-cny9v0+Mq6Tjz+e0erFAB+RYJ/AVGzkjnISiobqP8OWj9c9FLoZZu8/SPSKJWE17F1tk4018wfjV+ZbIbqC7fQ==
- dependencies:
- JSONStream "^1.3.4"
- bluebird "^3.5.1"
- figgy-pudding "^3.4.1"
- lru-cache "^5.1.1"
- make-fetch-happen "^5.0.0"
- npm-package-arg "^6.1.0"
- safe-buffer "^5.2.0"
-
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@@ -8491,7 +8730,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
-osenv@0, osenv@^0.1.5:
+osenv@0, osenv@^0.1.4, osenv@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
@@ -8556,16 +8795,28 @@ p-map-series@^1.0.0:
dependencies:
p-reduce "^1.0.0"
-p-map@^1.1.1, p-map@^1.2.0:
+p-map@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
+p-map@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
+ integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
+
p-pipe@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9"
integrity sha1-SxoROZoRUgpneQ7loMHViB1r7+k=
+p-queue@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-4.0.0.tgz#ed0eee8798927ed6f2c2f5f5b77fdb2061a5d346"
+ integrity sha512-3cRXXn3/O0o3+eVmUroJPSj/esxoEFIm0ZOno/T+NzG/VZgPOqQ8WKmlNqubSEpZmCIngEy34unkHGg83ZIBmg==
+ dependencies:
+ eventemitter3 "^3.1.0"
+
p-reduce@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa"
@@ -8588,42 +8839,6 @@ p-waterfall@^1.0.0:
dependencies:
p-reduce "^1.0.0"
-pacote@^9.5.0:
- version "9.5.12"
- resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.5.12.tgz#1e11dd7a8d736bcc36b375a9804d41bb0377bf66"
- integrity sha512-BUIj/4kKbwWg4RtnBncXPJd15piFSVNpTzY0rysSr3VnMowTYgkGKcaHrbReepAkjTr8lH2CVWRi58Spg2CicQ==
- dependencies:
- bluebird "^3.5.3"
- cacache "^12.0.2"
- chownr "^1.1.2"
- figgy-pudding "^3.5.1"
- get-stream "^4.1.0"
- glob "^7.1.3"
- infer-owner "^1.0.4"
- lru-cache "^5.1.1"
- make-fetch-happen "^5.0.0"
- minimatch "^3.0.4"
- minipass "^2.3.5"
- mississippi "^3.0.0"
- mkdirp "^0.5.1"
- normalize-package-data "^2.4.0"
- npm-normalize-package-bin "^1.0.0"
- npm-package-arg "^6.1.0"
- npm-packlist "^1.1.12"
- npm-pick-manifest "^3.0.0"
- npm-registry-fetch "^4.0.0"
- osenv "^0.1.5"
- promise-inflight "^1.0.1"
- promise-retry "^1.1.1"
- protoduck "^5.0.1"
- rimraf "^2.6.2"
- safe-buffer "^5.1.2"
- semver "^5.6.0"
- ssri "^6.0.1"
- tar "^4.4.10"
- unique-filename "^1.1.1"
- which "^1.3.1"
-
pako@~1.0.5:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
@@ -9056,7 +9271,7 @@ promzard@^0.3.0:
dependencies:
read "1"
-prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
+prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@@ -9264,50 +9479,53 @@ react-chartjs-2@2.7.6:
lodash "^4.17.4"
prop-types "^15.5.8"
-react-dom@16.12.0:
- version "16.12.0"
- resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11"
- integrity sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==
+react-dom@17.0.1:
+ version "17.0.1"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6"
+ integrity sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
- prop-types "^15.6.2"
- scheduler "^0.18.0"
+ scheduler "^0.20.1"
react-fast-compare@^2.0.1:
version "2.0.4"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
-react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6:
+react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
-react-router-dom@4.3.1:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.3.1.tgz#4c2619fc24c4fa87c9fd18f4fb4a43fe63fbd5c6"
- integrity sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==
+react-router-dom@5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662"
+ integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==
dependencies:
- history "^4.7.2"
- invariant "^2.2.4"
+ "@babel/runtime" "^7.1.2"
+ history "^4.9.0"
loose-envify "^1.3.1"
- prop-types "^15.6.1"
- react-router "^4.3.1"
- warning "^4.0.1"
+ prop-types "^15.6.2"
+ react-router "5.2.0"
+ tiny-invariant "^1.0.2"
+ tiny-warning "^1.0.0"
-react-router@^4.3.1:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.3.1.tgz#aada4aef14c809cb2e686b05cee4742234506c4e"
- integrity sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==
+react-router@5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293"
+ integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==
dependencies:
- history "^4.7.2"
- hoist-non-react-statics "^2.5.0"
- invariant "^2.2.4"
+ "@babel/runtime" "^7.1.2"
+ history "^4.9.0"
+ hoist-non-react-statics "^3.1.0"
loose-envify "^1.3.1"
+ mini-create-react-context "^0.4.0"
path-to-regexp "^1.7.0"
- prop-types "^15.6.1"
- warning "^4.0.1"
+ prop-types "^15.6.2"
+ react-is "^16.6.0"
+ tiny-invariant "^1.0.2"
+ tiny-warning "^1.0.0"
react-transition-group@4.3.0:
version "4.3.0"
@@ -9329,14 +9547,13 @@ react-transition-group@^4.4.0:
loose-envify "^1.4.0"
prop-types "^15.6.2"
-react@16.12.0:
- version "16.12.0"
- resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83"
- integrity sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==
+react@17.0.1:
+ version "17.0.1"
+ resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"
+ integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
- prop-types "^15.6.2"
read-cmd-shim@^1.0.1:
version "1.0.5"
@@ -9913,14 +10130,6 @@ sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
-scheduler@^0.18.0:
- version "0.18.0"
- resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4"
- integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==
- dependencies:
- loose-envify "^1.1.0"
- object-assign "^4.1.1"
-
scheduler@^0.20.1:
version "0.20.1"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.1.tgz#da0b907e24026b01181ecbc75efdc7f27b5a000c"
@@ -9975,12 +10184,12 @@ selfsigned@^1.9.1:
dependencies:
node-forge "^0.10.0"
-"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
+"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-semver@^6.0.0:
+semver@^6.0.0, semver@^6.2.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
@@ -10096,6 +10305,13 @@ shallow-clone@^1.0.0:
kind-of "^5.0.0"
mixin-object "^2.0.1"
+shallow-clone@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
+ integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
+ dependencies:
+ kind-of "^6.0.2"
+
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
@@ -10630,7 +10846,7 @@ tar@^2.0.0:
fstream "^1.0.12"
inherits "2"
-tar@^4.4.10, tar@^4.4.8:
+tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
@@ -10723,6 +10939,20 @@ text-extensions@^1.0.0:
resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26"
integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==
+thenify-all@^1.0.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
+ integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
+ dependencies:
+ thenify ">= 3.1.0 < 4"
+
+"thenify@>= 3.1.0 < 4":
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
+ integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
+ dependencies:
+ any-promise "^1.0.0"
+
throat@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
@@ -10773,7 +11003,7 @@ tiny-invariant@^1.0.2:
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
-tiny-warning@^1.0.0, tiny-warning@^1.0.2:
+tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
@@ -11081,6 +11311,11 @@ type-fest@^0.18.0:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.0.tgz#2edfa6382d48653707344f7fccdb0443d460e8d6"
integrity sha512-fbDukFPnJBdn2eZ3RR+5mK2slHLFd6gYHY7jna1KWWy4Yr4XysHuCdXRzy+RiG/HwG4WJat00vdC2UHky5eKiQ==
+type-fest@^0.3.0:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1"
+ integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==
+
type-fest@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
@@ -11104,10 +11339,10 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-typescript@3.7.2:
- version "3.7.2"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb"
- integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==
+typescript@4.1.4:
+ version "4.1.4"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.4.tgz#f058636e2f4f83f94ddaae07b20fd5e14598432f"
+ integrity sha512-+Uru0t8qIRgjuCpiSPpfGuhHecMllk5Zsazj5LZvVsEStEjmIRRBZe+jHjGQvsgS7M1wONy2PQXd67EMyV6acg==
typings-for-css-modules-loader@1.7.0:
version "1.7.0"
@@ -11202,6 +11437,13 @@ universal-user-agent@^4.0.0:
dependencies:
os-name "^3.1.0"
+universal-user-agent@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-5.0.0.tgz#a3182aa758069bf0e79952570ca757de3579c1d9"
+ integrity sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==
+ dependencies:
+ os-name "^3.1.0"
+
universal-user-agent@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
@@ -11225,7 +11467,7 @@ unset-value@^1.0.0:
has-value "^0.3.1"
isobject "^3.0.0"
-upath@^1.1.1:
+upath@^1.1.1, upath@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
@@ -11408,13 +11650,6 @@ walker@~1.0.5:
dependencies:
makeerror "1.0.x"
-warning@^4.0.1:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
- integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
- dependencies:
- loose-envify "^1.0.0"
-
watch@~0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986"
@@ -11719,7 +11954,7 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0:
+write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0, write-file-atomic@^2.4.2:
version "2.4.3"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==
@@ -11728,7 +11963,7 @@ write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
-write-json-file@^2.2.0, write-json-file@^2.3.0:
+write-json-file@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f"
integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8=
@@ -11740,6 +11975,18 @@ write-json-file@^2.2.0, write-json-file@^2.3.0:
sort-keys "^2.0.0"
write-file-atomic "^2.0.0"
+write-json-file@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a"
+ integrity sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==
+ dependencies:
+ detect-indent "^5.0.0"
+ graceful-fs "^4.1.15"
+ make-dir "^2.1.0"
+ pify "^4.0.1"
+ sort-keys "^2.0.0"
+ write-file-atomic "^2.4.2"
+
write-pkg@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21"
@@ -11762,13 +12009,6 @@ x2js@*:
dependencies:
xmldom "^0.1.19"
-x2js@3.2.3:
- version "3.2.3"
- resolved "https://registry.yarnpkg.com/x2js/-/x2js-3.2.3.tgz#b59c0c5f18d36c7391b8a1db068e2bc10132c960"
- integrity sha512-LJNWWp+WFOdsrp2nfTuC6+erPjZSNfeHsrdWPGpesj5g0gj2WwsedsqbN33wZWf/3loQA0jIR58jrx5Cyj7G/Q==
- dependencies:
- xmldom "^0.1.19"
-
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
@@ -11845,6 +12085,14 @@ yargs-parser@^13.1.2:
camelcase "^5.0.0"
decamelize "^1.2.0"
+yargs-parser@^15.0.1:
+ version "15.0.1"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.1.tgz#54786af40b820dcb2fb8025b11b4d659d76323b3"
+ integrity sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==
+ dependencies:
+ camelcase "^5.0.0"
+ decamelize "^1.2.0"
+
yargs-parser@^20.2.3:
version "20.2.4"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
@@ -11893,7 +12141,7 @@ yargs@^11.0.0:
y18n "^3.2.1"
yargs-parser "^9.0.2"
-yargs@^12.0.1, yargs@^12.0.4:
+yargs@^12.0.4:
version "12.0.5"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
@@ -11927,6 +12175,23 @@ yargs@^13.3.2:
y18n "^4.0.0"
yargs-parser "^13.1.2"
+yargs@^14.2.2:
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414"
+ integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==
+ dependencies:
+ cliui "^5.0.0"
+ decamelize "^1.2.0"
+ find-up "^3.0.0"
+ get-caller-file "^2.0.1"
+ require-directory "^2.1.1"
+ require-main-filename "^2.0.0"
+ set-blocking "^2.0.0"
+ string-width "^3.0.0"
+ which-module "^2.0.0"
+ y18n "^4.0.0"
+ yargs-parser "^15.0.1"
+
yargs@^7.0.0:
version "7.1.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.1.tgz#67f0ef52e228d4ee0d6311acede8850f53464df6"