Skip to content

Commit

Permalink
Merge pull request #6773 from OpenNMS/jira/NMS-16116-node-structure-h…
Browse files Browse the repository at this point in the history
…andle-query-strings

NMS-16116: Update node structure page to accept query strings
  • Loading branch information
synqotik authored Oct 17, 2023
2 parents 582045a + a6c9a78 commit f9d45c3
Show file tree
Hide file tree
Showing 15 changed files with 953 additions and 811 deletions.
4 changes: 2 additions & 2 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"@types/leaflet.markercluster": "^1.5.1",
"@types/lodash": "^4.14.196",
"@types/marked": "^4.0.3",
"@types/node": "18",
"@types/node": ">=18",
"@types/splitpanes": "^2.2.1",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
Expand All @@ -95,7 +95,7 @@
"eslint-plugin-vue": "^9.16.1",
"happy-dom": "^9.20.3",
"prettier": "^2.8.8",
"typescript": "^4.9.4",
"typescript": "^5.2.2",
"unplugin-auto-import": "^0.12.1",
"unplugin-vue-components": "^0.22.12",
"vite": "^4.3.9",
Expand Down
4 changes: 4 additions & 0 deletions ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,21 @@ import { useAuthStore } from '@/stores/authStore'
import { useInfoStore } from '@/stores/infoStore'
import { usePluginStore } from '@/stores/pluginStore'
import { useMenuStore } from '@/stores/menuStore'
import { useNodeStructureStore } from '@/stores/nodeStructureStore'
const authStore = useAuthStore()
const infoStore = useInfoStore()
const menuStore = useMenuStore()
const nodeStructureStore = useNodeStructureStore()
const pluginStore = usePluginStore()
onMounted(() => {
authStore.getWhoAmI()
infoStore.getInfo()
menuStore.getMainMenu()
menuStore.getNotificationSummary()
nodeStructureStore.getCategories()
nodeStructureStore.getMonitoringLocations()
pluginStore.getPlugins()
})
</script>
Expand Down
5 changes: 4 additions & 1 deletion ui/src/components/Nodes/ManagementIPTooltipCell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
import { IpInterface, Node } from '@/types'
import { FeatherTooltip, PointerAlignment, PopoverPlacement } from '@featherds/tooltip'
import { PropType } from 'vue'
import { IpInterfaceInfo, getBestIpInterfaceForNode } from './utils'
import { IpInterfaceInfo } from '@/types'
import { useIpInterfaceQuery } from '@/components/Nodes/hooks/useIpInterfaceQuery'
const { getBestIpInterfaceForNode } = useIpInterfaceQuery()
const props = defineProps({
computeNodeIpInterfaceLink: {
Expand Down
4 changes: 3 additions & 1 deletion ui/src/components/Nodes/NodeDetailsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
<script setup lang="ts">
import { PropType } from 'vue'
import { FeatherDialog } from '@featherds/dialog'
import { getBestIpInterfaceForNode, hasEgressFlow, hasIngressFlow } from './utils'
import { hasEgressFlow, hasIngressFlow } from './utils'
import { useIpInterfaceQuery } from '@/components/Nodes/hooks/useIpInterfaceQuery'
import { useNodeStore } from '@/stores/nodeStore'
import { Node } from '@/types'
Expand Down Expand Up @@ -49,6 +50,7 @@ const labels = reactive({
const EMPTY = '--'
const nodeStore = useNodeStore()
const { getBestIpInterfaceForNode } = useIpInterfaceQuery()
const nodeItems = computed(() => {
const ipLabel = getBestIpInterfaceForNode(props.node?.id || '', nodeStore.nodeToIpInterfaceMap)
Expand Down
92 changes: 41 additions & 51 deletions ui/src/components/Nodes/NodeStructurePanel.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<template>
<h1 class="title">Filtering</h1>
<div class="button-panel">
<FeatherButton primary class="category-btn" @click="onClearAll" :disabled="!selectedCount">Clear All</FeatherButton>
<FeatherButton primary class="category-btn" @click="onClearAll" :disabled="!isAnyFilterSelected">Clear All</FeatherButton>
</div>
<FeatherExpansionPanel>
<template v-slot:title>
<template #title>
<div v-if="selectedCategoryCount">
<span>{{ `Categories (${selectedCategoryCount})` }}</span>
<FeatherButton icon="Clear" @click="onClearCategories">
Expand All @@ -13,32 +13,34 @@
</div>
<div v-else>Categories</div>
</template>
<div class="category-button-group">
<FeatherButton
class="switcher-button"
:primary="categoryMode === SetOperator.Union"
:secondary="categoryMode !== SetOperator.Union"
@click="categoryModeUpdated(SetOperator.Union)"
>Any</FeatherButton>
<FeatherButton
class="switcher-button"
:primary="categoryMode === SetOperator.Intersection"
:secondary="categoryMode !== SetOperator.Intersection"
@click="categoryModeUpdated(SetOperator.Intersection)"
>All</FeatherButton>
</div>
<FeatherList class="category-list">
<FeatherListItem
v-for="cat of categories"
:selected="isCategorySelected(cat)"
:key="cat.name"
@click="onCategoryClick(cat)">
{{ cat.name }}
</FeatherListItem>
</FeatherList>
<template #default>
<div class="category-button-group">
<FeatherButton
class="switcher-button"
:primary="categoryMode === SetOperator.Union"
:secondary="categoryMode !== SetOperator.Union"
@click="categoryModeUpdated(SetOperator.Union)"
>Any</FeatherButton>
<FeatherButton
class="switcher-button"
:primary="categoryMode === SetOperator.Intersection"
:secondary="categoryMode !== SetOperator.Intersection"
@click="categoryModeUpdated(SetOperator.Intersection)"
>All</FeatherButton>
</div>
<FeatherList class="category-list">
<FeatherListItem
v-for="cat of nodeStructureStore.categories"
:selected="isCategorySelected(cat)"
:key="cat.name"
@click="onCategoryClick(cat)">
{{ cat.name }}
</FeatherListItem>
</FeatherList>
</template>
</FeatherExpansionPanel>
<FeatherExpansionPanel>
<template v-slot:title>
<template #title>
<div v-if="selectedFlowCount">
<span>{{ `Flows (${selectedFlowCount})` }}</span>
<FeatherButton icon="Clear" @click="onClearFlows">
Expand All @@ -58,7 +60,7 @@
</FeatherList>
</FeatherExpansionPanel>
<FeatherExpansionPanel>
<template v-slot:title>
<template #title>
<div v-if="selectedLocationCount">
<span>{{ `Locations (${selectedLocationCount})` }}</span>
<FeatherButton icon="Clear" @click="onClearLocations">
Expand Down Expand Up @@ -107,18 +109,14 @@ import { Category, MonitoringLocation, SetOperator } from '@/types'
const nodeStructureStore = useNodeStructureStore()
const clearIcon = ref(ClearIcon)
const categories = computed<Category[]>(() => nodeStructureStore.categories)
const selectedCategories = computed<Category[]>(() => nodeStructureStore.selectedCategories)
const flowTypes = computed<string[]>(() => ['Ingress', 'Egress'])
const selectedFlows = computed<string[]>(() => nodeStructureStore.selectedFlows)
const categoryMode = computed(() => nodeStructureStore.categoryMode)
const categoryMode = computed(() => nodeStructureStore.queryFilter.categoryMode)
const locations = computed<MonitoringLocation[]>(() => nodeStructureStore.monitoringLocations)
const selectedLocations = computed<MonitoringLocation[]>(() => nodeStructureStore.selectedMonitoringLocations)
const selectedCategoryCount = computed<number>(() => selectedCategories.value?.length || 0)
const selectedFlowCount = computed<number>(() => selectedFlows.value?.length || 0)
const selectedLocationCount = computed<number>(() => selectedLocations.value?.length || 0)
const selectedCount = computed<boolean>(() => selectedCategoryCount.value > 0 || selectedFlowCount.value > 0 || selectedLocationCount.value > 0)
const selectedCategoryCount = computed<number>(() => nodeStructureStore.queryFilter.selectedCategories?.length || 0)
const selectedFlowCount = computed<number>(() => nodeStructureStore.queryFilter.selectedFlows?.length || 0)
const selectedLocationCount = computed<number>(() => nodeStructureStore.queryFilter.selectedMonitoringLocations?.length || 0)
const isAnyFilterSelected = computed<boolean>(() => nodeStructureStore.queryFilter.searchTerm?.length > 0 || selectedCategoryCount.value > 0 || selectedFlowCount.value > 0 || selectedLocationCount.value > 0)
const metaSearchString = ref()
const loading = ref(false)
Expand All @@ -142,15 +140,15 @@ const categoryModeUpdated = (val: any) => {
}
const isCategorySelected = (cat: Category) => {
return selectedCategories.value.some(c => c.id === cat.id)
return nodeStructureStore.queryFilter.selectedCategories.some(c => c.id === cat.id)
}
const isFlowSelected = (flow: string) => {
return selectedFlows.value.some(f => f === flow)
return nodeStructureStore.queryFilter.selectedFlows.some(f => f === flow)
}
const isLocationSelected = (loc: MonitoringLocation) => {
return selectedLocations.value.some(x => x.name === loc.name)
return nodeStructureStore.queryFilter.selectedMonitoringLocations.some(x => x.name === loc.name)
}
const onClearCategories = () => {
Expand All @@ -166,10 +164,7 @@ const onClearLocations = () => {
}
const onClearAll = () => {
onClearCategories()
categoryModeUpdated(SetOperator.Union)
onClearFlows()
onClearLocations()
nodeStructureStore.clearAllFilters(SetOperator.Union)
}
/**
Expand All @@ -190,24 +185,19 @@ const getNewSelection = <T,>(item: T, isSelected: boolean, existingItems: T[], d
}
const onCategoryClick = (cat: Category) => {
const newSelection = getNewSelection(cat, isCategorySelected(cat), selectedCategories.value, c => c.id !== cat.id)
const newSelection = getNewSelection(cat, isCategorySelected(cat), nodeStructureStore.queryFilter.selectedCategories, c => c.id !== cat.id)
nodeStructureStore.setSelectedCategories(newSelection)
}
const onFlowClick = (flow: string) => {
const newSelection = getNewSelection(flow, isFlowSelected(flow), selectedFlows.value, f => f !== flow)
const newSelection = getNewSelection(flow, isFlowSelected(flow), nodeStructureStore.queryFilter.selectedFlows, f => f !== flow)
nodeStructureStore.setSelectedFlows(newSelection)
}
const onLocationClick = (loc: MonitoringLocation) => {
const newSelection = getNewSelection(loc, isLocationSelected(loc), selectedLocations.value, x => x.name !== loc.name)
const newSelection = getNewSelection(loc, isLocationSelected(loc), nodeStructureStore.queryFilter.selectedMonitoringLocations, x => x.name !== loc.name)
nodeStructureStore.setSelectedMonitoringLocations(newSelection)
}
onMounted(() => {
nodeStructureStore.getCategories()
nodeStructureStore.getMonitoringLocations()
})
</script>

<style lang="scss" scoped>
Expand Down
Loading

0 comments on commit f9d45c3

Please sign in to comment.