@gen-epix/ui-client-casedb 4.3.0 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/_chunks/Dashboard.js +613 -666
  2. package/dist/_chunks/Dashboard.js.map +1 -1
  3. package/dist/_chunks/LegendaItem.js.map +1 -1
  4. package/dist/_chunks/UploadUtil.js +4 -6
  5. package/dist/_chunks/UploadUtil.js.map +1 -1
  6. package/dist/_chunks/_baseClone.js +1 -1
  7. package/dist/_chunks/_baseClone.js.map +1 -1
  8. package/dist/_chunks/cloneDeep.js +1 -1
  9. package/dist/_chunks/cloneDeep.js.map +1 -1
  10. package/dist/_chunks/esm.js +93 -101
  11. package/dist/_chunks/esm.js.map +1 -1
  12. package/dist/_chunks/react.js +1 -1
  13. package/dist/_chunks/react.js.map +1 -1
  14. package/dist/_chunks/shallow.js +2 -2
  15. package/dist/_chunks/shallow.js.map +1 -1
  16. package/dist/_chunks/sync.js +4 -4
  17. package/dist/_chunks/sync.js.map +1 -1
  18. package/dist/_chunks/vanilla.js +1 -1
  19. package/dist/_chunks/vanilla.js.map +1 -1
  20. package/dist/_chunks/yup.js +2 -2
  21. package/dist/_chunks/yup.js.map +1 -1
  22. package/dist/components/ui/ContextMenu/index.js +1 -1
  23. package/dist/components/ui/ContextMenu/index.js.map +1 -1
  24. package/dist/components/ui/CreateEventDialog/index.js +1 -1
  25. package/dist/components/ui/CreateEventDialog/index.js.map +1 -1
  26. package/dist/components/ui/HistogramWidget/index.js +1 -1
  27. package/dist/components/ui/HistogramWidget/index.js.map +1 -1
  28. package/dist/components/ui/PanelSeparator/index.js +50 -2
  29. package/dist/components/ui/PanelSeparator/index.js.map +1 -0
  30. package/dist/pages/CasesDetailPage/index.js +16 -16
  31. package/dist/pages/ColsAdminPage/index.js +77 -77
  32. package/dist/pages/ColsAdminPage/index.js.map +1 -1
  33. package/dist/pages/ConceptsAdminPage/index.js +31 -31
  34. package/dist/pages/DataCollectionVisualizationPage/index.js +1 -1
  35. package/dist/pages/DataCollectionVisualizationPage/index.js.map +1 -1
  36. package/dist/pages/DimsAdminPage/index.js +46 -46
  37. package/dist/pages/EventsDetailPage/index.js +18 -18
  38. package/dist/pages/RefColsAdminPage/index.js +94 -94
  39. package/dist/pages/RegionSetShapesAdminPage/index.js +26 -26
  40. package/dist/pages/RegionsAdminPage/index.js +33 -33
  41. package/dist/pages/UserEffectiveRightsAdminPage/index.js +56 -56
  42. package/dist/pages/UserEffectiveRightsAdminPage/index.js.map +1 -1
  43. package/dist/pages/UserEffectiveRightsTesterAdminPage/index.js +45 -45
  44. package/dist/pages/UserEffectiveRightsTesterAdminPage/index.js.map +1 -1
  45. package/dist/utils/CaseDbStandardConfigUtil/index.js +1 -5
  46. package/dist/utils/CaseDbStandardConfigUtil/index.js.map +1 -1
  47. package/dist/utils/MapUtil/index.js +1 -1
  48. package/dist/utils/MapUtil/index.js.map +1 -1
  49. package/package.json +17 -12
  50. package/dist/_chunks/PanelSeparator.js +0 -1666
  51. package/dist/_chunks/PanelSeparator.js.map +0 -1
  52. package/dist/_chunks/chunk-OB3PAWPO.js +0 -1162
  53. package/dist/_chunks/chunk-OB3PAWPO.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/pages/DataCollectionVisualizationPage/DataCollectionVisualizationPage.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next';\nimport {\n Autocomplete,\n Box,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n useTheme,\n} from '@mui/material';\nimport EChartsReact from 'echarts-for-react';\nimport {\n dispose,\n getInstanceByDom,\n init,\n use as registerECharts,\n} from 'echarts/core';\nimport { CanvasRenderer } from 'echarts/renderers';\nimport { TooltipComponent } from 'echarts/components';\nimport { GraphChart } from 'echarts/charts';\nimport {\n useCallback,\n useMemo,\n useState,\n} from 'react';\nimport type {\n MouseEvent as ReactMouseEvent,\n SyntheticEvent,\n} from 'react';\nimport type {\n EChartsOption,\n GraphSeriesOption,\n} from 'echarts';\nimport type { AutocompleteRenderInputParams } from '@mui/material/Autocomplete';\nimport type { CaseDbOrganizationAccessCasePolicy } from '@gen-epix/api-casedb';\nimport { LoadableUtil } from '@gen-epix/ui-client-common/utils/LoadableUtil';\nimport { PageContainer } from '@gen-epix/ui-client-common/components/ui/PageContainer';\nimport { ResponseHandler } from '@gen-epix/ui-client-common/components/ui/ResponseHandler';\nimport { useOrganizationMapQuery } from '@gen-epix/ui-client-common/dataHooks/useOrganizationsQuery';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\nimport { StringUtil } from '@gen-epix/ui-core/utils/StringUtil';\nimport { useArray } from '@gen-epix/ui-core/hooks/useArray';\n\nimport { useDataCollectionsMapQuery } from '../../dataHooks/useDataCollectionsQuery';\nimport { useOrganizationAccessCasePoliciesQuery } from '../../dataHooks/useOrganizationAccessCasePoliciesQuery';\nimport { useOrganizationShareCasePoliciesQuery } from '../../dataHooks/useOrganizationShareCasePoliciesQuery';\nimport { EffectiveRightsUtil } from '../../utils/EffectiveRightsUtil';\n\nconst echartsCore = {\n dispose,\n getInstanceByDom,\n init,\n};\n\nregisterECharts([TooltipComponent, CanvasRenderer, GraphChart]);\n\ntype AccessLink = {\n accessPolicyCount: number;\n accessRights: AccessRightsSummary;\n dataCollectionName: string;\n lineStyle: NonNullable<GraphSeriesOption['lineStyle']>;\n linkType: 'access';\n organizationName: string;\n sharePolicyCount: number;\n source: string;\n sourceDataCollectionNames: string[];\n target: string;\n value: number;\n};\n\ntype AccessRightsSummary = Pick<CaseDbOrganizationAccessCasePolicy, 'add_case_set' | 'add_case' | 'is_private' | 'read_case_set' | 'remove_case_set' | 'remove_case' | 'write_case_set'>;\n\ntype Category = {\n name: string;\n};\n\ntype Graph = {\n categories: Category[];\n links: Link[];\n nodes: Node[];\n totalAccessLinks: number;\n totalDataCollections: number;\n totalOrganizations: number;\n totalShareLinks: number;\n zoom: number;\n};\n\ntype GraphTooltipParams = {\n data: Link | Node;\n dataType?: 'edge' | 'node';\n};\n\ntype Link = AccessLink | ShareLink;\n\ntype Node = {\n accessLinkCount: number;\n category: number;\n id: string;\n itemStyle: {\n borderColor: string;\n borderWidth: number;\n color: string;\n };\n label: NonNullable<GraphSeriesOption['label']>;\n name: string;\n nodeType: 'dataCollection' | 'organization';\n shareInCount: number;\n shareOutCount: number;\n symbol: 'circle' | 'roundRect';\n symbolSize: number;\n value: number;\n x: number;\n y: number;\n};\n\ntype SelectionOption = {\n label: string;\n value: string;\n};\n\ntype SelectionType = 'dataCollection' | 'organization';\n\ntype ShareLink = {\n lineStyle: NonNullable<GraphSeriesOption['lineStyle']>;\n linkType: 'share';\n organizationNames: string[];\n sharePolicyCount: number;\n source: string;\n sourceDataCollectionName: string;\n target: string;\n targetDataCollectionName: string;\n value: number;\n};\n\nconst EMPTY_GRAPH: Graph = {\n categories: [],\n links: [],\n nodes: [],\n totalAccessLinks: 0,\n totalDataCollections: 0,\n totalOrganizations: 0,\n totalShareLinks: 0,\n zoom: 1,\n};\n\nconst GRAPH_LAYOUT = {\n bottomPadding: 72,\n fitZoomSafetyFactor: 0.94,\n labelPadding: 12,\n nodeLabelWidth: 220,\n organizationX: 120,\n rowGap: 68,\n singleRowVerticalOffset: 96,\n sourceDataCollectionX: 1060,\n targetAndSourceDataCollectionX: 820,\n targetDataCollectionX: 620,\n topPadding: 72,\n viewportHorizontalPadding: 24,\n viewportVerticalPadding: 24,\n} as const;\n\nexport const DataCollectionVisualizationPage = () => {\n const { t } = useTranslation();\n const theme = useTheme();\n const [selectionType, setSelectionType] = useState<SelectionType>('organization');\n const [selectedEntityId, setSelectedEntityId] = useState<string>(null);\n const dataCollectionMapQuery = useDataCollectionsMapQuery();\n const organizationMapQuery = useOrganizationMapQuery();\n const organizationAccessCasePoliciesQuery = useOrganizationAccessCasePoliciesQuery(policies => policies.filter(policy => policy.is_active));\n const organizationShareCasePoliciesQuery = useOrganizationShareCasePoliciesQuery(policies => policies.filter(policy => policy.is_active));\n\n const loadables = useArray([\n dataCollectionMapQuery,\n organizationMapQuery,\n organizationAccessCasePoliciesQuery,\n organizationShareCasePoliciesQuery,\n ]);\n\n const organizationOptions = useMemo<SelectionOption[]>(() => {\n return Array.from(organizationMapQuery.map.values())\n .map(organization => ({\n label: organization.name,\n value: organization.id,\n }))\n .sort((a, b) => StringUtil.advancedSortComperator(a.label, b.label));\n }, [organizationMapQuery.map]);\n\n const dataCollectionOptions = useMemo<SelectionOption[]>(() => {\n return Array.from(dataCollectionMapQuery.map.values())\n .map(dataCollection => ({\n label: dataCollection.name,\n value: dataCollection.id,\n }))\n .sort((a, b) => StringUtil.advancedSortComperator(a.label, b.label));\n }, [dataCollectionMapQuery.map]);\n\n const selectionOptions = useMemo(() => {\n return selectionType === 'organization' ? organizationOptions : dataCollectionOptions;\n }, [dataCollectionOptions, organizationOptions, selectionType]);\n\n const selectedOption = useMemo(() => {\n return selectionOptions.find(option => option.value === selectedEntityId) ?? null;\n }, [selectedEntityId, selectionOptions]);\n\n const selectionLabel = selectionType === 'organization' ? t`Organization` : t`Data collection`;\n const hasSelection = !!selectedEntityId;\n\n const onSelectionTypeChange = useCallback((_event: ReactMouseEvent<HTMLElement>, nextSelectionType: null | SelectionType) => {\n if (!nextSelectionType || nextSelectionType === selectionType) {\n return;\n }\n\n setSelectionType(nextSelectionType);\n setSelectedEntityId(null);\n }, [selectionType]);\n\n const getSelectionOptionLabel = useCallback((option: SelectionOption) => {\n return option.label;\n }, []);\n\n const isSelectionOptionEqualToValue = useCallback((option: SelectionOption, value: SelectionOption) => {\n return option.value === value.value;\n }, []);\n\n const onSelectionChange = useCallback((_event: SyntheticEvent, nextOption: null | SelectionOption) => {\n setSelectedEntityId(nextOption?.value ?? null);\n }, []);\n\n const renderSelectionInput = useCallback((params: AutocompleteRenderInputParams) => {\n return (\n <TextField\n {...params}\n label={selectionLabel}\n required\n size={'small'}\n />\n );\n }, [selectionLabel]);\n\n const graph = useMemo<Graph>(() => {\n if (LoadableUtil.isSomeLoading(loadables)) {\n return EMPTY_GRAPH;\n }\n\n if (!selectedEntityId) {\n return EMPTY_GRAPH;\n }\n\n const categories: Category[] = [\n {\n name: t`Organization`,\n },\n {\n name: t`Data collection`,\n },\n ];\n\n const organizationNodeColor = theme.palette.primary.main;\n const organizationNodeBorderColor = theme.palette.primary.dark;\n const dataCollectionNodeColor = theme.palette.secondary.main;\n const dataCollectionNodeBorderColor = theme.palette.secondary.dark;\n const accessLinkColor = theme.palette.primary.light;\n const shareLinkColor = theme.palette.warning.main;\n\n const policyGroups = EffectiveRightsUtil.getOrganizationPolicyGroups({\n organizationAccessCasePolicies: organizationAccessCasePoliciesQuery.data,\n organizationShareCasePolicies: organizationShareCasePoliciesQuery.data,\n });\n\n const filteredPolicyGroups = policyGroups.filter(policyGroup => {\n if (selectionType === 'organization') {\n return policyGroup.organization_id === selectedEntityId;\n }\n\n return policyGroup.data_collection_id === selectedEntityId\n || policyGroup.share_case_policies.some(policy => policy.from_data_collection_id === selectedEntityId);\n });\n\n const nodesById = new Map<string, Omit<Node, 'accessLinkCount' | 'label' | 'shareInCount' | 'shareOutCount' | 'symbolSize' | 'value' | 'x' | 'y'>>();\n const nodeStats = new Map<string, Pick<Node, 'accessLinkCount' | 'shareInCount' | 'shareOutCount'>>();\n const accessLinks: AccessLink[] = [];\n const shareLinksByKey = new Map<string, {\n organizationNames: Set<string>;\n sharePolicyCount: number;\n source: string;\n sourceDataCollectionName: string;\n target: string;\n targetDataCollectionName: string;\n }>();\n\n const buildNodeLabel = (position: 'left' | 'right'): Node['label'] => {\n return {\n color: theme.palette.text.primary,\n distance: 8,\n fontSize: 12,\n formatter: '{b}',\n overflow: 'truncate',\n position,\n show: true,\n width: GRAPH_LAYOUT.nodeLabelWidth,\n };\n };\n\n const ensureNode = (params: {\n borderColor: string;\n category: number;\n color: string;\n id: string;\n name: string;\n nodeType: Node['nodeType'];\n symbol: Node['symbol'];\n }) => {\n if (nodesById.has(params.id)) {\n return;\n }\n\n nodesById.set(params.id, {\n category: params.category,\n id: params.id,\n itemStyle: {\n borderColor: params.borderColor,\n borderWidth: 1.5,\n color: params.color,\n },\n name: params.name,\n nodeType: params.nodeType,\n symbol: params.symbol,\n });\n };\n\n const incrementNodeStat = (nodeId: string, key: keyof Pick<Node, 'accessLinkCount' | 'shareInCount' | 'shareOutCount'>) => {\n const currentStats = nodeStats.get(nodeId) ?? {\n accessLinkCount: 0,\n shareInCount: 0,\n shareOutCount: 0,\n };\n\n currentStats[key] += 1;\n nodeStats.set(nodeId, currentStats);\n };\n\n filteredPolicyGroups.forEach(policyGroup => {\n const organizationNodeId = `organization:${policyGroup.organization_id}`;\n const targetDataCollectionNodeId = `dataCollection:${policyGroup.data_collection_id}`;\n const organizationName = organizationMapQuery.map.get(policyGroup.organization_id)?.name ?? policyGroup.organization_id;\n const targetDataCollectionName = dataCollectionMapQuery.map.get(policyGroup.data_collection_id)?.name ?? policyGroup.data_collection_id;\n const sourceDataCollectionNames = Array.from(new Set(policyGroup.share_case_policies.map(policy => dataCollectionMapQuery.map.get(policy.from_data_collection_id)?.name ?? policy.from_data_collection_id))).sort();\n\n const accessRights = policyGroup.access_case_policies.reduce<AccessRightsSummary>((summary, policy) => {\n return {\n add_case: summary.add_case || policy.add_case,\n add_case_set: summary.add_case_set || policy.add_case_set,\n is_private: summary.is_private || policy.is_private,\n read_case_set: summary.read_case_set || policy.read_case_set,\n remove_case: summary.remove_case || policy.remove_case,\n remove_case_set: summary.remove_case_set || policy.remove_case_set,\n write_case_set: summary.write_case_set || policy.write_case_set,\n };\n }, {\n add_case: false,\n add_case_set: false,\n is_private: false,\n read_case_set: false,\n remove_case: false,\n remove_case_set: false,\n write_case_set: false,\n });\n\n ensureNode({\n borderColor: organizationNodeBorderColor,\n category: 0,\n color: organizationNodeColor,\n id: organizationNodeId,\n name: organizationName,\n nodeType: 'organization',\n symbol: 'roundRect',\n });\n ensureNode({\n borderColor: dataCollectionNodeBorderColor,\n category: 1,\n color: dataCollectionNodeColor,\n id: targetDataCollectionNodeId,\n name: targetDataCollectionName,\n nodeType: 'dataCollection',\n symbol: 'circle',\n });\n\n accessLinks.push({\n accessPolicyCount: policyGroup.access_case_policies.length,\n accessRights,\n dataCollectionName: targetDataCollectionName,\n lineStyle: {\n color: accessLinkColor,\n curveness: 0.08,\n opacity: 0.5,\n width: 1.5 + Math.min(policyGroup.access_case_policies.length * 0.35, 1.5),\n },\n linkType: 'access',\n organizationName,\n sharePolicyCount: policyGroup.share_case_policies.length,\n source: organizationNodeId,\n sourceDataCollectionNames,\n target: targetDataCollectionNodeId,\n value: Math.max(policyGroup.access_case_policies.length, 1),\n });\n\n incrementNodeStat(organizationNodeId, 'accessLinkCount');\n incrementNodeStat(targetDataCollectionNodeId, 'accessLinkCount');\n\n policyGroup.share_case_policies.forEach(sharePolicy => {\n const sourceDataCollectionNodeId = `dataCollection:${sharePolicy.from_data_collection_id}`;\n const sourceDataCollectionName = dataCollectionMapQuery.map.get(sharePolicy.from_data_collection_id)?.name ?? sharePolicy.from_data_collection_id;\n const shareLinkKey = `${sourceDataCollectionNodeId}::${targetDataCollectionNodeId}`;\n const existingShareLink = shareLinksByKey.get(shareLinkKey);\n\n ensureNode({\n borderColor: dataCollectionNodeBorderColor,\n category: 1,\n color: dataCollectionNodeColor,\n id: sourceDataCollectionNodeId,\n name: sourceDataCollectionName,\n nodeType: 'dataCollection',\n symbol: 'circle',\n });\n\n if (existingShareLink) {\n existingShareLink.organizationNames.add(organizationName);\n existingShareLink.sharePolicyCount += 1;\n return;\n }\n\n shareLinksByKey.set(shareLinkKey, {\n organizationNames: new Set([organizationName]),\n sharePolicyCount: 1,\n source: sourceDataCollectionNodeId,\n sourceDataCollectionName,\n target: targetDataCollectionNodeId,\n targetDataCollectionName,\n });\n });\n });\n\n const shareLinks = Array.from(shareLinksByKey.values()).map(shareLink => {\n incrementNodeStat(shareLink.source, 'shareOutCount');\n incrementNodeStat(shareLink.target, 'shareInCount');\n\n return {\n lineStyle: {\n color: shareLinkColor,\n curveness: 0.28,\n opacity: 0.45,\n type: 'dashed',\n width: 1.25 + Math.min(shareLink.sharePolicyCount * 0.3, 1.25),\n },\n linkType: 'share',\n organizationNames: Array.from(shareLink.organizationNames).sort(),\n sharePolicyCount: shareLink.sharePolicyCount,\n source: shareLink.source,\n sourceDataCollectionName: shareLink.sourceDataCollectionName,\n target: shareLink.target,\n targetDataCollectionName: shareLink.targetDataCollectionName,\n value: Math.max(shareLink.sharePolicyCount, 1),\n } satisfies ShareLink;\n });\n\n const rawNodes = Array.from(nodesById.values())\n .map(node => {\n const stats = nodeStats.get(node.id) ?? {\n accessLinkCount: 0,\n shareInCount: 0,\n shareOutCount: 0,\n };\n const totalConnections = stats.accessLinkCount + stats.shareInCount + stats.shareOutCount;\n\n return {\n ...node,\n accessLinkCount: stats.accessLinkCount,\n label: buildNodeLabel('right'),\n shareInCount: stats.shareInCount,\n shareOutCount: stats.shareOutCount,\n symbolSize: node.nodeType === 'organization'\n ? Math.min(22 + (stats.accessLinkCount * 2), 34)\n : Math.min(18 + (totalConnections * 1.5), 30),\n value: totalConnections,\n x: 0,\n y: 0,\n } satisfies Node;\n });\n\n const getDataCollectionLayoutRank = (node: Node) => {\n if (node.accessLinkCount > 0 && node.shareOutCount > 0) {\n return 1;\n }\n if (node.accessLinkCount > 0) {\n return 0;\n }\n return 2;\n };\n\n const getDataCollectionX = (node: Node) => {\n if (node.accessLinkCount > 0 && node.shareOutCount > 0) {\n return GRAPH_LAYOUT.targetAndSourceDataCollectionX;\n }\n if (node.accessLinkCount > 0) {\n return GRAPH_LAYOUT.targetDataCollectionX;\n }\n return GRAPH_LAYOUT.sourceDataCollectionX;\n };\n\n const getDataCollectionLabelPosition = (node: Node): 'left' | 'right' => {\n return node.accessLinkCount > 0 && node.shareOutCount === 0 ? 'left' : 'right';\n };\n\n const isSingleNodePair = rawNodes.filter(node => node.nodeType === 'organization').length === 1\n && rawNodes.filter(node => node.nodeType === 'dataCollection').length === 1;\n\n const organizationNodes = rawNodes\n .filter(node => node.nodeType === 'organization')\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((node, index) => {\n return {\n ...node,\n label: buildNodeLabel('right'),\n x: GRAPH_LAYOUT.organizationX,\n y: GRAPH_LAYOUT.topPadding + (index * GRAPH_LAYOUT.rowGap),\n } satisfies Node;\n });\n\n const dataCollectionNodes = rawNodes\n .filter(node => node.nodeType === 'dataCollection')\n .sort((a, b) => {\n const rankDifference = getDataCollectionLayoutRank(a) - getDataCollectionLayoutRank(b);\n if (rankDifference !== 0) {\n return rankDifference;\n }\n return a.name.localeCompare(b.name);\n })\n .map((node, index) => {\n return {\n ...node,\n label: buildNodeLabel(getDataCollectionLabelPosition(node)),\n x: getDataCollectionX(node),\n y: GRAPH_LAYOUT.topPadding + (index * GRAPH_LAYOUT.rowGap) + (isSingleNodePair ? GRAPH_LAYOUT.singleRowVerticalOffset : 0),\n } satisfies Node;\n });\n\n const nodes = [...organizationNodes, ...dataCollectionNodes];\n const nodeBounds = nodes.reduce((bounds, node) => {\n return {\n maxX: Math.max(bounds.maxX, node.x),\n maxY: Math.max(bounds.maxY, node.y),\n minX: Math.min(bounds.minX, node.x),\n minY: Math.min(bounds.minY, node.y),\n };\n }, {\n maxX: Number.NEGATIVE_INFINITY,\n maxY: Number.NEGATIVE_INFINITY,\n minX: Number.POSITIVE_INFINITY,\n minY: Number.POSITIVE_INFINITY,\n });\n\n const contentBounds = nodes.reduce((bounds, node) => {\n const halfSymbolSize = node.symbolSize / 2;\n const labelPadding = GRAPH_LAYOUT.nodeLabelWidth + GRAPH_LAYOUT.labelPadding;\n const labelPosition = node.label.position === 'left' ? 'left' : 'right';\n\n return {\n maxX: Math.max(bounds.maxX, node.x + halfSymbolSize + (labelPosition === 'right' ? labelPadding : 0)),\n maxY: Math.max(bounds.maxY, node.y + halfSymbolSize + GRAPH_LAYOUT.viewportVerticalPadding),\n minX: Math.min(bounds.minX, node.x - halfSymbolSize - (labelPosition === 'left' ? labelPadding : 0)),\n minY: Math.min(bounds.minY, node.y - halfSymbolSize - GRAPH_LAYOUT.viewportVerticalPadding),\n };\n }, {\n maxX: Number.NEGATIVE_INFINITY,\n maxY: Number.NEGATIVE_INFINITY,\n minX: Number.POSITIVE_INFINITY,\n minY: Number.POSITIVE_INFINITY,\n });\n\n const nodeWidth = Math.max(nodeBounds.maxX - nodeBounds.minX, 1);\n const nodeHeight = Math.max(nodeBounds.maxY - nodeBounds.minY, 1);\n const contentWidth = Math.max(contentBounds.maxX - contentBounds.minX, 1);\n const contentHeight = Math.max(contentBounds.maxY - contentBounds.minY, 1);\n const zoom = Math.max(\n Math.min(\n (nodeWidth / contentWidth),\n (nodeHeight / contentHeight),\n 1,\n ) * GRAPH_LAYOUT.fitZoomSafetyFactor,\n 0.1,\n );\n\n return {\n categories,\n links: [...accessLinks, ...shareLinks],\n nodes,\n totalAccessLinks: accessLinks.length,\n totalDataCollections: dataCollectionNodes.length,\n totalOrganizations: organizationNodes.length,\n totalShareLinks: shareLinks.length,\n zoom,\n } satisfies Graph;\n }, [dataCollectionMapQuery.map, loadables, organizationAccessCasePoliciesQuery.data, organizationMapQuery.map, organizationShareCasePoliciesQuery.data, selectedEntityId, selectionType, t, theme.palette.primary.dark, theme.palette.primary.light, theme.palette.primary.main, theme.palette.secondary.dark, theme.palette.secondary.main, theme.palette.text.primary, theme.palette.warning.main]);\n\n const formatAccessRights = useCallback((accessRights: AccessRightsSummary) => {\n const enabledRights = [\n accessRights.add_case ? t`Add case` : null,\n accessRights.remove_case ? t`Remove case` : null,\n accessRights.add_case_set ? t`Add case set` : null,\n accessRights.remove_case_set ? t`Remove case set` : null,\n accessRights.read_case_set ? t`Read case set` : null,\n accessRights.write_case_set ? t`Write case set` : null,\n accessRights.is_private ? t`Private` : null,\n ].filter((value): value is string => !!value);\n\n return enabledRights.length > 0 ? enabledRights.join(', ') : t`None`;\n }, [t]);\n\n const formatList = useCallback((items: string[]) => {\n return items.length > 0 ? items.join(', ') : t`None`;\n }, [t]);\n\n const getOptions = useCallback(() => {\n return {\n animation: false,\n series: [\n {\n bottom: GRAPH_LAYOUT.viewportVerticalPadding,\n categories: graph.categories,\n center: ['50%', '50%'],\n data: graph.nodes,\n edgeSymbol: ['none', 'arrow'],\n edgeSymbolSize: 8,\n emphasis: {\n focus: 'adjacency',\n lineStyle: {\n width: 3,\n },\n },\n layout: 'none',\n left: GRAPH_LAYOUT.viewportHorizontalPadding,\n lineStyle: {\n opacity: 0.45,\n },\n links: graph.links,\n right: GRAPH_LAYOUT.viewportHorizontalPadding,\n roam: true,\n roamTrigger: 'global',\n scaleLimit: {\n max: 4,\n min: 0.1,\n },\n top: GRAPH_LAYOUT.viewportVerticalPadding,\n type: 'graph',\n zoom: graph.zoom,\n } satisfies GraphSeriesOption,\n ],\n tooltip: {\n formatter: (params: unknown) => {\n const typedParams = params as GraphTooltipParams;\n\n if (typedParams.dataType === 'node') {\n const node = typedParams.data as Node;\n\n if (node.nodeType === 'organization') {\n return [\n `<strong>${node.name}</strong>`,\n `${t('Accessible data collections')}: ${node.accessLinkCount}`,\n `${t('Connected share routes')}: ${node.shareInCount + node.shareOutCount}`,\n ].join('<br/>');\n }\n\n return [\n `<strong>${node.name}</strong>`,\n `${t('Organization access links')}: ${node.accessLinkCount}`,\n `${t('Incoming share routes')}: ${node.shareInCount}`,\n `${t('Outgoing share routes')}: ${node.shareOutCount}`,\n ].join('<br/>');\n }\n\n const link = typedParams.data as Link;\n\n if (link.linkType === 'access') {\n return [\n `<strong>${link.organizationName} -> ${link.dataCollectionName}</strong>`,\n `${t('Type')}: ${t`Organization access`}`,\n `${t('Active access policies')}: ${link.accessPolicyCount}`,\n `${t('Enabled access rights')}: ${formatAccessRights(link.accessRights)}`,\n `${t('Share source collections')}: ${formatList(link.sourceDataCollectionNames)}`,\n ].join('<br/>');\n }\n\n return [\n `<strong>${link.sourceDataCollectionName} -> ${link.targetDataCollectionName}</strong>`,\n `${t('Type')}: ${t`Organization share`}`,\n `${t('Active share policies')}: ${link.sharePolicyCount}`,\n `${t('Organizations')}: ${formatList(link.organizationNames)}`,\n ].join('<br/>');\n },\n },\n } satisfies EChartsOption;\n }, [formatAccessRights, formatList, graph.categories, graph.links, graph.nodes, graph.zoom, t]);\n\n return (\n <PageContainer\n fullHeight\n fullWidth\n showBreadcrumbs\n testIdAttributes={TestIdUtil.createAttributes('DataCollectionVisualizationPage')}\n title={t`Data collection visualization`}\n >\n <Box\n sx={{\n display: 'grid',\n gap: 2,\n gridTemplateRows: 'auto minmax(0, 1fr)',\n height: '100%',\n minHeight: 0,\n overflow: 'hidden',\n }}\n >\n <ResponseHandler\n loadables={loadables}\n >\n <Box\n sx={{\n borderRadius: 2,\n display: 'grid',\n gap: 2,\n px: 2,\n py: 2,\n }}\n >\n <Box\n sx={{\n alignItems: 'end',\n display: 'grid',\n gap: 2,\n gridTemplateColumns: {\n md: 'max-content minmax(320px, 520px)',\n xs: '1fr',\n },\n }}\n >\n <Box\n sx={{\n display: 'grid',\n gap: 0.75,\n }}\n >\n <Typography\n color={'text.secondary'}\n variant={'overline'}\n >\n {t`Type`}\n </Typography>\n <ToggleButtonGroup\n exclusive\n onChange={onSelectionTypeChange}\n size={'small'}\n value={selectionType}\n >\n <ToggleButton value={'organization'}>\n {t`Organization`}\n </ToggleButton>\n <ToggleButton value={'dataCollection'}>\n {t`Data collection`}\n </ToggleButton>\n </ToggleButtonGroup>\n </Box>\n <Autocomplete\n disablePortal\n getOptionLabel={getSelectionOptionLabel}\n isOptionEqualToValue={isSelectionOptionEqualToValue}\n noOptionsText={t`No results`}\n onChange={onSelectionChange}\n options={selectionOptions}\n renderInput={renderSelectionInput}\n value={selectedOption}\n />\n </Box>\n {hasSelection ? (\n <Box\n sx={{\n color: 'text.secondary',\n display: 'flex',\n flexWrap: 'wrap',\n gap: 2,\n }}\n >\n <Box component={'span'}>\n {t('Organizations: {{count}}', { count: graph.totalOrganizations })}\n </Box>\n <Box component={'span'}>\n {t('Data collections: {{count}}', { count: graph.totalDataCollections })}\n </Box>\n <Box component={'span'}>\n {t('Access links: {{count}}', { count: graph.totalAccessLinks })}\n </Box>\n <Box component={'span'}>\n {t('Share routes: {{count}}', { count: graph.totalShareLinks })}\n </Box>\n <Box component={'span'}>\n {t`Solid links show organization access policies. Dashed links show sharing routes between data collections.`}\n </Box>\n </Box>\n ) : (\n <Typography color={'text.secondary'}>\n {t`Select an organization or data collection to show the visualization.`}\n </Typography>\n )}\n </Box>\n <Box\n sx={{\n borderRadius: 2,\n height: '100%',\n minHeight: 0,\n minWidth: 0,\n overflow: 'hidden',\n }}\n >\n {hasSelection && graph.nodes.length > 0 ? (\n <EChartsReact\n echarts={echartsCore}\n notMerge\n option={getOptions()}\n style={{\n height: '100%',\n width: '100%',\n }}\n />\n ) : (\n <Box\n sx={{\n color: 'text.secondary',\n display: 'grid',\n height: '100%',\n placeItems: 'center',\n px: 3,\n textAlign: 'center',\n }}\n >\n {hasSelection\n ? t`No active organization access or share policies are available to visualize.`\n : t`Select an organization or data collection to show the visualization.`}\n </Box>\n )}\n </Box>\n </ResponseHandler>\n </Box>\n </PageContainer>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/pages/DataCollectionVisualizationPage/DataCollectionVisualizationPage.tsx"],"sourcesContent":["import { useTranslation } from 'react-i18next';\nimport {\n Autocomplete,\n Box,\n TextField,\n ToggleButton,\n ToggleButtonGroup,\n Typography,\n useTheme,\n} from '@mui/material';\nimport EChartsReact from 'echarts-for-react';\nimport {\n dispose,\n getInstanceByDom,\n init,\n use as registerECharts,\n} from 'echarts/core';\nimport { CanvasRenderer } from 'echarts/renderers';\nimport { TooltipComponent } from 'echarts/components';\nimport { GraphChart } from 'echarts/charts';\nimport {\n useCallback,\n useMemo,\n useState,\n} from 'react';\nimport type {\n MouseEvent as ReactMouseEvent,\n SyntheticEvent,\n} from 'react';\nimport type {\n EChartsOption,\n GraphSeriesOption,\n} from 'echarts';\nimport type { AutocompleteRenderInputParams } from '@mui/material/Autocomplete';\nimport type { CaseDbOrganizationAccessCasePolicy } from '@gen-epix/api-casedb';\nimport { LoadableUtil } from '@gen-epix/ui-client-common/utils/LoadableUtil';\nimport { PageContainer } from '@gen-epix/ui-client-common/components/ui/PageContainer';\nimport { ResponseHandler } from '@gen-epix/ui-client-common/components/ui/ResponseHandler';\nimport { useOrganizationMapQuery } from '@gen-epix/ui-client-common/dataHooks/useOrganizationsQuery';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\nimport { StringUtil } from '@gen-epix/ui-core/utils/StringUtil';\nimport { useArray } from '@gen-epix/ui-core/hooks/useArray';\n\nimport { useDataCollectionsMapQuery } from '../../dataHooks/useDataCollectionsQuery';\nimport { useOrganizationAccessCasePoliciesQuery } from '../../dataHooks/useOrganizationAccessCasePoliciesQuery';\nimport { useOrganizationShareCasePoliciesQuery } from '../../dataHooks/useOrganizationShareCasePoliciesQuery';\nimport { EffectiveRightsUtil } from '../../utils/EffectiveRightsUtil';\n\nconst echartsCore = {\n dispose,\n getInstanceByDom,\n init,\n};\n\nregisterECharts([TooltipComponent, CanvasRenderer, GraphChart]);\n\ntype AccessLink = {\n accessPolicyCount: number;\n accessRights: AccessRightsSummary;\n dataCollectionName: string;\n lineStyle: NonNullable<GraphSeriesOption['lineStyle']>;\n linkType: 'access';\n organizationName: string;\n sharePolicyCount: number;\n source: string;\n sourceDataCollectionNames: string[];\n target: string;\n value: number;\n};\n\ntype AccessRightsSummary = Pick<CaseDbOrganizationAccessCasePolicy, 'add_case_set' | 'add_case' | 'is_private' | 'read_case_set' | 'remove_case_set' | 'remove_case' | 'write_case_set'>;\n\ntype Category = {\n name: string;\n};\n\ntype Graph = {\n categories: Category[];\n links: Link[];\n nodes: Node[];\n totalAccessLinks: number;\n totalDataCollections: number;\n totalOrganizations: number;\n totalShareLinks: number;\n zoom: number;\n};\n\ntype GraphTooltipParams = {\n data: Link | Node;\n dataType?: 'edge' | 'node';\n};\n\ntype Link = AccessLink | ShareLink;\n\ntype Node = {\n accessLinkCount: number;\n category: number;\n id: string;\n itemStyle: {\n borderColor: string;\n borderWidth: number;\n color: string;\n };\n label: NonNullable<GraphSeriesOption['label']>;\n name: string;\n nodeType: 'dataCollection' | 'organization';\n shareInCount: number;\n shareOutCount: number;\n symbol: 'circle' | 'roundRect';\n symbolSize: number;\n value: number;\n x: number;\n y: number;\n};\n\ntype SelectionOption = {\n label: string;\n value: string;\n};\n\ntype SelectionType = 'dataCollection' | 'organization';\n\ntype ShareLink = {\n lineStyle: NonNullable<GraphSeriesOption['lineStyle']>;\n linkType: 'share';\n organizationNames: string[];\n sharePolicyCount: number;\n source: string;\n sourceDataCollectionName: string;\n target: string;\n targetDataCollectionName: string;\n value: number;\n};\n\nconst EMPTY_GRAPH: Graph = {\n categories: [],\n links: [],\n nodes: [],\n totalAccessLinks: 0,\n totalDataCollections: 0,\n totalOrganizations: 0,\n totalShareLinks: 0,\n zoom: 1,\n};\n\nconst GRAPH_LAYOUT = {\n bottomPadding: 72,\n fitZoomSafetyFactor: 0.94,\n labelPadding: 12,\n nodeLabelWidth: 220,\n organizationX: 120,\n rowGap: 68,\n singleRowVerticalOffset: 96,\n sourceDataCollectionX: 1060,\n targetAndSourceDataCollectionX: 820,\n targetDataCollectionX: 620,\n topPadding: 72,\n viewportHorizontalPadding: 24,\n viewportVerticalPadding: 24,\n} as const;\n\nexport const DataCollectionVisualizationPage = () => {\n const { t } = useTranslation();\n const theme = useTheme();\n const [selectionType, setSelectionType] = useState<SelectionType>('organization');\n const [selectedEntityId, setSelectedEntityId] = useState<string>(null);\n const dataCollectionMapQuery = useDataCollectionsMapQuery();\n const organizationMapQuery = useOrganizationMapQuery();\n const organizationAccessCasePoliciesQuery = useOrganizationAccessCasePoliciesQuery(policies => policies.filter(policy => policy.is_active));\n const organizationShareCasePoliciesQuery = useOrganizationShareCasePoliciesQuery(policies => policies.filter(policy => policy.is_active));\n\n const loadables = useArray([\n dataCollectionMapQuery,\n organizationMapQuery,\n organizationAccessCasePoliciesQuery,\n organizationShareCasePoliciesQuery,\n ]);\n\n const organizationOptions = useMemo<SelectionOption[]>(() => {\n return Array.from(organizationMapQuery.map.values())\n .map(organization => ({\n label: organization.name,\n value: organization.id,\n }))\n .sort((a, b) => StringUtil.advancedSortComperator(a.label, b.label));\n }, [organizationMapQuery.map]);\n\n const dataCollectionOptions = useMemo<SelectionOption[]>(() => {\n return Array.from(dataCollectionMapQuery.map.values())\n .map(dataCollection => ({\n label: dataCollection.name,\n value: dataCollection.id,\n }))\n .sort((a, b) => StringUtil.advancedSortComperator(a.label, b.label));\n }, [dataCollectionMapQuery.map]);\n\n const selectionOptions = useMemo(() => {\n return selectionType === 'organization' ? organizationOptions : dataCollectionOptions;\n }, [dataCollectionOptions, organizationOptions, selectionType]);\n\n const selectedOption = useMemo(() => {\n return selectionOptions.find(option => option.value === selectedEntityId) ?? null;\n }, [selectedEntityId, selectionOptions]);\n\n const selectionLabel = selectionType === 'organization' ? t`Organization` : t`Data collection`;\n const hasSelection = !!selectedEntityId;\n\n const onSelectionTypeChange = useCallback((_event: ReactMouseEvent<HTMLElement>, nextSelectionType: null | SelectionType) => {\n if (!nextSelectionType || nextSelectionType === selectionType) {\n return;\n }\n\n setSelectionType(nextSelectionType);\n setSelectedEntityId(null);\n }, [selectionType]);\n\n const getSelectionOptionLabel = useCallback((option: SelectionOption) => {\n return option.label;\n }, []);\n\n const isSelectionOptionEqualToValue = useCallback((option: SelectionOption, value: SelectionOption) => {\n return option.value === value.value;\n }, []);\n\n const onSelectionChange = useCallback((_event: SyntheticEvent, nextOption: null | SelectionOption) => {\n setSelectedEntityId(nextOption?.value ?? null);\n }, []);\n\n const renderSelectionInput = useCallback((params: AutocompleteRenderInputParams) => {\n return (\n <TextField\n {...params}\n label={selectionLabel}\n required\n size={'small'}\n />\n );\n }, [selectionLabel]);\n\n const graph = useMemo<Graph>(() => {\n if (LoadableUtil.isSomeLoading(loadables)) {\n return EMPTY_GRAPH;\n }\n\n if (!selectedEntityId) {\n return EMPTY_GRAPH;\n }\n\n const categories: Category[] = [\n {\n name: t`Organization`,\n },\n {\n name: t`Data collection`,\n },\n ];\n\n const organizationNodeColor = theme.palette.primary.main;\n const organizationNodeBorderColor = theme.palette.primary.dark;\n const dataCollectionNodeColor = theme.palette.secondary.main;\n const dataCollectionNodeBorderColor = theme.palette.secondary.dark;\n const accessLinkColor = theme.palette.primary.light;\n const shareLinkColor = theme.palette.warning.main;\n\n const policyGroups = EffectiveRightsUtil.getOrganizationPolicyGroups({\n organizationAccessCasePolicies: organizationAccessCasePoliciesQuery.data,\n organizationShareCasePolicies: organizationShareCasePoliciesQuery.data,\n });\n\n const filteredPolicyGroups = policyGroups.filter(policyGroup => {\n if (selectionType === 'organization') {\n return policyGroup.organization_id === selectedEntityId;\n }\n\n return policyGroup.data_collection_id === selectedEntityId\n || policyGroup.share_case_policies.some(policy => policy.from_data_collection_id === selectedEntityId);\n });\n\n const nodesById = new Map<string, Omit<Node, 'accessLinkCount' | 'label' | 'shareInCount' | 'shareOutCount' | 'symbolSize' | 'value' | 'x' | 'y'>>();\n const nodeStats = new Map<string, Pick<Node, 'accessLinkCount' | 'shareInCount' | 'shareOutCount'>>();\n const accessLinks: AccessLink[] = [];\n const shareLinksByKey = new Map<string, {\n organizationNames: Set<string>;\n sharePolicyCount: number;\n source: string;\n sourceDataCollectionName: string;\n target: string;\n targetDataCollectionName: string;\n }>();\n\n const buildNodeLabel = (position: 'left' | 'right'): Node['label'] => {\n return {\n color: theme.palette.text.primary,\n distance: 8,\n fontSize: 12,\n formatter: '{b}',\n overflow: 'truncate',\n position,\n show: true,\n width: GRAPH_LAYOUT.nodeLabelWidth,\n };\n };\n\n const ensureNode = (params: {\n borderColor: string;\n category: number;\n color: string;\n id: string;\n name: string;\n nodeType: Node['nodeType'];\n symbol: Node['symbol'];\n }) => {\n if (nodesById.has(params.id)) {\n return;\n }\n\n nodesById.set(params.id, {\n category: params.category,\n id: params.id,\n itemStyle: {\n borderColor: params.borderColor,\n borderWidth: 1.5,\n color: params.color,\n },\n name: params.name,\n nodeType: params.nodeType,\n symbol: params.symbol,\n });\n };\n\n const incrementNodeStat = (nodeId: string, key: keyof Pick<Node, 'accessLinkCount' | 'shareInCount' | 'shareOutCount'>) => {\n const currentStats = nodeStats.get(nodeId) ?? {\n accessLinkCount: 0,\n shareInCount: 0,\n shareOutCount: 0,\n };\n\n currentStats[key] += 1;\n nodeStats.set(nodeId, currentStats);\n };\n\n filteredPolicyGroups.forEach(policyGroup => {\n const organizationNodeId = `organization:${policyGroup.organization_id}`;\n const targetDataCollectionNodeId = `dataCollection:${policyGroup.data_collection_id}`;\n const organizationName = organizationMapQuery.map.get(policyGroup.organization_id)?.name ?? policyGroup.organization_id;\n const targetDataCollectionName = dataCollectionMapQuery.map.get(policyGroup.data_collection_id)?.name ?? policyGroup.data_collection_id;\n const sourceDataCollectionNames = Array.from(new Set(policyGroup.share_case_policies.map(policy => dataCollectionMapQuery.map.get(policy.from_data_collection_id)?.name ?? policy.from_data_collection_id))).sort();\n\n const accessRights = policyGroup.access_case_policies.reduce<AccessRightsSummary>((summary, policy) => {\n return {\n add_case: summary.add_case || policy.add_case,\n add_case_set: summary.add_case_set || policy.add_case_set,\n is_private: summary.is_private || policy.is_private,\n read_case_set: summary.read_case_set || policy.read_case_set,\n remove_case: summary.remove_case || policy.remove_case,\n remove_case_set: summary.remove_case_set || policy.remove_case_set,\n write_case_set: summary.write_case_set || policy.write_case_set,\n };\n }, {\n add_case: false,\n add_case_set: false,\n is_private: false,\n read_case_set: false,\n remove_case: false,\n remove_case_set: false,\n write_case_set: false,\n });\n\n ensureNode({\n borderColor: organizationNodeBorderColor,\n category: 0,\n color: organizationNodeColor,\n id: organizationNodeId,\n name: organizationName,\n nodeType: 'organization',\n symbol: 'roundRect',\n });\n ensureNode({\n borderColor: dataCollectionNodeBorderColor,\n category: 1,\n color: dataCollectionNodeColor,\n id: targetDataCollectionNodeId,\n name: targetDataCollectionName,\n nodeType: 'dataCollection',\n symbol: 'circle',\n });\n\n accessLinks.push({\n accessPolicyCount: policyGroup.access_case_policies.length,\n accessRights,\n dataCollectionName: targetDataCollectionName,\n lineStyle: {\n color: accessLinkColor,\n curveness: 0.08,\n opacity: 0.5,\n width: 1.5 + Math.min(policyGroup.access_case_policies.length * 0.35, 1.5),\n },\n linkType: 'access',\n organizationName,\n sharePolicyCount: policyGroup.share_case_policies.length,\n source: organizationNodeId,\n sourceDataCollectionNames,\n target: targetDataCollectionNodeId,\n value: Math.max(policyGroup.access_case_policies.length, 1),\n });\n\n incrementNodeStat(organizationNodeId, 'accessLinkCount');\n incrementNodeStat(targetDataCollectionNodeId, 'accessLinkCount');\n\n policyGroup.share_case_policies.forEach(sharePolicy => {\n const sourceDataCollectionNodeId = `dataCollection:${sharePolicy.from_data_collection_id}`;\n const sourceDataCollectionName = dataCollectionMapQuery.map.get(sharePolicy.from_data_collection_id)?.name ?? sharePolicy.from_data_collection_id;\n const shareLinkKey = `${sourceDataCollectionNodeId}::${targetDataCollectionNodeId}`;\n const existingShareLink = shareLinksByKey.get(shareLinkKey);\n\n ensureNode({\n borderColor: dataCollectionNodeBorderColor,\n category: 1,\n color: dataCollectionNodeColor,\n id: sourceDataCollectionNodeId,\n name: sourceDataCollectionName,\n nodeType: 'dataCollection',\n symbol: 'circle',\n });\n\n if (existingShareLink) {\n existingShareLink.organizationNames.add(organizationName);\n existingShareLink.sharePolicyCount += 1;\n return;\n }\n\n shareLinksByKey.set(shareLinkKey, {\n organizationNames: new Set([organizationName]),\n sharePolicyCount: 1,\n source: sourceDataCollectionNodeId,\n sourceDataCollectionName,\n target: targetDataCollectionNodeId,\n targetDataCollectionName,\n });\n });\n });\n\n const shareLinks = Array.from(shareLinksByKey.values()).map(shareLink => {\n incrementNodeStat(shareLink.source, 'shareOutCount');\n incrementNodeStat(shareLink.target, 'shareInCount');\n\n return {\n lineStyle: {\n color: shareLinkColor,\n curveness: 0.28,\n opacity: 0.45,\n type: 'dashed',\n width: 1.25 + Math.min(shareLink.sharePolicyCount * 0.3, 1.25),\n },\n linkType: 'share',\n organizationNames: Array.from(shareLink.organizationNames).sort(),\n sharePolicyCount: shareLink.sharePolicyCount,\n source: shareLink.source,\n sourceDataCollectionName: shareLink.sourceDataCollectionName,\n target: shareLink.target,\n targetDataCollectionName: shareLink.targetDataCollectionName,\n value: Math.max(shareLink.sharePolicyCount, 1),\n } satisfies ShareLink;\n });\n\n const rawNodes = Array.from(nodesById.values())\n .map(node => {\n const stats = nodeStats.get(node.id) ?? {\n accessLinkCount: 0,\n shareInCount: 0,\n shareOutCount: 0,\n };\n const totalConnections = stats.accessLinkCount + stats.shareInCount + stats.shareOutCount;\n\n return {\n ...node,\n accessLinkCount: stats.accessLinkCount,\n label: buildNodeLabel('right'),\n shareInCount: stats.shareInCount,\n shareOutCount: stats.shareOutCount,\n symbolSize: node.nodeType === 'organization'\n ? Math.min(22 + (stats.accessLinkCount * 2), 34)\n : Math.min(18 + (totalConnections * 1.5), 30),\n value: totalConnections,\n x: 0,\n y: 0,\n } satisfies Node;\n });\n\n const getDataCollectionLayoutRank = (node: Node) => {\n if (node.accessLinkCount > 0 && node.shareOutCount > 0) {\n return 1;\n }\n if (node.accessLinkCount > 0) {\n return 0;\n }\n return 2;\n };\n\n const getDataCollectionX = (node: Node) => {\n if (node.accessLinkCount > 0 && node.shareOutCount > 0) {\n return GRAPH_LAYOUT.targetAndSourceDataCollectionX;\n }\n if (node.accessLinkCount > 0) {\n return GRAPH_LAYOUT.targetDataCollectionX;\n }\n return GRAPH_LAYOUT.sourceDataCollectionX;\n };\n\n const getDataCollectionLabelPosition = (node: Node): 'left' | 'right' => {\n return node.accessLinkCount > 0 && node.shareOutCount === 0 ? 'left' : 'right';\n };\n\n const isSingleNodePair = rawNodes.filter(node => node.nodeType === 'organization').length === 1\n && rawNodes.filter(node => node.nodeType === 'dataCollection').length === 1;\n\n const organizationNodes = rawNodes\n .filter(node => node.nodeType === 'organization')\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((node, index) => {\n return {\n ...node,\n label: buildNodeLabel('right'),\n x: GRAPH_LAYOUT.organizationX,\n y: GRAPH_LAYOUT.topPadding + (index * GRAPH_LAYOUT.rowGap),\n } satisfies Node;\n });\n\n const dataCollectionNodes = rawNodes\n .filter(node => node.nodeType === 'dataCollection')\n .sort((a, b) => {\n const rankDifference = getDataCollectionLayoutRank(a) - getDataCollectionLayoutRank(b);\n if (rankDifference !== 0) {\n return rankDifference;\n }\n return a.name.localeCompare(b.name);\n })\n .map((node, index) => {\n return {\n ...node,\n label: buildNodeLabel(getDataCollectionLabelPosition(node)),\n x: getDataCollectionX(node),\n y: GRAPH_LAYOUT.topPadding + (index * GRAPH_LAYOUT.rowGap) + (isSingleNodePair ? GRAPH_LAYOUT.singleRowVerticalOffset : 0),\n } satisfies Node;\n });\n\n const nodes = [...organizationNodes, ...dataCollectionNodes];\n const nodeBounds = nodes.reduce((bounds, node) => {\n return {\n maxX: Math.max(bounds.maxX, node.x),\n maxY: Math.max(bounds.maxY, node.y),\n minX: Math.min(bounds.minX, node.x),\n minY: Math.min(bounds.minY, node.y),\n };\n }, {\n maxX: Number.NEGATIVE_INFINITY,\n maxY: Number.NEGATIVE_INFINITY,\n minX: Number.POSITIVE_INFINITY,\n minY: Number.POSITIVE_INFINITY,\n });\n\n const contentBounds = nodes.reduce((bounds, node) => {\n const halfSymbolSize = node.symbolSize / 2;\n const labelPadding = GRAPH_LAYOUT.nodeLabelWidth + GRAPH_LAYOUT.labelPadding;\n const labelPosition = node.label.position === 'left' ? 'left' : 'right';\n\n return {\n maxX: Math.max(bounds.maxX, node.x + halfSymbolSize + (labelPosition === 'right' ? labelPadding : 0)),\n maxY: Math.max(bounds.maxY, node.y + halfSymbolSize + GRAPH_LAYOUT.viewportVerticalPadding),\n minX: Math.min(bounds.minX, node.x - halfSymbolSize - (labelPosition === 'left' ? labelPadding : 0)),\n minY: Math.min(bounds.minY, node.y - halfSymbolSize - GRAPH_LAYOUT.viewportVerticalPadding),\n };\n }, {\n maxX: Number.NEGATIVE_INFINITY,\n maxY: Number.NEGATIVE_INFINITY,\n minX: Number.POSITIVE_INFINITY,\n minY: Number.POSITIVE_INFINITY,\n });\n\n const nodeWidth = Math.max(nodeBounds.maxX - nodeBounds.minX, 1);\n const nodeHeight = Math.max(nodeBounds.maxY - nodeBounds.minY, 1);\n const contentWidth = Math.max(contentBounds.maxX - contentBounds.minX, 1);\n const contentHeight = Math.max(contentBounds.maxY - contentBounds.minY, 1);\n const zoom = Math.max(\n Math.min(\n (nodeWidth / contentWidth),\n (nodeHeight / contentHeight),\n 1,\n ) * GRAPH_LAYOUT.fitZoomSafetyFactor,\n 0.1,\n );\n\n return {\n categories,\n links: [...accessLinks, ...shareLinks],\n nodes,\n totalAccessLinks: accessLinks.length,\n totalDataCollections: dataCollectionNodes.length,\n totalOrganizations: organizationNodes.length,\n totalShareLinks: shareLinks.length,\n zoom,\n } satisfies Graph;\n }, [dataCollectionMapQuery.map, loadables, organizationAccessCasePoliciesQuery.data, organizationMapQuery.map, organizationShareCasePoliciesQuery.data, selectedEntityId, selectionType, t, theme.palette.primary.dark, theme.palette.primary.light, theme.palette.primary.main, theme.palette.secondary.dark, theme.palette.secondary.main, theme.palette.text.primary, theme.palette.warning.main]);\n\n const formatAccessRights = useCallback((accessRights: AccessRightsSummary) => {\n const enabledRights = [\n accessRights.add_case ? t`Add case` : null,\n accessRights.remove_case ? t`Remove case` : null,\n accessRights.add_case_set ? t`Add case set` : null,\n accessRights.remove_case_set ? t`Remove case set` : null,\n accessRights.read_case_set ? t`Read case set` : null,\n accessRights.write_case_set ? t`Write case set` : null,\n accessRights.is_private ? t`Private` : null,\n ].filter((value): value is string => !!value);\n\n return enabledRights.length > 0 ? enabledRights.join(', ') : t`None`;\n }, [t]);\n\n const formatList = useCallback((items: string[]) => {\n return items.length > 0 ? items.join(', ') : t`None`;\n }, [t]);\n\n const getOptions = useCallback(() => {\n return {\n animation: false,\n series: [\n {\n bottom: GRAPH_LAYOUT.viewportVerticalPadding,\n categories: graph.categories,\n center: ['50%', '50%'],\n data: graph.nodes,\n edgeSymbol: ['none', 'arrow'],\n edgeSymbolSize: 8,\n emphasis: {\n focus: 'adjacency',\n lineStyle: {\n width: 3,\n },\n },\n layout: 'none',\n left: GRAPH_LAYOUT.viewportHorizontalPadding,\n lineStyle: {\n opacity: 0.45,\n },\n links: graph.links,\n right: GRAPH_LAYOUT.viewportHorizontalPadding,\n roam: true,\n roamTrigger: 'global',\n scaleLimit: {\n max: 4,\n min: 0.1,\n },\n top: GRAPH_LAYOUT.viewportVerticalPadding,\n type: 'graph',\n zoom: graph.zoom,\n } satisfies GraphSeriesOption,\n ],\n tooltip: {\n formatter: (params: unknown) => {\n const typedParams = params as GraphTooltipParams;\n\n if (typedParams.dataType === 'node') {\n const node = typedParams.data as Node;\n\n if (node.nodeType === 'organization') {\n return [\n `<strong>${node.name}</strong>`,\n `${t('Accessible data collections')}: ${node.accessLinkCount}`,\n `${t('Connected share routes')}: ${node.shareInCount + node.shareOutCount}`,\n ].join('<br/>');\n }\n\n return [\n `<strong>${node.name}</strong>`,\n `${t('Organization access links')}: ${node.accessLinkCount}`,\n `${t('Incoming share routes')}: ${node.shareInCount}`,\n `${t('Outgoing share routes')}: ${node.shareOutCount}`,\n ].join('<br/>');\n }\n\n const link = typedParams.data as Link;\n\n if (link.linkType === 'access') {\n return [\n `<strong>${link.organizationName} -> ${link.dataCollectionName}</strong>`,\n `${t('Type')}: ${t`Organization access`}`,\n `${t('Active access policies')}: ${link.accessPolicyCount}`,\n `${t('Enabled access rights')}: ${formatAccessRights(link.accessRights)}`,\n `${t('Share source collections')}: ${formatList(link.sourceDataCollectionNames)}`,\n ].join('<br/>');\n }\n\n return [\n `<strong>${link.sourceDataCollectionName} -> ${link.targetDataCollectionName}</strong>`,\n `${t('Type')}: ${t`Organization share`}`,\n `${t('Active share policies')}: ${link.sharePolicyCount}`,\n `${t('Organizations')}: ${formatList(link.organizationNames)}`,\n ].join('<br/>');\n },\n },\n } satisfies EChartsOption;\n }, [formatAccessRights, formatList, graph.categories, graph.links, graph.nodes, graph.zoom, t]);\n\n return (\n <PageContainer\n fullHeight\n fullWidth\n showBreadcrumbs\n testIdAttributes={TestIdUtil.createAttributes('DataCollectionVisualizationPage')}\n title={t`Data collection visualization`}\n >\n <Box\n sx={{\n display: 'grid',\n gap: 2,\n gridTemplateRows: 'auto minmax(0, 1fr)',\n height: '100%',\n minHeight: 0,\n overflow: 'hidden',\n }}\n >\n <ResponseHandler\n loadables={loadables}\n >\n <Box\n sx={{\n borderRadius: 2,\n display: 'grid',\n gap: 2,\n px: 2,\n py: 2,\n }}\n >\n <Box\n sx={{\n alignItems: 'end',\n display: 'grid',\n gap: 2,\n gridTemplateColumns: {\n md: 'max-content minmax(320px, 520px)',\n xs: '1fr',\n },\n }}\n >\n <Box\n sx={{\n display: 'grid',\n gap: 0.75,\n }}\n >\n <Typography\n color={'text.secondary'}\n variant={'overline'}\n >\n {t`Type`}\n </Typography>\n <ToggleButtonGroup\n exclusive\n onChange={onSelectionTypeChange}\n size={'small'}\n value={selectionType}\n >\n <ToggleButton value={'organization'}>\n {t`Organization`}\n </ToggleButton>\n <ToggleButton value={'dataCollection'}>\n {t`Data collection`}\n </ToggleButton>\n </ToggleButtonGroup>\n </Box>\n <Autocomplete\n disablePortal\n getOptionLabel={getSelectionOptionLabel}\n isOptionEqualToValue={isSelectionOptionEqualToValue}\n noOptionsText={t`No results`}\n onChange={onSelectionChange}\n options={selectionOptions}\n renderInput={renderSelectionInput}\n value={selectedOption}\n />\n </Box>\n {hasSelection ? (\n <Box\n sx={{\n color: 'text.secondary',\n display: 'flex',\n flexWrap: 'wrap',\n gap: 2,\n }}\n >\n <Box component={'span'}>\n {t('Organizations: {{count}}', { count: graph.totalOrganizations })}\n </Box>\n <Box component={'span'}>\n {t('Data collections: {{count}}', { count: graph.totalDataCollections })}\n </Box>\n <Box component={'span'}>\n {t('Access links: {{count}}', { count: graph.totalAccessLinks })}\n </Box>\n <Box component={'span'}>\n {t('Share routes: {{count}}', { count: graph.totalShareLinks })}\n </Box>\n <Box component={'span'}>\n {t`Solid links show organization access policies. Dashed links show sharing routes between data collections.`}\n </Box>\n </Box>\n ) : (\n <Typography color={'text.secondary'}>\n {t`Select an organization or data collection to show the visualization.`}\n </Typography>\n )}\n </Box>\n <Box\n sx={{\n borderRadius: 2,\n height: '100%',\n minHeight: 0,\n minWidth: 0,\n overflow: 'hidden',\n }}\n >\n {hasSelection && graph.nodes.length > 0 ? (\n <EChartsReact\n echarts={echartsCore}\n notMerge\n option={getOptions()}\n style={{\n height: '100%',\n width: '100%',\n }}\n />\n ) : (\n <Box\n sx={{\n color: 'text.secondary',\n display: 'grid',\n height: '100%',\n placeItems: 'center',\n px: 3,\n textAlign: 'center',\n }}\n >\n {hasSelection\n ? t`No active organization access or share policies are available to visualize.`\n : t`Select an organization or data collection to show the visualization.`}\n </Box>\n )}\n </Box>\n </ResponseHandler>\n </Box>\n </PageContainer>\n );\n};\n"],"mappings":"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"}
@@ -1,71 +1,71 @@
1
1
  import { CASEDB_QUERY_KEY as e } from "../../constants/query.js";
2
2
  import { useCaseTypeMapQuery as t, useCaseTypeOptionsQuery as n } from "../../dataHooks/useCaseTypesQuery/index.js";
3
- import { t as r } from "../../_chunks/chunk-OB3PAWPO.js";
4
- import { useRefDimOptionsQuery as i } from "../../dataHooks/useRefDimsQuery/index.js";
5
- import { boolean as a, object as o, string as s } from "yup";
6
- import { CaseDbCaseApi as c, CaseDbCommandName as l, CaseDbPermissionType as u } from "@gen-epix/api-casedb";
7
- import { FORM_FIELD_DEFINITION_TYPE as d } from "@gen-epix/ui-core-form/models/form";
8
- import { useCallback as f, useMemo as p } from "react";
9
- import { useTranslation as m } from "react-i18next";
10
- import { jsx as h } from "react/jsx-runtime";
11
- import { useArray as g } from "@gen-epix/ui-core/hooks/useArray";
12
- import { TableUtil as _ } from "@gen-epix/ui-client-common/utils/TableUtil";
13
- import { TestIdUtil as v } from "@gen-epix/ui-core/utils/TestIdUtil";
14
- import { SchemaUtil as y } from "@gen-epix/ui-core-form/utils/SchemaUtil";
15
- import { AuthorizationService as b } from "@gen-epix/ui-client-common/classes/services/AuthorizationService";
16
- import { CrudPage as x } from "@gen-epix/ui-client-common/pages/CrudPage";
3
+ import { useRefDimOptionsQuery as r } from "../../dataHooks/useRefDimsQuery/index.js";
4
+ import { boolean as i, object as a, string as o } from "yup";
5
+ import { CaseDbCaseApi as s, CaseDbCommandName as c, CaseDbPermissionType as l } from "@gen-epix/api-casedb";
6
+ import { FORM_FIELD_DEFINITION_TYPE as u } from "@gen-epix/ui-core-form/models/form";
7
+ import { useCallback as d, useMemo as f } from "react";
8
+ import { useTranslation as p } from "react-i18next";
9
+ import { jsx as m } from "react/jsx-runtime";
10
+ import { useArray as h } from "@gen-epix/ui-core/hooks/useArray";
11
+ import { TableUtil as g } from "@gen-epix/ui-client-common/utils/TableUtil";
12
+ import { TestIdUtil as _ } from "@gen-epix/ui-core/utils/TestIdUtil";
13
+ import { SchemaUtil as v } from "@gen-epix/ui-core-form/utils/SchemaUtil";
14
+ import { AuthorizationService as y } from "@gen-epix/ui-client-common/classes/services/AuthorizationService";
15
+ import { CrudPage as b } from "@gen-epix/ui-client-common/pages/CrudPage";
16
+ import { useParams as x } from "react-router-dom";
17
17
  //#region src/pages/DimsAdminPage/DimsAdminPage.tsx
18
18
  var S = () => {
19
- let { caseTypeId: S } = r(), { t: C } = m(), w = i(), T = n(), E = t(), D = g([T, w]), O = f(async (e) => (await c.getInstance().dimsGetAll(null, null, { signal: e }))?.data, []), k = f((e) => S ? e.filter((e) => e.case_type_id === S) : e, [S]), A = f(async (e) => await c.getInstance().dimsDeleteOne(e.id), []), j = f(async (e, t) => (await c.getInstance().dimsPutOne(t.id, {
19
+ let { caseTypeId: S } = x(), { t: C } = p(), w = r(), T = n(), E = t(), D = h([T, w]), O = d(async (e) => (await s.getInstance().dimsGetAll(null, null, { signal: e }))?.data, []), k = d((e) => S ? e.filter((e) => e.case_type_id === S) : e, [S]), A = d(async (e) => await s.getInstance().dimsDeleteOne(e.id), []), j = d(async (e, t) => (await s.getInstance().dimsPutOne(t.id, {
20
20
  id: t.id,
21
21
  ...e
22
- })).data, []), M = f(async (e) => (await c.getInstance().dimsPostOne(e)).data, []), N = f((e) => e.label, []), P = p(() => o().shape({
23
- case_type_id: s().uuid4().required().max(100),
24
- code: y.code,
25
- description: y.description,
26
- is_case_date_dim: a().required(),
27
- label: y.label,
28
- occurrence: y.number.required().min(0).integer().positive(),
29
- rank: y.rank,
30
- ref_dim_id: s().uuid4().required().max(100)
31
- }), []), F = p(() => [
22
+ })).data, []), M = d(async (e) => (await s.getInstance().dimsPostOne(e)).data, []), N = d((e) => e.label, []), P = f(() => a().shape({
23
+ case_type_id: o().uuid4().required().max(100),
24
+ code: v.code,
25
+ description: v.description,
26
+ is_case_date_dim: i().required(),
27
+ label: v.label,
28
+ occurrence: v.number.required().min(0).integer().positive(),
29
+ rank: v.rank,
30
+ ref_dim_id: o().uuid4().required().max(100)
31
+ }), []), F = f(() => [
32
32
  {
33
- definition: d.AUTOCOMPLETE,
33
+ definition: u.AUTOCOMPLETE,
34
34
  label: C`Case type`,
35
35
  name: "case_type_id",
36
36
  options: T.options
37
37
  },
38
38
  {
39
- definition: d.AUTOCOMPLETE,
39
+ definition: u.AUTOCOMPLETE,
40
40
  label: C`Reference dimension`,
41
41
  name: "ref_dim_id",
42
42
  options: w.options
43
43
  },
44
44
  {
45
- definition: d.TEXTFIELD,
45
+ definition: u.TEXTFIELD,
46
46
  label: C`Code`,
47
47
  name: "code"
48
48
  },
49
49
  {
50
- definition: d.TEXTFIELD,
50
+ definition: u.TEXTFIELD,
51
51
  label: C`Label`,
52
52
  name: "label"
53
53
  },
54
54
  {
55
- definition: d.TEXTFIELD,
55
+ definition: u.TEXTFIELD,
56
56
  label: C`Description`,
57
57
  multiline: !0,
58
58
  name: "description",
59
59
  rows: 5
60
60
  },
61
61
  {
62
- definition: d.TEXTFIELD,
62
+ definition: u.TEXTFIELD,
63
63
  label: C`Occurrence`,
64
64
  name: "occurrence",
65
65
  type: "number"
66
66
  },
67
67
  {
68
- definition: d.TEXTFIELD,
68
+ definition: u.TEXTFIELD,
69
69
  label: C`Rank`,
70
70
  name: "rank",
71
71
  type: "number"
@@ -74,26 +74,26 @@ var S = () => {
74
74
  T.options,
75
75
  w.options,
76
76
  C
77
- ]), I = p(() => {
77
+ ]), I = f(() => {
78
78
  let e = [];
79
- return S || e.push(_.createOptionsColumn({
79
+ return S || e.push(g.createOptionsColumn({
80
80
  id: "case_type_id",
81
81
  name: C`Case type`,
82
82
  options: T.options
83
- })), e.push(_.createOptionsColumn({
83
+ })), e.push(g.createOptionsColumn({
84
84
  id: "ref_dim_id",
85
85
  name: C`Reference dimension`,
86
86
  options: w.options
87
- }), _.createTextColumn({
87
+ }), g.createTextColumn({
88
88
  id: "code",
89
89
  name: C`Code`
90
- }), _.createTextColumn({
90
+ }), g.createTextColumn({
91
91
  id: "label",
92
92
  name: C`Label`
93
- }), _.createNumberColumn({
93
+ }), g.createNumberColumn({
94
94
  id: "occurrence",
95
95
  name: C`Occurrence`
96
- }), _.createNumberColumn({
96
+ }), g.createNumberColumn({
97
97
  id: "rank",
98
98
  name: C`Rank`
99
99
  })), e;
@@ -102,13 +102,13 @@ var S = () => {
102
102
  T.options,
103
103
  w.options,
104
104
  C
105
- ]), L = p(() => ({ case_type_id: S ?? null }), [S]), R = p(() => b.getInstance().doesUserHavePermission([{
106
- command_name: l.RefColCrudCommand,
107
- permission_type: u.READ
105
+ ]), L = f(() => ({ case_type_id: S ?? null }), [S]), R = f(() => y.getInstance().doesUserHavePermission([{
106
+ command_name: c.RefColCrudCommand,
107
+ permission_type: l.READ
108
108
  }]) ? [{
109
109
  getPathName: (e) => S ? `/management/case-types/${S}/dimensions/${e.id}/columns` : `/management/dimensions/${e.id}/columns`,
110
110
  label: C`Manage columns`
111
- }] : [], [S, C]), z = p(() => {
111
+ }] : [], [S, C]), z = f(() => {
112
112
  let e = [];
113
113
  return S && E.map.has(S) && e.push(E.map.get(S)?.name), e.push(C`Dimensions`), e;
114
114
  }, [
@@ -116,10 +116,10 @@ var S = () => {
116
116
  E.map,
117
117
  C
118
118
  ]);
119
- return /* @__PURE__ */ h(x, {
119
+ return /* @__PURE__ */ m(b, {
120
120
  createItemDialogTitle: C`Create new dimensions`,
121
121
  createOne: M,
122
- crudCommandType: l.DimCrudCommand,
122
+ crudCommandType: c.DimCrudCommand,
123
123
  defaultNewItem: L,
124
124
  defaultSortByField: S ? "rank" : "case_type_id",
125
125
  defaultSortDirection: "asc",
@@ -135,7 +135,7 @@ var S = () => {
135
135
  subPages: R,
136
136
  tableColumns: I,
137
137
  tableStoreStorageNamePostFix: S ? "CaseType" : void 0,
138
- testIdAttributes: v.createAttributes("DimsAdminPage"),
138
+ testIdAttributes: _.createAttributes("DimsAdminPage"),
139
139
  title: z,
140
140
  updateOne: j
141
141
  });
@@ -1,24 +1,24 @@
1
1
  import { CASEDB_QUERY_KEY as e } from "../../constants/query.js";
2
2
  import { useCaseTypeMapQuery as t } from "../../dataHooks/useCaseTypesQuery/index.js";
3
3
  import { n } from "../../_chunks/Dashboard.js";
4
- import { t as r } from "../../_chunks/chunk-OB3PAWPO.js";
5
- import { CaseDbCaseApi as i } from "@gen-epix/api-casedb";
6
- import { useEffect as a, useMemo as o } from "react";
7
- import { useTranslation as s } from "react-i18next";
8
- import { jsx as c } from "react/jsx-runtime";
9
- import { ResponseHandler as l } from "@gen-epix/ui-client-common/components/ui/ResponseHandler";
10
- import { useItemQuery as u } from "@gen-epix/ui-client-common/hooks/useItemQuery";
11
- import { useArray as d } from "@gen-epix/ui-core/hooks/useArray";
12
- import { TestIdUtil as f } from "@gen-epix/ui-core/utils/TestIdUtil";
4
+ import { CaseDbCaseApi as r } from "@gen-epix/api-casedb";
5
+ import { useEffect as i, useMemo as a } from "react";
6
+ import { useTranslation as o } from "react-i18next";
7
+ import { jsx as s } from "react/jsx-runtime";
8
+ import { ResponseHandler as c } from "@gen-epix/ui-client-common/components/ui/ResponseHandler";
9
+ import { useItemQuery as l } from "@gen-epix/ui-client-common/hooks/useItemQuery";
10
+ import { useArray as u } from "@gen-epix/ui-core/hooks/useArray";
11
+ import { TestIdUtil as d } from "@gen-epix/ui-core/utils/TestIdUtil";
12
+ import { useParams as f } from "react-router-dom";
13
13
  import { PageContainer as p } from "@gen-epix/ui-client-common/components/ui/PageContainer";
14
14
  import { useUpdateBreadcrumb as m } from "@gen-epix/ui-client-common/hooks/useUpdateBreadcrumb";
15
15
  //#region src/pages/EventsDetailPage/EventsDetailPage.tsx
16
16
  var h = () => {
17
- let { t: h } = s(), { caseSetId: g, slug: _ } = r(), v = t(), y = m("Event"), b = u({
17
+ let { t: h } = o(), { caseSetId: g, slug: _ } = f(), v = t(), y = m("Event"), b = l({
18
18
  baseQueryKey: e.CASE_SETS,
19
19
  itemId: g,
20
- useQueryOptions: { queryFn: async ({ signal: e }) => (await i.getInstance().caseSetsGetOne(g, { signal: e })).data }
21
- }), x = o(() => {
20
+ useQueryOptions: { queryFn: async ({ signal: e }) => (await r.getInstance().caseSetsGetOne(g, { signal: e })).data }
21
+ }), x = a(() => {
22
22
  if (!b.data) return h`Event`;
23
23
  let e = v.isLoading || !v.map.has(b.data.case_type_id) ? "⌛" : v.map.get(b.data.case_type_id).name;
24
24
  return `${b.data.name} (${e})`;
@@ -28,22 +28,22 @@ var h = () => {
28
28
  v.map,
29
29
  h
30
30
  ]);
31
- a(() => {
31
+ i(() => {
32
32
  y(x);
33
33
  }, [x, y]);
34
- let S = d([v, b]);
35
- return /* @__PURE__ */ c(p, {
34
+ let S = u([v, b]);
35
+ return /* @__PURE__ */ s(p, {
36
36
  fullHeight: !0,
37
37
  fullWidth: !0,
38
38
  showBreadcrumbs: !0,
39
- testIdAttributes: f.createAttributes("EventsDetailPage", {
39
+ testIdAttributes: d.createAttributes("EventsDetailPage", {
40
40
  "case-set-id": g,
41
41
  slug: _
42
42
  }),
43
43
  title: x,
44
- children: /* @__PURE__ */ c(l, {
44
+ children: /* @__PURE__ */ s(c, {
45
45
  loadables: S,
46
- children: /* @__PURE__ */ c(n, {
46
+ children: /* @__PURE__ */ s(n, {
47
47
  caseSet: b.data,
48
48
  caseTypeId: b.data?.case_type_id
49
49
  })