Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Put topologyNodes in store #1137

Merged
merged 6 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions src/lib/topology/createTopologyHashMaps.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { describe, it, expect } from 'vitest'
import { createTopologyHashMaps } from './createTopologyHashMaps'

describe('createTopologyHashMap', () => {
it('should create a hash map from a valid topology', () => {
const topology = [
{ id: '1', name: 'Node 1' },
{ id: '2', name: 'Node 2' },
{ id: '3', name: 'Node 3' },
]
const result = createTopologyHashMaps(topology)
expect(result).toEqual({
childIdToParentNodeMap: new Map(),
idToNodeMap: new Map(
Object.entries({
'1': { id: '1', name: 'Node 1' },
'2': { id: '2', name: 'Node 2' },
'3': { id: '3', name: 'Node 3' },
}),
),
})
})

it('should return an empty maps for an empty topology', () => {
const topology: any[] = []
const result = createTopologyHashMaps(topology)
expect(result).toEqual({
childIdToParentNodeMap: new Map(),
idToNodeMap: new Map(),
})
})

it('should handle topology with duplicate ids', () => {
const topology = [
{ id: '1', name: 'Node 1' },
{ id: '1', name: 'Node 1 Duplicate' },
{ id: '3', name: 'Node 3' },
]
const result = createTopologyHashMaps(topology)
expect(result).toEqual({
childIdToParentNodeMap: new Map(),
idToNodeMap: new Map(
Object.entries({
'1': { id: '1', name: 'Node 1 Duplicate' },
'3': { id: '3', name: 'Node 3' },
}),
),
})
})

it('should handle a nested topology', () => {
const topology = [
{ id: '1', name: 'Node 1' },
{ id: '2', name: 'Node 2', topologyNodes: [{ id: '3', name: 'Node 3' }] },
{ id: '4', name: 'Node 4' },
]
const result = createTopologyHashMaps(topology)
expect(result).toEqual({
childIdToParentNodeMap: new Map(
Object.entries({
'3': {
id: '2',
name: 'Node 2',
topologyNodes: [{ id: '3', name: 'Node 3' }],
},
}),
),
idToNodeMap: new Map(
Object.entries({
'1': { id: '1', name: 'Node 1' },
'2': {
id: '2',
name: 'Node 2',
topologyNodes: [{ id: '3', name: 'Node 3' }],
},
'3': { id: '3', name: 'Node 3' },
'4': { id: '4', name: 'Node 4' },
}),
),
})
})

it('should handle a deeply nested topology', () => {
const topology = [
{ id: '1', name: 'Node 1' },
{
id: '2',
name: 'Node 2',
topologyNodes: [
{
id: '3',
name: 'Node 3',
topologyNodes: [{ id: '4', name: 'Node 4' }],
},
],
},
{ id: '5', name: 'Node 5' },
]
const result = createTopologyHashMaps(topology)
expect(result).toEqual({
childIdToParentNodeMap: new Map(
Object.entries({
'3': {
id: '2',
name: 'Node 2',
topologyNodes: [
{
id: '3',
name: 'Node 3',
topologyNodes: [{ id: '4', name: 'Node 4' }],
},
],
},
'4': {
id: '3',
name: 'Node 3',
topologyNodes: [{ id: '4', name: 'Node 4' }],
},
}),
),
idToNodeMap: new Map(
Object.entries({
'1': { id: '1', name: 'Node 1' },
'2': {
id: '2',
name: 'Node 2',
topologyNodes: [
{
id: '3',
name: 'Node 3',
topologyNodes: [{ id: '4', name: 'Node 4' }],
},
],
},
'3': {
id: '3',
name: 'Node 3',
topologyNodes: [{ id: '4', name: 'Node 4' }],
},
'4': { id: '4', name: 'Node 4' },
'5': { id: '5', name: 'Node 5' },
}),
),
})
})
})
41 changes: 41 additions & 0 deletions src/lib/topology/createTopologyHashMaps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { TopologyNode } from '@deltares/fews-pi-requests'

/**
* Creates hash maps for topology nodes.
*
* This function generates two hash maps:
* 1. idToNodeMap: Maps node IDs to their corresponding TopologyNode objects.
* 2. childIdToParentNodeMap: Maps child node IDs to their parent node.
*
* @param {TopologyNode[] | undefined} nodes - An array of TopologyNode objects or undefined.
* @returns {{ idToNodeMap: Map<string, TopologyNode>, childIdToParentNodeMap: Map<string, string> }} - An object containing the two hash maps.
*/
export function createTopologyHashMaps(nodes: TopologyNode[] | undefined): {
idToNodeMap: Map<string, TopologyNode>
childIdToParentNodeMap: Map<string, TopologyNode>
} {
const idToNodeMap = new Map<string, TopologyNode>()
const childIdToParentNodeMap = new Map<string, TopologyNode>()

function recursivelyFillMaps(nodes: TopologyNode[]) {
for (const node of nodes) {
idToNodeMap.set(node.id, node)

if (node.topologyNodes) {
node.topologyNodes.forEach((childNode) => {
childIdToParentNodeMap.set(childNode.id, node)
})
recursivelyFillMaps(node.topologyNodes)
}
}
}

if (nodes) {
recursivelyFillMaps(nodes)
}

return {
idToNodeMap,
childIdToParentNodeMap,
}
}
28 changes: 28 additions & 0 deletions src/lib/topology/getTopologyNodes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { configManager } from '@/services/application-config/index.ts'
import {
PiWebserviceProvider,
type TopologyNode,
} from '@deltares/fews-pi-requests'
import { createTransformRequestFn } from '@/lib/requests/transformRequest'

/**
* Fetch the topology nodes from the FEWS web services.
*
* @returns {Promise<TopologyNode[]>} - An array of TopologyNode objects.
*/
export async function getTopologyNodes(): Promise<TopologyNode[]> {
const baseUrl = configManager.get('VITE_FEWS_WEBSERVICES_URL')
const piProvider = new PiWebserviceProvider(baseUrl, {
transformRequestFn: createTransformRequestFn(),
})

let nodes: TopologyNode[] = []
try {
const response = await piProvider.getTopologyNodes()
nodes = response.topologyNodes
} catch (error) {
error = 'error-loading'
}

return nodes
}
53 changes: 0 additions & 53 deletions src/lib/topology/index.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/services/application-config/ApplicationConfigManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { UserManagerSettings } from 'oidc-client-ts'
import { ApplicationConfig } from './ApplicationConfig'
import oidcSettings from '../authentication/oidcSettings.ts'
import { getOidcSettings } from '@/services/authentication/oidcSettings'

export class ApplicationConfigManager {
_config!: ApplicationConfig
Expand Down Expand Up @@ -30,7 +30,7 @@ export class ApplicationConfigManager {

getUserManagerSettings(): UserManagerSettings {
return {
...oidcSettings,
...getOidcSettings(),
...{
authority: this.get('VITE_AUTH_AUTHORITY'),
client_id: this.get('VITE_AUTH_ID'),
Expand Down
29 changes: 15 additions & 14 deletions src/services/authentication/oidcSettings.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { UserManagerSettings } from 'oidc-client-ts'

const baseUrl = window.location.origin + import.meta.env.BASE_URL
const oidcSettings: UserManagerSettings = {
authority: `${import.meta.env.VITE_AUTH_AUTHORITY}`,
metadataUrl: `${import.meta.env.VITE_AUTH_METADATA_URL}`,
client_id: `${import.meta.env.VITE_AUTH_ID}`,
redirect_uri: `${baseUrl}auth/callback`,
silent_redirect_uri: `${baseUrl}auth/silent`,
response_type: `code`,
scope: `${import.meta.env.VITE_AUTH_SCOPE}`,
post_logout_redirect_uri: `${baseUrl}auth/logout`,
monitorSession: false,
automaticSilentRenew: true,
export function getOidcSettings() {
const baseUrl = window.location.origin + import.meta.env.BASE_URL
const oidcSettings: UserManagerSettings = {
authority: `${import.meta.env.VITE_AUTH_AUTHORITY}`,
metadataUrl: `${import.meta.env.VITE_AUTH_METADATA_URL}`,
client_id: `${import.meta.env.VITE_AUTH_ID}`,
redirect_uri: `${baseUrl}auth/callback`,
silent_redirect_uri: `${baseUrl}auth/silent`,
response_type: `code`,
scope: `${import.meta.env.VITE_AUTH_SCOPE}`,
post_logout_redirect_uri: `${baseUrl}auth/logout`,
monitorSession: false,
automaticSilentRenew: true,
}
return oidcSettings
}

export default oidcSettings
3 changes: 1 addition & 2 deletions src/services/useFilterLocations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import type { FeatureCollection, Geometry } from 'geojson'
import type { Location } from '@deltares/fews-pi-requests'
import type { Ref, MaybeRefOrGetter, ShallowRef } from 'vue'
import { ref, watchEffect, shallowRef, toValue } from 'vue'

import {
convertGeoJsonToFewsPiLocation,
fetchLocationsAsGeoJson,
} from '@/lib/topology'
} from '@/lib/topology/locations'

export interface UseFilterLocationsReturn {
error: Ref<any>
Expand Down
Loading
Loading