Update InventoryApp 83/122983/1
authorAijana Schumann <aijana.schumann@highstreet-technologies.com>
Fri, 30 Jul 2021 07:03:14 +0000 (09:03 +0200)
committerAijana Schumann <aijana.schumann@highstreet-technologies.com>
Fri, 30 Jul 2021 07:03:14 +0000 (09:03 +0200)
Fix several bugs and improve usability

Issue-ID: CCSDK-3395
Signed-off-by: Aijana Schumann <aijana.schumann@highstreet-technologies.com>
Change-Id: I25a3badc2d179ccc99ffd38e860046dbfd771df1

sdnr/wt/odlux/apps/inventoryApp/src/index.html
sdnr/wt/odlux/apps/inventoryApp/src/pluginInventory.tsx
sdnr/wt/odlux/apps/inventoryApp/src/services/inventoryService.ts
sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx
sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx
sdnr/wt/odlux/odlux.properties

index 21f3130..2c44424 100644 (file)
   <script type="text/javascript" src="./config.js"></script>
   <script>
     // run the application
-    require(["app", "inventoryApp", "connectApp", "configurationApp"], function (app, inventoryApp, connectApp, configurationApp) {
+    require(["app", "inventoryApp", "connectApp", "configurationApp", "faultApp"], function (app, inventoryApp, connectApp, configurationApp, faultApp) {
       inventoryApp.register();
       connectApp.register();
       configurationApp.register();
+      faultApp.register();
       app("./app.tsx").runApplication();
     });
   </script>
index 665e085..50339c0 100644 (file)
@@ -21,16 +21,68 @@ import * as React from "react";
 import { withRouter, RouteComponentProps, Route, Switch, Redirect } from 'react-router-dom';
 import { faShoppingBag } from '@fortawesome/free-solid-svg-icons'; // select app icon
 import applicationManager from '../../../framework/src/services/applicationManager';
+import connect, { Connect, IDispatcher } from '../../../framework/src/flux/connect';
+import { IApplicationStoreState } from "../../../framework/src/store/applicationStore";
 
 import { InventoryTreeView } from './views/treeview';
-import Dashboard from "./views/dashboard";
+import Dashboard from './views/dashboard';
+
+import { PanelId } from "./models/panelId";
+import { SetPanelAction } from "./actions/panelActions";
 
 import inventoryAppRootHandler from './handlers/inventoryAppRootHandler';
+import { createInventoryElementsActions, createInventoryElementsProperties } from "./handlers/inventoryElementsHandler";
+import { createConnectedNetworkElementsProperties, createConnectedNetworkElementsActions } from "./handlers/connectedNetworkElementsHandler";
+
+let currentMountId: string | undefined = undefined;
+const mapProps = (state: IApplicationStoreState) => ({
+  inventoryProperties: createInventoryElementsProperties(state),
+  panelId: state.inventory.currentOpenPanel,
+  connectedNetworkElementsProperties: createConnectedNetworkElementsProperties(state),
+});
+
+const mapDisp = (dispatcher: IDispatcher) => ({
+  inventoryActions: createInventoryElementsActions(dispatcher.dispatch, true),
+  connectedNetworkElementsActions: createConnectedNetworkElementsActions(dispatcher.dispatch, true),
+  setCurrentPanel: (panelId: PanelId) => dispatcher.dispatch(new SetPanelAction(panelId)),
+});
+
+const InventoryTableApplicationRouteAdapter = connect(mapProps, mapDisp)((props: RouteComponentProps<{ mountId?: string }> & Connect<typeof mapProps, typeof mapDisp>) => {
+  if (currentMountId !== props.match.params.mountId) {
+    // route parameter has changed
+    currentMountId = props.match.params.mountId || undefined;
+    // Hint: This timeout is needed, since it is not recommended to change the state while rendering is in progress !
+    window.setTimeout(() => {
+      if (currentMountId) {
+        if (props.panelId) {
+          props.setCurrentPanel(props.panelId);
+        }
+        else {
+          props.setCurrentPanel("InventoryElementsTable");
+        }
+        props.inventoryActions.onFilterChanged("nodeId", currentMountId);
+        props.connectedNetworkElementsActions.onFilterChanged("nodeId", currentMountId);
+        if (!props.inventoryProperties.showFilter) {
+          props.inventoryActions.onToggleFilter(false);
+        }
+        if (!props.connectedNetworkElementsProperties.showFilter) {
+          props.connectedNetworkElementsActions.onToggleFilter(false);
+        }
+        props.inventoryActions.onRefresh();
+        props.connectedNetworkElementsActions.onRefresh();
+      }
+    });
+  }
+  return (
+    <Dashboard />
+  )
+});
 
 const App = withRouter((props: RouteComponentProps) => (
   <Switch>
+    <Route path={`${props.match.path}/dashboard/:mountId`} component={InventoryTableApplicationRouteAdapter} />
     <Route path={`${props.match.path}/:mountId`} component={InventoryTreeView} />
-    <Route path={`${props.match.path}`} component={Dashboard} /> 
+    <Route path={`${props.match.path}`} component={Dashboard} />
     <Redirect to={`${props.match.path}`} />
   </Switch>
 ));
index cf25a40..cb70bf5 100644 (file)
@@ -32,7 +32,7 @@ class InventoryService {
       "query": searchTerm
     };
     const inventoryTree = await requestRest<InventoryTreeNode>(path, { method: "POST" , body: JSON.stringify(body)});
-    return inventoryTree && convertPropertyNames(inventoryTree, replaceHyphen) || null;
+    return inventoryTree && inventoryTree || null;
   }
 
   public async getInventoryEntry(id: string): Promise<InventoryType | undefined> {
@@ -61,7 +61,7 @@ class InventoryService {
     }>(path, { method: "POST", body: JSON.stringify(body) });
 
     return inventoryTreeElement && inventoryTreeElement["data-provider:output"] && inventoryTreeElement["data-provider:output"].pagination && inventoryTreeElement["data-provider:output"].pagination.total >= 1 &&
-      inventoryTreeElement["data-provider:output"].data && convertPropertyNames(inventoryTreeElement["data-provider:output"].data[0], replaceHyphen) || undefined;
+      inventoryTreeElement["data-provider:output"].data && inventoryTreeElement["data-provider:output"].data[0] || undefined;
    // return await getElement(id);
   }
 
index 11427fb..b672dc3 100644 (file)
@@ -55,7 +55,7 @@ const mapDispatch = (dispatcher: IDispatcher) => ({
   },
   inventoryElementsActions: createInventoryElementsActions(dispatcher.dispatch),
   navigateToApplication: (applicationName: string, path?: string) => dispatcher.dispatch(new NavigateToApplication(applicationName, path)),
-  updateInventoryTree: (mountId: string, seatchTerm?: string) => dispatcher.dispatch(updateInventoryTreeAsyncAction(mountId, seatchTerm)),
+  updateInventoryTree: (mountId: string, searchTerm?: string) => dispatcher.dispatch(updateInventoryTreeAsyncAction(mountId, searchTerm)),
 });
 
 let treeViewInitialSorted = false;
@@ -173,19 +173,19 @@ class DashboardSelectorComponent extends React.Component<DashboardComponentProps
         {
           activePanelId === "TreeviewTable" &&
 
-          <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 },
-            { property: "port", title: "Port", type: ColumnType.numeric },
-            { property: "coreModelCapability", title: "Core Model", type: ColumnType.text },
-            { property: "deviceType", title: "Type", type: ColumnType.text },
-          ]} idProperty="id" {...this.props.connectedNetworkElementsActions} {...this.props.connectedNetworkElementsProperties} asynchronus >
+          <ConnectedElementTable stickyHeader tableId="treeview-networkelement-selection-table"
+            onHandleClick={(e, row) => {
+              this.props.navigateToApplication("inventory", 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 },
+              { property: "port", title: "Port", type: ColumnType.numeric },
+              { property: "coreModelCapability", title: "Core Model", type: ColumnType.text },
+              { property: "deviceType", title: "Type", type: ColumnType.text },
+            ]} idProperty="id" {...this.props.connectedNetworkElementsActions} {...this.props.connectedNetworkElementsProperties} asynchronus >
           </ConnectedElementTable>
         }
       </>
index 9544861..cfcfd3f 100644 (file)
@@ -24,10 +24,13 @@ import { TreeView, TreeViewCtorType, SearchMode } from '../../../../framework/sr
 
 import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
 
+import Breadcrumbs from '@material-ui/core/Breadcrumbs';
+import Link from '@material-ui/core/Link';
+
 import { updateInventoryTreeAsyncAction, selectInventoryNodeAsyncAction, UpdateSelectedNodeAction, UpdateExpandedNodesAction, setSearchTermAction } from "../actions/inventoryTreeActions";
 import { TreeDemoItem } from "../models/inventory";
 
-import { RouteComponentProps } from "react-router-dom";
+import { RouteComponentProps } from 'react-router-dom';
 
 const styles = (theme: Theme) => createStyles({
   root: {
@@ -56,7 +59,7 @@ const mapProps = (state: IApplicationStoreState) => ({
 
 const mapDispatch = (dispatcher: IDispatcher) => ({
   updateExpendedNodes: (expendedNodes: TreeDemoItem[]) => dispatcher.dispatch(new UpdateExpandedNodesAction(expendedNodes)),
-  updateInventoryTree: (mountId: string, seatchTerm?: string) => dispatcher.dispatch(updateInventoryTreeAsyncAction(mountId, seatchTerm)),
+  updateInventoryTree: (mountId: string, searchTerm?: string) => dispatcher.dispatch(updateInventoryTreeAsyncAction(mountId, searchTerm)),
   selectTreeNode: (nodeId?: string) => nodeId ? dispatcher.dispatch(selectInventoryNodeAsyncAction(nodeId)) : dispatcher.dispatch(new UpdateSelectedNodeAction(undefined)),
   setSearchTerm: (searchTerm: string) => dispatcher.dispatch(setSearchTermAction(searchTerm)),
 });
@@ -97,24 +100,46 @@ class DashboardComponent extends React.Component<TreeviewComponentProps, Treevie
   render() {
     const { classes, updateInventoryTree, updateExpendedNodes, expendedItems, selectedNode, selectTreeNode, searchTerm, match: { params: { mountId } } } = this.props;
     const scrollbar = { overflow: "auto", paddingRight: "20px" }
+
+    let filteredDashboardPath = `/inventory/dashboard/${this.props.match.params.mountId}`;
+    let basePath = `/inventory/${this.props.match.params.mountId}`;
+
     return (
-      <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);
-            if (indexOfItemToToggle === -1) {
-              updateExpendedNodes([...expendedItems, item]);
-            } else {
-              updateExpendedNodes([
-                ...expendedItems.slice(0, indexOfItemToToggle),
-                ...expendedItems.slice(indexOfItemToToggle + 1),
-              ]);
-            }
-          }}
-          onItemClick={(elm) => selectTreeNode(elm.value)} />
-        <div className={classes.details}>{
-          selectedNode && renderObject(selectedNode, "tree-view") || null
-        }</div>
+      <div style={scrollbar} >
+        <div >
+          <Breadcrumbs aria-label="breadcrumbs">
+            <Link color="inherit" href="#" aria-label="back-breadcrumb"
+              onClick={(event: React.MouseEvent<HTMLElement>) => {
+                event.preventDefault();
+                this.props.history.push(filteredDashboardPath);
+              }}>Back</Link>
+            <Link color="inherit" href="#"
+              aria-label={this.props.match.params.mountId + '-breadcrumb'}
+              onClick={(event: React.MouseEvent<HTMLElement>) => {
+                event.preventDefault();
+                this.props.history.push(basePath);
+              }}><span>{this.props.match.params.mountId}</span></Link>
+          </Breadcrumbs>
+        </div>
+        <br />
+        <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);
+              if (indexOfItemToToggle === -1) {
+                updateExpendedNodes([...expendedItems, item]);
+              } else {
+                updateExpendedNodes([
+                  ...expendedItems.slice(0, indexOfItemToToggle),
+                  ...expendedItems.slice(indexOfItemToToggle + 1),
+                ]);
+              }
+            }}
+            onItemClick={(elm) => selectTreeNode(elm.value)} />
+          <div className={classes.details}>{
+            selectedNode && renderObject(selectedNode, "tree-view") || null
+          }</div>
+        </div>
       </div>
     );
   }
@@ -125,7 +150,7 @@ class DashboardComponent extends React.Component<TreeviewComponentProps, Treevie
   }
 
   componentWillUnmount() {
-    this.props.setSearchTerm("");
+    this.props.setSearchTerm("*");
   }
 }
 
index 3b41140..5e34ec0 100644 (file)
@@ -4,7 +4,7 @@ odlux.apps.connectApp.buildno=110.0d5d064(21/07/05)
 odlux.apps.eventLogApp.buildno=96.078ad12(21/03/25)
 odlux.apps.faultApp.buildno=110.0d5d064(21/07/05)
 odlux.apps.helpApp.buildno=96.078ad12(21/03/25)
-odlux.apps.inventoryApp.buildno=96.078ad12(21/03/25)
+odlux.apps.inventoryApp.buildno=108.a60ec28(21/06/11)
 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)