From 9200d78ea23316e8f132a44ea739793d8f8e4bd4 Mon Sep 17 00:00:00 2001 From: Werner Kramer Date: Fri, 8 Nov 2024 13:10:54 +0100 Subject: [PATCH 1/7] Move topology displayTabs to own function --- src/lib/topology/displayTabs.ts | 110 ++++++++++++++++++++++++++++++ src/views/TopologyDisplayView.vue | 109 +---------------------------- 2 files changed, 112 insertions(+), 107 deletions(-) create mode 100644 src/lib/topology/displayTabs.ts diff --git a/src/lib/topology/displayTabs.ts b/src/lib/topology/displayTabs.ts new file mode 100644 index 00000000..7f418544 --- /dev/null +++ b/src/lib/topology/displayTabs.ts @@ -0,0 +1,110 @@ +import { TopologyNode } from '@deltares/fews-pi-requests' +import { RouteLocationNamedRaw } from 'vue-router' + +export interface DisplayTab { + type: + | 'charts' + | 'map' + | 'reports' + | 'schematic-status-display' + id: string + title: string + href?: string + target?: string + to: RouteLocationNamedRaw + icon: string +} + +export function displayTabsForNode(leafNode: TopologyNode, parentNodeId?: string) { + const activeNodeId = leafNode.id + const timeseriesTabId = `${activeNodeId}-timeseries` + const reportsTabId = `${activeNodeId}-reports` + const spatialTabId = `${activeNodeId}-spatial` + const ssdTabId = `${activeNodeId}-ssd` + const _displayTabs: DisplayTab[] = [] + if ( + leafNode.gridDisplaySelection !== undefined || + leafNode.filterIds !== undefined + ) { + _displayTabs.push({ + type: 'map', + id: spatialTabId, + title: 'Map', + to: { + name: 'TopologySpatialDisplay', + params: { + nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, + layerName: leafNode.gridDisplaySelection?.plotId, + }, + }, + icon: 'mdi-map', + }) + } + if ( + leafNode.displayGroups !== undefined || + leafNode.displayId !== undefined || + (leafNode.plotId != undefined && leafNode.locationIds != undefined) + ) { + _displayTabs.push({ + type: 'charts', + id: timeseriesTabId, + title: 'Charts', + to: { + name: 'TopologyTimeSeries', + params: { + nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, + }, + }, + icon: 'mdi-chart-multiple', + }) + } + if ( + leafNode.filterIds !== undefined && + leafNode.filterIds.length == 1 && + leafNode.dataDownloadDisplay !== undefined + ) { + _displayTabs.push({ + type: 'charts', + id: timeseriesTabId, + title: 'Download', + to: { + name: 'TopologyDataDownload', + params: { + nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, + }, + }, + icon: 'mdi-download', + }) + } + if (leafNode.reportDisplay?.reports.length) { + _displayTabs.push({ + type: 'reports', + id: reportsTabId, + title: 'Reports', + to: { + name: 'TopologyReports', + params: { + nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, + }, + }, + icon: 'mdi-file-document', + }) + } + if (leafNode.scadaPanelId !== undefined) { + _displayTabs.push({ + type: 'schematic-status-display', + id: ssdTabId, + title: 'Schematic', + to: { + name: 'TopologySchematicStatusDisplay', + params: { + nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, + panelId: leafNode.scadaPanelId, + }, + }, + icon: 'mdi-view-dashboard', + }) + } + return _displayTabs +} + diff --git a/src/views/TopologyDisplayView.vue b/src/views/TopologyDisplayView.vue index f3dbfc75..bfb136c5 100644 --- a/src/views/TopologyDisplayView.vue +++ b/src/views/TopologyDisplayView.vue @@ -118,7 +118,6 @@ import type { WebOcTopologyDisplayConfig } from '@deltares/fews-pi-requests' import { computed, ref, StyleValue, watch, watchEffect } from 'vue' import { - type RouteLocationNamedRaw, onBeforeRouteUpdate, RouteLocationNormalized, useRoute, @@ -131,6 +130,7 @@ import { useDisplay } from 'vuetify' import { useNodesStore } from '@/stores/nodes' import { nodeButtonItems, recursiveUpdateNode } from '@/lib/topology/nodes' import { useDownloadDialogStore } from '@/stores/downloadDialog' +import { displayTabsForNode, type DisplayTab } from '@/lib/topology/displayTabs.js' interface Props { nodeId?: string | string[] @@ -141,16 +141,6 @@ interface Props { longitude?: string } -interface DisplayTab { - type: 'charts' | 'map' | 'reports' | 'schematic-status-display' - id: string - title: string - href?: string - target?: string - to: RouteLocationNamedRaw - icon: string -} - const props = defineProps() const configStore = useConfigStore() @@ -274,99 +264,6 @@ function updateItems(): void { } } -function displayTabsForNode(leafNode: TopologyNode, parentNodeId?: string) { - const activeNodeId = leafNode.id - const timeseriesTabId = `${activeNodeId}-timeseries` - const reportsTabId = `${activeNodeId}-reports` - const spatialTabId = `${activeNodeId}-spatial` - const ssdTabId = `${activeNodeId}-ssd` - const _displayTabs: DisplayTab[] = [] - if ( - leafNode.gridDisplaySelection !== undefined || - leafNode.filterIds !== undefined - ) { - _displayTabs.push({ - type: 'map', - id: spatialTabId, - title: 'Map', - to: { - name: 'TopologySpatialDisplay', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - layerName: leafNode.gridDisplaySelection?.plotId, - }, - }, - icon: 'mdi-map', - }) - } - if ( - leafNode.displayGroups !== undefined || - leafNode.displayId !== undefined || - (leafNode.plotId != undefined && leafNode.locationIds != undefined) - ) { - _displayTabs.push({ - type: 'charts', - id: timeseriesTabId, - title: 'Charts', - to: { - name: 'TopologyTimeSeries', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - }, - }, - icon: 'mdi-chart-multiple', - }) - } - if ( - leafNode.filterIds !== undefined && - leafNode.filterIds.length == 1 && - leafNode.dataDownloadDisplay !== undefined - ) { - _displayTabs.push({ - type: 'charts', - id: timeseriesTabId, - title: 'Download', - to: { - name: 'TopologyDataDownload', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - }, - }, - icon: 'mdi-download', - }) - } - if (leafNode.reportDisplay?.reports.length) { - _displayTabs.push({ - type: 'reports', - id: reportsTabId, - title: 'Reports', - to: { - name: 'TopologyReports', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - }, - }, - icon: 'mdi-file-document', - }) - } - if (leafNode.scadaPanelId !== undefined) { - _displayTabs.push({ - type: 'schematic-status-display', - id: ssdTabId, - title: 'Schematic', - to: { - name: 'TopologySchematicStatusDisplay', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - panelId: leafNode.scadaPanelId, - }, - }, - icon: 'mdi-view-dashboard', - }) - } - return _displayTabs -} - watch(nodes, updateItems) watch(thresholds, updateItems) @@ -408,9 +305,7 @@ watchEffect(() => { // Create the displayTabs for the active node. if (node === undefined) return - const _displayTabs = displayTabsForNode(node, parentNodeIdNodeId) - displayTabs.value = _displayTabs - + displayTabs.value = displayTabsForNode(node, parentNodeIdNodeId) externalLink.value = node.url }) From 3699afdf85742c583d949e9834c14f24134d521e Mon Sep 17 00:00:00 2001 From: Werner Kramer Date: Fri, 8 Nov 2024 13:29:23 +0100 Subject: [PATCH 2/7] Refactor displayTabsForNode --- src/lib/topology/displayTabs.ts | 180 +++++++++++++++----------------- 1 file changed, 84 insertions(+), 96 deletions(-) diff --git a/src/lib/topology/displayTabs.ts b/src/lib/topology/displayTabs.ts index 7f418544..58ba20a9 100644 --- a/src/lib/topology/displayTabs.ts +++ b/src/lib/topology/displayTabs.ts @@ -2,109 +2,97 @@ import { TopologyNode } from '@deltares/fews-pi-requests' import { RouteLocationNamedRaw } from 'vue-router' export interface DisplayTab { - type: - | 'charts' - | 'map' - | 'reports' - | 'schematic-status-display' + type: 'charts' | 'map' | 'reports' | 'schematic-status-display' id: string title: string href?: string target?: string to: RouteLocationNamedRaw icon: string + active: boolean } -export function displayTabsForNode(leafNode: TopologyNode, parentNodeId?: string) { - const activeNodeId = leafNode.id - const timeseriesTabId = `${activeNodeId}-timeseries` - const reportsTabId = `${activeNodeId}-reports` - const spatialTabId = `${activeNodeId}-spatial` - const ssdTabId = `${activeNodeId}-ssd` - const _displayTabs: DisplayTab[] = [] - if ( - leafNode.gridDisplaySelection !== undefined || - leafNode.filterIds !== undefined - ) { - _displayTabs.push({ - type: 'map', - id: spatialTabId, - title: 'Map', - to: { - name: 'TopologySpatialDisplay', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - layerName: leafNode.gridDisplaySelection?.plotId, - }, - }, - icon: 'mdi-map', - }) - } - if ( - leafNode.displayGroups !== undefined || - leafNode.displayId !== undefined || - (leafNode.plotId != undefined && leafNode.locationIds != undefined) - ) { - _displayTabs.push({ - type: 'charts', - id: timeseriesTabId, - title: 'Charts', - to: { - name: 'TopologyTimeSeries', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - }, - }, - icon: 'mdi-chart-multiple', - }) - } - if ( - leafNode.filterIds !== undefined && - leafNode.filterIds.length == 1 && - leafNode.dataDownloadDisplay !== undefined - ) { - _displayTabs.push({ - type: 'charts', - id: timeseriesTabId, - title: 'Download', - to: { - name: 'TopologyDataDownload', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - }, - }, - icon: 'mdi-download', - }) - } - if (leafNode.reportDisplay?.reports.length) { - _displayTabs.push({ - type: 'reports', - id: reportsTabId, - title: 'Reports', - to: { - name: 'TopologyReports', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - }, - }, - icon: 'mdi-file-document', - }) - } - if (leafNode.scadaPanelId !== undefined) { - _displayTabs.push({ - type: 'schematic-status-display', - id: ssdTabId, - title: 'Schematic', - to: { - name: 'TopologySchematicStatusDisplay', - params: { - nodeId: parentNodeId ? [parentNodeId, leafNode.id] : leafNode.id, - panelId: leafNode.scadaPanelId, - }, - }, - icon: 'mdi-view-dashboard', - }) - } - return _displayTabs +const displayTabs: DisplayTab[] = [ + { + type: 'charts', + id: 'timeseries', + title: 'Charts', + to: { name: 'TopologyTimeSeries' }, + icon: 'mdi-chart-multiple', + active: false, + }, + { + type: 'map', + id: 'spatial', + title: 'Map', + to: { name: 'TopologySpatialDisplay' }, + icon: 'mdi-map', + active: false, + }, + { + type: 'reports', + id: 'reports', + title: 'Reports', + to: { name: 'TopologyReports' }, + icon: 'mdi-file-document', + active: false, + }, + { + type: 'schematic-status-display', + id: 'ssd', + title: 'Schematic', + to: { name: 'TopologySchematicStatusDisplay' }, + icon: 'mdi-view-dashboard', + active: false, + }, +] + + + +function nodeHasMap(node: TopologyNode) { + return node.gridDisplaySelection !== undefined || node.filterIds !== undefined } +function nodeHasCharts(node: TopologyNode) { + return ( + node.displayGroups !== undefined || + node.displayId !== undefined || + (node.plotId != undefined && node.locationIds != undefined) + ) +} + +function nodeHasReports(node: TopologyNode) { + return node.reportDisplay?.reports !== undefined +} + +function nodeHasSchematicStatusDisplay(node: TopologyNode) { + return node.scadaPanelId !== undefined +} + +export function displayTabsForNode(node: TopologyNode, parentNodeId?: string) { + for (const tab of displayTabs) { + const params = { + nodeId: parentNodeId ? [parentNodeId, node.id] : node.id, + } + switch (tab.type) { + case 'map': + tab.active = nodeHasMap(node) + tab.to.params = { ...params, LayerName: node.gridDisplaySelection?.plotId, + } + break + case 'charts': + tab.active = nodeHasCharts(node) + tab.to.params = { ...params } + break + case 'reports': + tab.active = nodeHasReports(node) + tab.to.params = { ...params } + break + case 'schematic-status-display': + tab.active = nodeHasSchematicStatusDisplay(node) + tab.to.params = { ...params, panelId: node.scadaPanelId } + break + } + } + return displayTabs.filter((tab) => tab.active) +} From 679ab79afb50a4d7eef7a96ab9a4aa0a17c9bd8f Mon Sep 17 00:00:00 2001 From: Werner Kramer Date: Fri, 8 Nov 2024 13:44:10 +0100 Subject: [PATCH 3/7] Add support for system monitor in topology --- src/lib/topology/displayTabs.ts | 37 +++++++++--------------- src/lib/topology/nodes.ts | 39 +++++++++++++++++++++----- src/views/SystemMonitorDisplayView.vue | 2 +- 3 files changed, 47 insertions(+), 31 deletions(-) diff --git a/src/lib/topology/displayTabs.ts b/src/lib/topology/displayTabs.ts index 58ba20a9..4ac343ff 100644 --- a/src/lib/topology/displayTabs.ts +++ b/src/lib/topology/displayTabs.ts @@ -1,8 +1,9 @@ import { TopologyNode } from '@deltares/fews-pi-requests' import { RouteLocationNamedRaw } from 'vue-router' +import { nodeHasCharts, nodeHasMap, nodeHasReports, nodeHasSchematicStatusDisplay, nodeHasSystemMonitor } from './nodes' export interface DisplayTab { - type: 'charts' | 'map' | 'reports' | 'schematic-status-display' + type: 'charts' | 'map' | 'reports' | 'schematic-status-display' | 'system-monitor' id: string title: string href?: string @@ -45,30 +46,16 @@ const displayTabs: DisplayTab[] = [ icon: 'mdi-view-dashboard', active: false, }, + { + type: 'system-monitor', + id: 'ssd', + title: 'System Monitor', + to: { name: 'TopologySystemMonitor' }, + icon: 'mdi-view-dashboard', + active: false, + }, ] - - -function nodeHasMap(node: TopologyNode) { - return node.gridDisplaySelection !== undefined || node.filterIds !== undefined -} - -function nodeHasCharts(node: TopologyNode) { - return ( - node.displayGroups !== undefined || - node.displayId !== undefined || - (node.plotId != undefined && node.locationIds != undefined) - ) -} - -function nodeHasReports(node: TopologyNode) { - return node.reportDisplay?.reports !== undefined -} - -function nodeHasSchematicStatusDisplay(node: TopologyNode) { - return node.scadaPanelId !== undefined -} - export function displayTabsForNode(node: TopologyNode, parentNodeId?: string) { for (const tab of displayTabs) { const params = { @@ -92,6 +79,10 @@ export function displayTabsForNode(node: TopologyNode, parentNodeId?: string) { tab.active = nodeHasSchematicStatusDisplay(node) tab.to.params = { ...params, panelId: node.scadaPanelId } break + case 'system-monitor': + tab.active = nodeHasSystemMonitor(node) + tab.to.params = { ...params } + break } } return displayTabs.filter((tab) => tab.active) diff --git a/src/lib/topology/nodes.ts b/src/lib/topology/nodes.ts index 71dabc39..28ec58e7 100644 --- a/src/lib/topology/nodes.ts +++ b/src/lib/topology/nodes.ts @@ -115,18 +115,43 @@ function topologyNodeIsVisible(node: TopologyNode): boolean { } function hasSupportedDisplay(node: TopologyNode): boolean { - if (node.scadaPanelId !== undefined) return true + if ( + nodeHasSchematicStatusDisplay(node) || + nodeHasMap(node) || + nodeHasCharts(node) || + nodeHasReports(node) || + nodeHasSystemMonitor(node) + ) + return true if ( node.filterIds !== undefined && node.filterIds.length == 1 && node.dataDownloadDisplay !== undefined ) return true - if (node.plotId != undefined && node.locationIds != undefined) return true - if (node.filterIds !== undefined && node.filterIds.length > 0) return true - if (node.gridDisplaySelection !== undefined) return true - if (node.displayId !== undefined) return true - if (node.displayGroups !== undefined && node.displayGroups.length > 0) - return true return false } + +export function nodeHasMap(node: TopologyNode) { + return node.gridDisplaySelection !== undefined || node.filterIds !== undefined +} + +export function nodeHasCharts(node: TopologyNode) { + return ( + node.displayGroups !== undefined || + node.displayId !== undefined || + (node.plotId != undefined && node.locationIds != undefined) + ) +} + +export function nodeHasReports(node: TopologyNode) { + return node.reportDisplay?.reports !== undefined +} + +export function nodeHasSchematicStatusDisplay(node: TopologyNode) { + return node.scadaPanelId !== undefined +} + +export function nodeHasSystemMonitor(node: TopologyNode) { + return node.mainPanel !== undefined && node.mainPanel === 'system monitor' +} diff --git a/src/views/SystemMonitorDisplayView.vue b/src/views/SystemMonitorDisplayView.vue index 89f9bf25..97f782d4 100644 --- a/src/views/SystemMonitorDisplayView.vue +++ b/src/views/SystemMonitorDisplayView.vue @@ -1,5 +1,5 @@