diff options
author | Michael Dürre <michael.duerre@highstreet-technologies.com> | 2020-07-16 05:55:07 +0200 |
---|---|---|
committer | Michael Dürre <michael.duerre@highstreet-technologies.com> | 2020-07-16 05:55:21 +0200 |
commit | 7dbe38ba0522b346a0fcd9851e797f0fd71ecd5e (patch) | |
tree | cc19db7e0637c8e392d40cdf3a53bb5e5f3e0d30 /sdnr/wt/odlux/apps/inventoryApp/src/views | |
parent | 25b3759a0907d06e0d8e391f751c6fcf067087f5 (diff) |
switch to rfc8040 restconf
change rest interface and some small code cleanups
Issue-ID: CCSDK-2572
Signed-off-by: Michael Dürre <michael.duerre@highstreet-technologies.com>
Change-Id: I3475bd2574b32950c4bf84fbd1c2a9dac9af208a
Diffstat (limited to 'sdnr/wt/odlux/apps/inventoryApp/src/views')
-rw-r--r-- | sdnr/wt/odlux/apps/inventoryApp/src/views/dashboard.tsx | 195 | ||||
-rw-r--r-- | sdnr/wt/odlux/apps/inventoryApp/src/views/treeview.tsx | 132 |
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 |