summaryrefslogtreecommitdiffstats
path: root/sdnr/wt/odlux/apps/inventoryApp/src/views
diff options
context:
space:
mode:
Diffstat (limited to 'sdnr/wt/odlux/apps/inventoryApp/src/views')
-rw-r--r--sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx195
-rw-r--r--sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx132
2 files changed, 267 insertions, 60 deletions
diff --git a/sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx b/sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx
index b63f628a3..14792df5b 100644
--- a/sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx
+++ b/sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx
@@ -15,88 +15,163 @@
* the License.
* ============LICENSE_END==========================================================================
*/
-import * as React from "react";
-import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
-import { Connect, connect, IDispatcher } from '../../../../framework/src/flux/connect';
-import { MaterialTable, MaterialTableCtorType } from '../../../../framework/src/components/material-table';
-import { TreeView, TreeItem, TreeViewCtorType } from '../../../../framework/src/components/material-ui/treeView';
+import * as React from 'react';
+import { RouteComponentProps, withRouter } from 'react-router-dom';
-import { InventoryType } from '../models/inventory';
+import connect, { IDispatcher, Connect } from "../../../../framework/src/flux/connect";
import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
-import { createInventoryElementsProperties, createInventoryElementsActions } from "../handlers/inventoryElementsHandler";
+import { MaterialTable, MaterialTableCtorType, ColumnType } from "../../../../framework/src/components/material-table";
+import { AppBar, Tabs, Tab, MenuItem, Typography } from "@material-ui/core";
+import { PanelId } from "../models/panelId";
+import { setPanelAction } from "../actions/panelActions";
-const styles = (theme: Theme) => createStyles({
- root: {
- flex: "1 0 0%",
- display: "flex",
- flexDirection: "row",
- },
- tree: {
- flex: "1 0 0%",
- minWidth: "250px",
- padding: `0px ${theme.spacing(1)}px`
- },
- details: {
- flex: "5 0 0%",
- padding: `0px ${theme.spacing(1)}px`
- }
-});
-const InventoryTable = MaterialTable as MaterialTableCtorType<InventoryType & {_id: string}>;
+import { createConnectedNetworkElementsProperties, createConnectedNetworkElementsActions } from "../handlers/connectedNetworkElementsHandler";
+
+import { NetworkElementConnection } from "../models/networkElementConnection";
+
+import { InventoryType } from '../models/inventory';
+
+import { createInventoryElementsProperties, createInventoryElementsActions } from "../handlers/inventoryElementsHandler";
+import { NavigateToApplication } from '../../../../framework/src/actions/navigationActions';
+import { updateInventoryTreeAsyncAction } from '../actions/inventoryTreeActions';
+
+const InventoryTable = MaterialTable as MaterialTableCtorType<InventoryType & { _id: string }>;
const mapProps = (state: IApplicationStoreState) => ({
+ connectedNetworkElementsProperties: createConnectedNetworkElementsProperties(state),
+ panelId: state.inventory.currentOpenPanel,
inventoryElementsProperties: createInventoryElementsProperties(state),
inventoryElements: state.inventory.inventoryElements
});
const mapDispatch = (dispatcher: IDispatcher) => ({
- inventoryElementsActions: createInventoryElementsActions(dispatcher.dispatch)
+ connectedNetworkElementsActions: createConnectedNetworkElementsActions(dispatcher.dispatch),
+ switchActivePanel: (panelId: PanelId) => {
+ dispatcher.dispatch(setPanelAction(panelId));
+ },
+ 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)),
});
-const SampleTree = TreeView as any as TreeViewCtorType<string>;
+let treeViewInitialSorted = false;
+let inventoryInitialSorted = false;
+const ConnectedElementTable = MaterialTable as MaterialTableCtorType<NetworkElementConnection>;
-type TreeDemoItem = TreeItem<string>;
+type DashboardComponentProps = RouteComponentProps & Connect<typeof mapProps, typeof mapDispatch>;
-const treeData: TreeDemoItem[] = [
- {
- content: "Erste Ebene", children: [
- {
- content: "Zweite Ebene", children: [
- { content: "Dritte Ebene" },
- ]
- },
- { content: "Zweite Ebene 2" },
- ]
- },
- { content: "Erste Ebene 3" },
-];
+class DashboardSelectorComponent extends React.Component<DashboardComponentProps> {
+
+ private onHandleTabChange = (event: React.ChangeEvent<{}>, newValue: PanelId) => {
+ this.onTogglePanel(newValue);
+ }
+
+ private onTogglePanel = (panelId: PanelId) => {
+ const nextActivePanel = panelId;
+ this.props.switchActivePanel(nextActivePanel);
+
+ switch (nextActivePanel) {
+ case 'InventoryElementsTable':
+
+ if (!inventoryInitialSorted) {
+ this.props.inventoryElementsActions.onHandleExplicitRequestSort("nodeId", "asc");
+ inventoryInitialSorted = true;
+ } else {
+ this.props.inventoryElementsActions.onRefresh();
+
+ }
+ break;
+ case 'TreeviewTable':
+ if (!treeViewInitialSorted) {
+ this.props.connectedNetworkElementsActions.onHandleExplicitRequestSort("nodeId", "asc");
+ treeViewInitialSorted = true;
+ } else {
+ this.props.connectedNetworkElementsActions.onRefresh();
+ }
+ break;
+ case null:
+ // do nothing if all panels are closed
+ break;
+ default:
+ console.warn("Unknown nextActivePanel [" + nextActivePanel + "] in connectView");
+ break;
+ }
+
+ };
+
+ getContextMenu = (rowData: InventoryType) => {
+ return [
+ <MenuItem aria-label={"inventory-button"} onClick={event => { this.props.updateInventoryTree(rowData.nodeId, rowData.uuid); this.props.navigateToApplication("inventory", rowData.nodeId) }}><Typography>View in Treeview</Typography></MenuItem>,
+ ];
+
+ }
-class DashboardComponent extends React.Component<& WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>> {
render() {
- return <InventoryTable stickyHeader title="Inventory" idProperty="_id" 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} >
- </InventoryTable>
+
+ const { panelId: activePanelId } = this.props;
+ return (
+ <>
+ <AppBar position="static">
+ <Tabs value={activePanelId} onChange={this.onHandleTabChange} aria-label="simple tabs example">
+ <Tab label="Table View" value="InventoryElementsTable" />
+ <Tab label="Tree view" value="TreeviewTable" />
+ </Tabs>
+ </AppBar>
+
+ {
+
+ activePanelId === "InventoryElementsTable" &&
+
+ <InventoryTable stickyHeader title="Inventory" idProperty="_id" 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>
+
+ }
+ {
+ activePanelId === "TreeviewTable" &&
+
+ <ConnectedElementTable stickyHeader onHandleClick={(e, row) => { this.props.history.push(`${this.props.match.path}/${row.nodeId}`) }} columns={[
+ { property: "nodeId", title: "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>
+ }
+ </>
+ );
}
componentDidMount() {
- this.props.inventoryElementsActions.onToggleFilter();
- this.props.inventoryElementsActions.onHandleRequestSort("node-id");
+
+ if (this.props.panelId === null) { //set default tab if none is set
+ this.onTogglePanel("InventoryElementsTable");
+ }
+
}
}
-export const Dashboard = connect(mapProps, mapDispatch)(withStyles(styles)(DashboardComponent));
-export default Dashboard; \ No newline at end of file
+export const Dashboard = withRouter(connect(mapProps, mapDispatch)(DashboardSelectorComponent));
+export default Dashboard;
+
diff --git a/sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx b/sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx
new file mode 100644
index 000000000..5f2c61080
--- /dev/null
+++ b/sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx
@@ -0,0 +1,132 @@
+/**
+ * ============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 { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles';
+
+import { renderObject } from '../../../../framework/src/components/objectDump';
+import { Connect, connect, IDispatcher } from '../../../../framework/src/flux/connect';
+import { TreeView, TreeViewCtorType, SearchMode } from '../../../../framework/src/components/material-ui/treeView';
+
+import { IApplicationStoreState } from "../../../../framework/src/store/applicationStore";
+
+import { updateInventoryTreeAsyncAction, selectInventoryNodeAsyncAction, UpdateSelectedNodeAction, UpdateExpandedNodesAction, setSearchTermAction} from "../actions/inventoryTreeActions";
+import { TreeDemoItem } from "../models/inventory";
+
+import { RouteComponentProps } from "react-router-dom";
+
+const styles = (theme: Theme) => createStyles({
+ root: {
+ flex: "1 0 0%",
+ display: "flex",
+ flexDirection: "row",
+ },
+ tree: {
+ flex: "1 0 0%",
+ minWidth: "250px",
+ padding: `0px ${theme.spacing(1)}px`
+ },
+ details: {
+ flex: "5 0 0%",
+ padding: `0px ${theme.spacing(1)}px`
+ }
+});
+
+const mapProps = (state: IApplicationStoreState) => ({
+ isBusy: state.inventory.inventoryTree.isBusy,
+ rootNodes: state.inventory.inventoryTree.rootNodes,
+ searchTerm: state.inventory.inventoryTree.searchTerm,
+ selectedNode: state.inventory.inventoryTree.selectedNode,
+ expendedItems: state.inventory.inventoryTree.expandedItems,
+});
+
+const mapDispatch = (dispatcher: IDispatcher) => ({
+ updateExpendedNodes: (expendedNodes: TreeDemoItem[]) => dispatcher.dispatch(new UpdateExpandedNodesAction(expendedNodes)),
+ updateInventoryTree: (mountId: string, seatchTerm?: string) => dispatcher.dispatch(updateInventoryTreeAsyncAction(mountId, seatchTerm)),
+ selectTreeNode: (nodeId?: string) => nodeId ? dispatcher.dispatch(selectInventoryNodeAsyncAction(nodeId)) : dispatcher.dispatch(new UpdateSelectedNodeAction(undefined)),
+ setSearchTerm: (searchTerm: string) => dispatcher.dispatch(setSearchTermAction(searchTerm)),
+});
+
+const propsChache = Symbol("PropsCache");
+const InventoryTree = TreeView as any as TreeViewCtorType<string>;
+
+
+
+type TreeviewComponentProps = RouteComponentProps<{ mountId: string}> & WithStyles<typeof styles> & Connect<typeof mapProps, typeof mapDispatch>
+
+type TreeviewComponentState = {
+ [propsChache]: {
+ rootNodes?: TreeDemoItem[];
+ };
+ rootNodes: TreeDemoItem[];
+}
+
+
+class DashboardComponent extends React.Component<TreeviewComponentProps, TreeviewComponentState> {
+
+ constructor (props: TreeviewComponentProps) {
+ super(props);
+
+ this.state = {
+ [propsChache]: {},
+ rootNodes: [],
+ };
+ }
+
+ static getDerivedStateFromProps(props: TreeviewComponentProps, state: TreeviewComponentState) {
+ if (state[propsChache].rootNodes != props.rootNodes) {
+ state = { ...state, rootNodes: props.rootNodes}
+ }
+ return state;
+ }
+
+ render() {
+ const { classes, updateInventoryTree, updateExpendedNodes, expendedItems, selectedNode, selectTreeNode, searchTerm, match: { params: { mountId }} } = this.props;
+ return (
+ <div 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) || null
+ }</div>
+ </div>
+ );
+ }
+
+ componentDidMount() {
+ const { updateInventoryTree, searchTerm, match: { params: { mountId } }} = this.props;
+ updateInventoryTree(mountId, searchTerm);
+ }
+
+ componentWillUnmount(){
+ this.props.setSearchTerm("");
+ }
+}
+
+export const InventoryTreeView = connect(mapProps, mapDispatch)(withStyles(styles)(DashboardComponent));
+export default InventoryTreeView; \ No newline at end of file