@k-4u/resource-mapper-core 0.0.1 → 0.1.0

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 (248) hide show
  1. package/coverage/junit.xml +17 -17
  2. package/coverage/test-results.json +1 -1
  3. package/data/services/api/api-gateway.yaml +18 -18
  4. package/data/services/api/group-info.yaml +7 -7
  5. package/data/services/api/lambda-orders.yaml +21 -21
  6. package/data/services/api/lambda-products.yaml +15 -15
  7. package/data/services/api/lambda-users.yaml +15 -15
  8. package/data/services/compute/alb.yaml +15 -15
  9. package/data/services/compute/ecs-inventory.yaml +16 -16
  10. package/data/services/compute/ecs-notification.yaml +15 -15
  11. package/data/services/compute/group-info.yaml +7 -7
  12. package/data/services/data/dynamodb-notifications.yaml +12 -12
  13. package/data/services/data/dynamodb-orders.yaml +9 -9
  14. package/data/services/data/dynamodb-products.yaml +9 -9
  15. package/data/services/data/dynamodb-users.yaml +9 -9
  16. package/data/services/data/group-info.yaml +7 -7
  17. package/data/services/data/rds-postgres.yaml +9 -9
  18. package/data/services/data/redis.yaml +10 -10
  19. package/data/services/frontend/cloudfront.yaml +12 -12
  20. package/data/services/frontend/group-info.yaml +7 -7
  21. package/data/services/frontend/route53.yaml +15 -15
  22. package/data/services/frontend/s3-website.yaml +9 -9
  23. package/data/teams/cloud-shepherds.yaml +15 -15
  24. package/data/teams/data-wizards.yaml +15 -15
  25. package/data/teams/interface-architects.yaml +18 -18
  26. package/e2e/demo.test.ts +54 -54
  27. package/e2e/header-toolbar.spec.ts +53 -53
  28. package/e2e/layout.spec.ts +30 -30
  29. package/package.json +74 -69
  30. package/playwright.config.ts +10 -10
  31. package/plugins/mapper-data-plugin.ts +32 -32
  32. package/project.json +22 -22
  33. package/src/app.css +125 -125
  34. package/src/app.d.ts +31 -31
  35. package/src/app.html +11 -11
  36. package/src/lib/assets/favicon.svg +18 -18
  37. package/src/lib/components/EmptyState.svelte +37 -37
  38. package/src/lib/components/ErrorDisplay.svelte +82 -82
  39. package/src/lib/components/FlowCanvas.svelte +223 -223
  40. package/src/lib/components/GenericSidebarCard.svelte +43 -43
  41. package/src/lib/components/GroupDetailSidebar.svelte +31 -31
  42. package/src/lib/components/Header.svelte +57 -57
  43. package/src/lib/components/Legend.svelte +25 -25
  44. package/src/lib/components/LoadingOverlay.svelte +42 -42
  45. package/src/lib/components/LoadingSpinner.svelte +10 -10
  46. package/src/lib/components/ServiceDetailSidebar.svelte +89 -89
  47. package/src/lib/components/TeamContactCard.svelte +166 -166
  48. package/src/lib/components/flow/ExternalNode.svelte +45 -45
  49. package/src/lib/components/flow/MainGroupNode.svelte +24 -24
  50. package/src/lib/components/flow/ServiceGroupNode.svelte +17 -17
  51. package/src/lib/components/flow/ServiceNode.svelte +40 -40
  52. package/src/lib/components/flow/SnakeEdge.svelte +206 -206
  53. package/src/lib/components/flow/index.ts +5 -5
  54. package/src/lib/components/index.ts +12 -12
  55. package/src/lib/data/connections.ts +26 -26
  56. package/src/lib/data/groups.ts +11 -11
  57. package/src/lib/data/services.ts +12 -12
  58. package/src/lib/data/teams.ts +11 -11
  59. package/src/lib/index.ts +1 -1
  60. package/src/lib/state/theme.svelte.ts +21 -21
  61. package/src/lib/stores/diagram.ts +6 -6
  62. package/src/lib/stores/routingStore.test.ts +133 -133
  63. package/src/lib/stores/routingStore.ts +232 -232
  64. package/src/lib/utils/awsIcons.ts +117 -117
  65. package/src/lib/utils/flow/groupOverviewGraph.ts +73 -73
  66. package/src/lib/utils/flow/helpers.ts +14 -14
  67. package/src/lib/utils/flow/layout.test.ts +271 -271
  68. package/src/lib/utils/flow/layout.ts +240 -240
  69. package/src/lib/utils/flow/serviceIds.ts +4 -4
  70. package/src/lib/utils/flow/servicesGraph.test.ts +119 -119
  71. package/src/lib/utils/flow/servicesGraph.ts +258 -258
  72. package/src/routes/+error.svelte +36 -36
  73. package/src/routes/+layout.svelte +27 -27
  74. package/src/routes/+page.svelte +81 -81
  75. package/src/routes/+page.ts +31 -31
  76. package/src/routes/group/[groupId]/+page.svelte +102 -102
  77. package/src/routes/group/[groupId]/+page.ts +48 -48
  78. package/static/static/robots.txt +3 -3
  79. package/svelte.config.js +27 -27
  80. package/tailwind.config.js +12 -12
  81. package/tsconfig.json +22 -22
  82. package/vite.config.ts +80 -80
  83. package/.aws-icons-last-updated +0 -1
  84. package/.svelte-kit/ambient.d.ts +0 -263
  85. package/.svelte-kit/generated/client/app.js +0 -31
  86. package/.svelte-kit/generated/client/matchers.js +0 -1
  87. package/.svelte-kit/generated/client/nodes/0.js +0 -1
  88. package/.svelte-kit/generated/client/nodes/1.js +0 -1
  89. package/.svelte-kit/generated/client/nodes/2.js +0 -3
  90. package/.svelte-kit/generated/client/nodes/3.js +0 -3
  91. package/.svelte-kit/generated/client-optimized/app.js +0 -31
  92. package/.svelte-kit/generated/client-optimized/matchers.js +0 -1
  93. package/.svelte-kit/generated/client-optimized/nodes/0.js +0 -1
  94. package/.svelte-kit/generated/client-optimized/nodes/1.js +0 -1
  95. package/.svelte-kit/generated/client-optimized/nodes/2.js +0 -3
  96. package/.svelte-kit/generated/client-optimized/nodes/3.js +0 -3
  97. package/.svelte-kit/generated/root.js +0 -3
  98. package/.svelte-kit/generated/root.svelte +0 -68
  99. package/.svelte-kit/generated/server/internal.js +0 -53
  100. package/.svelte-kit/non-ambient.d.ts +0 -43
  101. package/.svelte-kit/output/client/.vite/manifest.json +0 -175
  102. package/.svelte-kit/output/client/_app/immutable/assets/0.Czt_67iE.css +0 -1
  103. package/.svelte-kit/output/client/_app/immutable/assets/TeamContactCard.Dxj5nUCr.css +0 -1
  104. package/.svelte-kit/output/client/_app/immutable/assets/helpers.ysDrpaDf.css +0 -1
  105. package/.svelte-kit/output/client/_app/immutable/assets/libavoid.DQJapW5w.wasm +0 -0
  106. package/.svelte-kit/output/client/_app/immutable/chunks/BlLuv0eP.js +0 -46
  107. package/.svelte-kit/output/client/_app/immutable/chunks/CSBHmwYv.js +0 -1
  108. package/.svelte-kit/output/client/_app/immutable/chunks/CTCi5ueQ.js +0 -1
  109. package/.svelte-kit/output/client/_app/immutable/chunks/CfOzjaik.js +0 -2
  110. package/.svelte-kit/output/client/_app/immutable/chunks/D4PdvFNs.js +0 -1
  111. package/.svelte-kit/output/client/_app/immutable/chunks/DXgP-QUS.js +0 -2
  112. package/.svelte-kit/output/client/_app/immutable/chunks/DlbDC5An.js +0 -1
  113. package/.svelte-kit/output/client/_app/immutable/chunks/wRWe7aK9.js +0 -1
  114. package/.svelte-kit/output/client/_app/immutable/entry/app.ConrMuHl.js +0 -2
  115. package/.svelte-kit/output/client/_app/immutable/entry/start.Bm6FyGme.js +0 -1
  116. package/.svelte-kit/output/client/_app/immutable/nodes/0.d3cL-ETU.js +0 -1
  117. package/.svelte-kit/output/client/_app/immutable/nodes/1.D6z9rPGv.js +0 -1
  118. package/.svelte-kit/output/client/_app/immutable/nodes/2.CLD-8chl.js +0 -1
  119. package/.svelte-kit/output/client/_app/immutable/nodes/3.DXYeBoel.js +0 -1
  120. package/.svelte-kit/output/client/_app/version.json +0 -1
  121. package/.svelte-kit/output/client/libavoid.wasm +0 -0
  122. package/.svelte-kit/output/client/static/robots.txt +0 -3
  123. package/.svelte-kit/output/prerendered/dependencies/_app/env.js +0 -1
  124. package/.svelte-kit/output/server/.vite/manifest.json +0 -224
  125. package/.svelte-kit/output/server/_app/immutable/assets/LoadingOverlay.DBbe6V8W.css +0 -1
  126. package/.svelte-kit/output/server/_app/immutable/assets/_layout.Czt_67iE.css +0 -1
  127. package/.svelte-kit/output/server/_app/immutable/assets/_page.D9P41uDZ.css +0 -1
  128. package/.svelte-kit/output/server/chunks/ErrorDisplay.js +0 -59
  129. package/.svelte-kit/output/server/chunks/LoadingOverlay.js +0 -12
  130. package/.svelte-kit/output/server/chunks/LoadingOverlay.svelte_svelte_type_style_lang.js +0 -1671
  131. package/.svelte-kit/output/server/chunks/connections.js +0 -33
  132. package/.svelte-kit/output/server/chunks/diagram.js +0 -7
  133. package/.svelte-kit/output/server/chunks/environment.js +0 -34
  134. package/.svelte-kit/output/server/chunks/equality.js +0 -57
  135. package/.svelte-kit/output/server/chunks/exports.js +0 -174
  136. package/.svelte-kit/output/server/chunks/false.js +0 -4
  137. package/.svelte-kit/output/server/chunks/index.js +0 -59
  138. package/.svelte-kit/output/server/chunks/index2.js +0 -2939
  139. package/.svelte-kit/output/server/chunks/index3.js +0 -20
  140. package/.svelte-kit/output/server/chunks/internal.js +0 -1017
  141. package/.svelte-kit/output/server/chunks/shared.js +0 -770
  142. package/.svelte-kit/output/server/chunks/utils.js +0 -43
  143. package/.svelte-kit/output/server/entries/pages/_error.svelte.js +0 -64
  144. package/.svelte-kit/output/server/entries/pages/_layout.svelte.js +0 -65
  145. package/.svelte-kit/output/server/entries/pages/_page.svelte.js +0 -3991
  146. package/.svelte-kit/output/server/entries/pages/_page.ts.js +0 -30
  147. package/.svelte-kit/output/server/entries/pages/group/_groupId_/_page.svelte.js +0 -67
  148. package/.svelte-kit/output/server/entries/pages/group/_groupId_/_page.ts.js +0 -47
  149. package/.svelte-kit/output/server/index.js +0 -3747
  150. package/.svelte-kit/output/server/internal.js +0 -13
  151. package/.svelte-kit/output/server/manifest-full.js +0 -47
  152. package/.svelte-kit/output/server/manifest.js +0 -47
  153. package/.svelte-kit/output/server/nodes/0.js +0 -8
  154. package/.svelte-kit/output/server/nodes/1.js +0 -8
  155. package/.svelte-kit/output/server/nodes/2.js +0 -10
  156. package/.svelte-kit/output/server/nodes/3.js +0 -10
  157. package/.svelte-kit/output/server/remote-entry.js +0 -557
  158. package/.svelte-kit/tsconfig.json +0 -61
  159. package/.svelte-kit/types/route_meta_data.json +0 -8
  160. package/.svelte-kit/types/src/routes/$types.d.ts +0 -26
  161. package/.svelte-kit/types/src/routes/group/[groupId]/$types.d.ts +0 -21
  162. package/.svelte-kit/types/src/routes/group/[groupId]/proxy+page.ts +0 -49
  163. package/.svelte-kit/types/src/routes/proxy+page.ts +0 -33
  164. package/build/_app/env.js +0 -1
  165. package/build/_app/env.js.br +0 -1
  166. package/build/_app/env.js.gz +0 -0
  167. package/build/_app/immutable/assets/0.Czt_67iE.css +0 -1
  168. package/build/_app/immutable/assets/0.Czt_67iE.css.br +0 -0
  169. package/build/_app/immutable/assets/0.Czt_67iE.css.gz +0 -0
  170. package/build/_app/immutable/assets/TeamContactCard.Dxj5nUCr.css +0 -1
  171. package/build/_app/immutable/assets/TeamContactCard.Dxj5nUCr.css.br +0 -0
  172. package/build/_app/immutable/assets/TeamContactCard.Dxj5nUCr.css.gz +0 -0
  173. package/build/_app/immutable/assets/helpers.ysDrpaDf.css +0 -1
  174. package/build/_app/immutable/assets/helpers.ysDrpaDf.css.br +0 -0
  175. package/build/_app/immutable/assets/helpers.ysDrpaDf.css.gz +0 -0
  176. package/build/_app/immutable/assets/libavoid.DQJapW5w.wasm +0 -0
  177. package/build/_app/immutable/assets/libavoid.DQJapW5w.wasm.br +0 -0
  178. package/build/_app/immutable/assets/libavoid.DQJapW5w.wasm.gz +0 -0
  179. package/build/_app/immutable/chunks/BlLuv0eP.js +0 -46
  180. package/build/_app/immutable/chunks/BlLuv0eP.js.br +0 -0
  181. package/build/_app/immutable/chunks/BlLuv0eP.js.gz +0 -0
  182. package/build/_app/immutable/chunks/CSBHmwYv.js +0 -1
  183. package/build/_app/immutable/chunks/CSBHmwYv.js.br +0 -0
  184. package/build/_app/immutable/chunks/CSBHmwYv.js.gz +0 -0
  185. package/build/_app/immutable/chunks/CTCi5ueQ.js +0 -1
  186. package/build/_app/immutable/chunks/CTCi5ueQ.js.br +0 -0
  187. package/build/_app/immutable/chunks/CTCi5ueQ.js.gz +0 -0
  188. package/build/_app/immutable/chunks/CfOzjaik.js +0 -2
  189. package/build/_app/immutable/chunks/CfOzjaik.js.br +0 -0
  190. package/build/_app/immutable/chunks/CfOzjaik.js.gz +0 -0
  191. package/build/_app/immutable/chunks/D4PdvFNs.js +0 -1
  192. package/build/_app/immutable/chunks/D4PdvFNs.js.br +0 -0
  193. package/build/_app/immutable/chunks/D4PdvFNs.js.gz +0 -0
  194. package/build/_app/immutable/chunks/DXgP-QUS.js +0 -2
  195. package/build/_app/immutable/chunks/DXgP-QUS.js.br +0 -0
  196. package/build/_app/immutable/chunks/DXgP-QUS.js.gz +0 -0
  197. package/build/_app/immutable/chunks/DlbDC5An.js +0 -1
  198. package/build/_app/immutable/chunks/DlbDC5An.js.br +0 -0
  199. package/build/_app/immutable/chunks/DlbDC5An.js.gz +0 -0
  200. package/build/_app/immutable/chunks/wRWe7aK9.js +0 -1
  201. package/build/_app/immutable/chunks/wRWe7aK9.js.br +0 -0
  202. package/build/_app/immutable/chunks/wRWe7aK9.js.gz +0 -0
  203. package/build/_app/immutable/entry/app.ConrMuHl.js +0 -2
  204. package/build/_app/immutable/entry/app.ConrMuHl.js.br +0 -0
  205. package/build/_app/immutable/entry/app.ConrMuHl.js.gz +0 -0
  206. package/build/_app/immutable/entry/start.Bm6FyGme.js +0 -1
  207. package/build/_app/immutable/entry/start.Bm6FyGme.js.br +0 -2
  208. package/build/_app/immutable/entry/start.Bm6FyGme.js.gz +0 -0
  209. package/build/_app/immutable/nodes/0.d3cL-ETU.js +0 -1
  210. package/build/_app/immutable/nodes/0.d3cL-ETU.js.br +0 -0
  211. package/build/_app/immutable/nodes/0.d3cL-ETU.js.gz +0 -0
  212. package/build/_app/immutable/nodes/1.D6z9rPGv.js +0 -1
  213. package/build/_app/immutable/nodes/1.D6z9rPGv.js.br +0 -0
  214. package/build/_app/immutable/nodes/1.D6z9rPGv.js.gz +0 -0
  215. package/build/_app/immutable/nodes/2.CLD-8chl.js +0 -1
  216. package/build/_app/immutable/nodes/2.CLD-8chl.js.br +0 -0
  217. package/build/_app/immutable/nodes/2.CLD-8chl.js.gz +0 -0
  218. package/build/_app/immutable/nodes/3.DXYeBoel.js +0 -1
  219. package/build/_app/immutable/nodes/3.DXYeBoel.js.br +0 -0
  220. package/build/_app/immutable/nodes/3.DXYeBoel.js.gz +0 -0
  221. package/build/_app/version.json +0 -1
  222. package/build/_app/version.json.br +0 -0
  223. package/build/_app/version.json.gz +0 -0
  224. package/build/index.html +0 -34
  225. package/build/index.html.br +0 -0
  226. package/build/index.html.gz +0 -0
  227. package/build/libavoid.wasm +0 -0
  228. package/build/libavoid.wasm.br +0 -0
  229. package/build/libavoid.wasm.gz +0 -0
  230. package/build/static/robots.txt +0 -3
  231. package/coverage/coverage-final.json +0 -6
  232. package/coverage/coverage-summary.json +0 -7
  233. package/coverage/lcov-report/base.css +0 -224
  234. package/coverage/lcov-report/block-navigation.js +0 -87
  235. package/coverage/lcov-report/favicon.png +0 -0
  236. package/coverage/lcov-report/index.html +0 -131
  237. package/coverage/lcov-report/prettify.css +0 -1
  238. package/coverage/lcov-report/prettify.js +0 -2
  239. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  240. package/coverage/lcov-report/sorter.js +0 -210
  241. package/coverage/lcov-report/stores/index.html +0 -116
  242. package/coverage/lcov-report/stores/routingStore.ts.html +0 -781
  243. package/coverage/lcov-report/utils/flow/helpers.ts.html +0 -127
  244. package/coverage/lcov-report/utils/flow/index.html +0 -161
  245. package/coverage/lcov-report/utils/flow/layout.ts.html +0 -805
  246. package/coverage/lcov-report/utils/flow/serviceIds.ts.html +0 -97
  247. package/coverage/lcov-report/utils/flow/servicesGraph.ts.html +0 -859
  248. package/coverage/lcov.info +0 -646
@@ -1,81 +1,81 @@
1
- <script lang="ts">
2
- import type {PageData} from './$types'
3
- import {FlowCanvas, GroupDetailSidebar, LoadingSpinner, EmptyState, ErrorDisplay} from '$lib/components'
4
- import {buildGroupOverviewGraph} from '$lib/utils/flow/groupOverviewGraph'
5
- import {goto, invalidateAll} from '$app/navigation'
6
- import {SvelteFlowProvider} from "@xyflow/svelte";
7
-
8
- let { data } = $props<{ data: PageData }>()
9
-
10
- const groups = $derived(data.groups)
11
- const groupConnections = $derived(data.groupConnections)
12
- const errorMessage = $derived(data.errorMessage)
13
-
14
- let { graphInput, nodeGroupMap } = $derived.by(() => {
15
- if (groups && groupConnections) {
16
- const {graph, nodeToGroupMap} = buildGroupOverviewGraph(groups, groupConnections)
17
- console.debug('[overview.svelte] built flow graph', {
18
- groups: Object.keys(groups).length,
19
- connections: groupConnections.length,
20
- nodeCount: Object.keys(nodeToGroupMap).length,
21
- hasGraph: !!graph
22
- })
23
- return { graphInput: graph, nodeGroupMap: nodeToGroupMap }
24
- }
25
- return { graphInput: null, nodeGroupMap: {} }
26
- })
27
-
28
- let isLoading = $derived(!groups || !groupConnections)
29
- let hasDiagramContent = $derived(true)
30
-
31
- function handleNodeDoubleClick(event: CustomEvent<string>) {
32
- const groupId = nodeGroupMap[event.detail]
33
- console.debug('[overview.svelte] nodeDoubleClick', {nodeId: event.detail, groupId})
34
- if (groupId) {
35
- goto(`/group/${groupId}`)
36
- }
37
- }
38
-
39
- async function refreshData() {
40
- await invalidateAll()
41
- }
42
- </script>
43
-
44
- <svelte:head>
45
- <title>Resource Mapper – Overview</title>
46
- </svelte:head>
47
-
48
- {#if errorMessage}
49
- <ErrorDisplay
50
- title="Error loading groups"
51
- message="Failed to load the group overview diagram."
52
- checkList={[
53
- 'Ensure YAML data exists under /data/services',
54
- 'Check the browser console for more details'
55
- ]}
56
- technicalDetails={errorMessage}
57
- onRetry={refreshData}
58
- />
59
- {:else if isLoading}
60
- <LoadingSpinner message="Loading group overview..."/>
61
- {:else if !hasDiagramContent}
62
- <EmptyState title="No Groups Found" message="No group definitions were discovered in the static data set."/>
63
- {:else}
64
- <div class="flex h-full w-full gap-1 lg:flex-row">
65
- <SvelteFlowProvider>
66
- <!-- Todo: make the pending variable dependant on the actual loading of data -->
67
- <FlowCanvas
68
- graph={graphInput}
69
- pending={isLoading}
70
- on:nodeDoubleClick={handleNodeDoubleClick}
71
- />
72
- <!-- Todo: Check if we can resize this sidebar on drag -->
73
- <!-- Todo: Check if we can close the sidebar with a button in the center left of the sidebar when open -->
74
- <GroupDetailSidebar
75
- groupMap={nodeGroupMap}
76
- groups={groups ?? {}}
77
- placeholderMessage="Select a group to see details"
78
- />
79
- </SvelteFlowProvider>
80
- </div>
81
- {/if}
1
+ <script lang="ts">
2
+ import type {PageData} from './$types'
3
+ import {FlowCanvas, GroupDetailSidebar, LoadingSpinner, EmptyState, ErrorDisplay} from '$lib/components'
4
+ import {buildGroupOverviewGraph} from '$lib/utils/flow/groupOverviewGraph'
5
+ import {goto, invalidateAll} from '$app/navigation'
6
+ import {SvelteFlowProvider} from "@xyflow/svelte";
7
+
8
+ let { data } = $props<{ data: PageData }>()
9
+
10
+ const groups = $derived(data.groups)
11
+ const groupConnections = $derived(data.groupConnections)
12
+ const errorMessage = $derived(data.errorMessage)
13
+
14
+ let { graphInput, nodeGroupMap } = $derived.by(() => {
15
+ if (groups && groupConnections) {
16
+ const {graph, nodeToGroupMap} = buildGroupOverviewGraph(groups, groupConnections)
17
+ console.debug('[overview.svelte] built flow graph', {
18
+ groups: Object.keys(groups).length,
19
+ connections: groupConnections.length,
20
+ nodeCount: Object.keys(nodeToGroupMap).length,
21
+ hasGraph: !!graph
22
+ })
23
+ return { graphInput: graph, nodeGroupMap: nodeToGroupMap }
24
+ }
25
+ return { graphInput: null, nodeGroupMap: {} }
26
+ })
27
+
28
+ let isLoading = $derived(!groups || !groupConnections)
29
+ let hasDiagramContent = $derived(true)
30
+
31
+ function handleNodeDoubleClick(event: CustomEvent<string>) {
32
+ const groupId = nodeGroupMap[event.detail]
33
+ console.debug('[overview.svelte] nodeDoubleClick', {nodeId: event.detail, groupId})
34
+ if (groupId) {
35
+ goto(`/group/${groupId}`)
36
+ }
37
+ }
38
+
39
+ async function refreshData() {
40
+ await invalidateAll()
41
+ }
42
+ </script>
43
+
44
+ <svelte:head>
45
+ <title>Resource Mapper – Overview</title>
46
+ </svelte:head>
47
+
48
+ {#if errorMessage}
49
+ <ErrorDisplay
50
+ title="Error loading groups"
51
+ message="Failed to load the group overview diagram."
52
+ checkList={[
53
+ 'Ensure YAML data exists under /data/services',
54
+ 'Check the browser console for more details'
55
+ ]}
56
+ technicalDetails={errorMessage}
57
+ onRetry={refreshData}
58
+ />
59
+ {:else if isLoading}
60
+ <LoadingSpinner message="Loading group overview..."/>
61
+ {:else if !hasDiagramContent}
62
+ <EmptyState title="No Groups Found" message="No group definitions were discovered in the static data set."/>
63
+ {:else}
64
+ <div class="flex h-full w-full gap-1 lg:flex-row">
65
+ <SvelteFlowProvider>
66
+ <!-- Todo: make the pending variable dependant on the actual loading of data -->
67
+ <FlowCanvas
68
+ graph={graphInput}
69
+ pending={isLoading}
70
+ on:nodeDoubleClick={handleNodeDoubleClick}
71
+ />
72
+ <!-- Todo: Check if we can resize this sidebar on drag -->
73
+ <!-- Todo: Check if we can close the sidebar with a button in the center left of the sidebar when open -->
74
+ <GroupDetailSidebar
75
+ groupMap={nodeGroupMap}
76
+ groups={groups ?? {}}
77
+ placeholderMessage="Select a group to see details"
78
+ />
79
+ </SvelteFlowProvider>
80
+ </div>
81
+ {/if}
@@ -1,31 +1,31 @@
1
- import type {PageLoad} from './$types'
2
- import {getAllGroups} from '$lib/data/groups'
3
- import {getAllGroupConnections} from '$lib/data/connections'
4
- import {getAllTeams} from '$lib/data/teams'
5
- import {selectedGroup} from "$lib/stores/diagram";
6
-
7
- export const load: PageLoad = async () => {
8
- try {
9
- console.debug('[overview.load] start fetching data')
10
- const [groups, groupConnections, teams] = await Promise.all([
11
- getAllGroups(),
12
- getAllGroupConnections(),
13
- getAllTeams()
14
- ])
15
- console.debug('[overview.load] data fetched', {
16
- groups,
17
- groupConnections,
18
- teams
19
- })
20
- selectedGroup.set(null);
21
- return { groups, groupConnections, teams }
22
- } catch (error) {
23
- console.error('[overview.load] failed to fetch data', error)
24
- return {
25
- groups: null,
26
- groupConnections: null,
27
- teams: null,
28
- errorMessage: error instanceof Error ? error.message : 'Failed to load overview data'
29
- }
30
- }
31
- }
1
+ import type {PageLoad} from './$types'
2
+ import {getAllGroups} from '$lib/data/groups'
3
+ import {getAllGroupConnections} from '$lib/data/connections'
4
+ import {getAllTeams} from '$lib/data/teams'
5
+ import {selectedGroup} from "$lib/stores/diagram";
6
+
7
+ export const load: PageLoad = async () => {
8
+ try {
9
+ console.debug('[overview.load] start fetching data')
10
+ const [groups, groupConnections, teams] = await Promise.all([
11
+ getAllGroups(),
12
+ getAllGroupConnections(),
13
+ getAllTeams()
14
+ ])
15
+ console.debug('[overview.load] data fetched', {
16
+ groups,
17
+ groupConnections,
18
+ teams
19
+ })
20
+ selectedGroup.set(null);
21
+ return { groups, groupConnections, teams }
22
+ } catch (error) {
23
+ console.error('[overview.load] failed to fetch data', error)
24
+ return {
25
+ groups: null,
26
+ groupConnections: null,
27
+ teams: null,
28
+ errorMessage: error instanceof Error ? error.message : 'Failed to load overview data'
29
+ }
30
+ }
31
+ }
@@ -1,102 +1,102 @@
1
- <script lang="ts">
2
- import type {PageData} from './$types'
3
- import type {ExternalGroupServices, GroupInfo, ServiceDefinition} from '$shared/types'
4
- import {FlowCanvas, LoadingOverlay, ErrorDisplay, EmptyState, ServiceDetailSidebar} from '$lib/components';
5
- import type {FlowGraphInput} from '$shared/flow-types'
6
- import {buildGroupServicesGraph} from '$lib/utils/flow/servicesGraph'
7
- import {goto} from '$app/navigation'
8
- import {SvelteFlowProvider} from '@xyflow/svelte';
9
- import {selectedGroup} from "$lib/stores/diagram";
10
-
11
- let {data}: { data: PageData } = $props()
12
-
13
- let group = $derived(data.group)
14
- let allGroups = $derived(data.groups)
15
- let groupConnections = $derived(data.connections)
16
- let services: ServiceDefinition[] = $derived(data.services ?? [])
17
- let externalServices: ExternalGroupServices[] = $derived(data.externalServices ?? [])
18
- let groupId = $derived(data.groupId)
19
-
20
- let serviceNodeLookup = $state<Record<string, ServiceDefinition>>({})
21
- let externalServiceLookup = $state<Record<string, { service: ServiceDefinition; group: GroupInfo }>>({})
22
- let externalGroupNodeLookup = $state<Record<string, string>>({})
23
- let groupGraph = $state<FlowGraphInput | null>(null)
24
- let loadError = $state<string | null>(null)
25
- let hasDiagramContent = $derived(!!(groupGraph && groupGraph.serviceNodes.length > 0))
26
-
27
-
28
- $effect(() => {
29
- if (!group) {
30
- loadError = groupId ? `Unable to load group '${groupId}'.` : 'Missing group identifier.'
31
- } else {
32
- loadError = null
33
- selectedGroup.set(data.group)
34
- }
35
- })
36
-
37
- $effect(() => {
38
- if (group) {
39
- const result = buildGroupServicesGraph(group, services, allGroups, groupConnections, externalServices)
40
- groupGraph = result.graph
41
- serviceNodeLookup = result.serviceNodes
42
- externalServiceLookup = result.externalNodes
43
- externalGroupNodeLookup = Object.entries(result.externalNodes).reduce<Record<string, string>>((acc, [nodeId, entry]) => {
44
- acc[nodeId] = entry.group.groupName
45
- return acc
46
- }, {})
47
- console.debug('[group.svelte] built flow graph', {
48
- group: group.groupName,
49
- services: services.length,
50
- externalEntries: externalServices.length,
51
- })
52
- } else {
53
- groupGraph = null
54
- serviceNodeLookup = {}
55
- externalServiceLookup = {}
56
- externalGroupNodeLookup = {}
57
- }
58
- })
59
-
60
- function handleNodeDoubleClick(event: CustomEvent<string>) {
61
- const nodeId = event.detail
62
- const externalGroupId = externalGroupNodeLookup[nodeId]
63
- console.debug('[group.svelte] nodeDoubleClick', {nodeId, externalGroupId})
64
- if (externalGroupId) {
65
- goto(`/group/${externalGroupId}`)
66
- }
67
- }
68
- </script>
69
-
70
- <svelte:head>
71
- <title>Resource Mapper – {group?.name ?? 'Group'}</title>
72
- </svelte:head>
73
-
74
- {#if loadError}
75
- <ErrorDisplay
76
- title="Unable to load group"
77
- message={loadError}
78
- checkList={['Verify the group identifier in the URL', 'Ensure the YAML definition exists']}
79
- onBack={() => goto('/')}
80
- />
81
- {:else if !group}
82
- <LoadingOverlay message="Loading group..."/>
83
- {:else if !hasDiagramContent}
84
- <EmptyState title="No services" message="This group has no service diagram to display yet."/>
85
- {:else}
86
- <div class="flex h-full w-full gap-1 lg:flex-row">
87
- <SvelteFlowProvider>
88
- <FlowCanvas
89
- graph={groupGraph}
90
- pending={false}
91
- on:nodeDoubleClick={handleNodeDoubleClick}
92
- />
93
- <!-- on:nodeClick={handleNodeClick}-->
94
-
95
- <ServiceDetailSidebar
96
- {group}
97
- {serviceNodeLookup}
98
- {externalServiceLookup}
99
- />
100
- </SvelteFlowProvider>
101
- </div>
102
- {/if}
1
+ <script lang="ts">
2
+ import type {PageData} from './$types'
3
+ import type {ExternalGroupServices, GroupInfo, ServiceDefinition} from '$shared/types'
4
+ import {FlowCanvas, LoadingOverlay, ErrorDisplay, EmptyState, ServiceDetailSidebar} from '$lib/components';
5
+ import type {FlowGraphInput} from '$shared/flow-types'
6
+ import {buildGroupServicesGraph} from '$lib/utils/flow/servicesGraph'
7
+ import {goto} from '$app/navigation'
8
+ import {SvelteFlowProvider} from '@xyflow/svelte';
9
+ import {selectedGroup} from "$lib/stores/diagram";
10
+
11
+ let {data}: { data: PageData } = $props()
12
+
13
+ let group = $derived(data.group)
14
+ let allGroups = $derived(data.groups)
15
+ let groupConnections = $derived(data.connections)
16
+ let services: ServiceDefinition[] = $derived(data.services ?? [])
17
+ let externalServices: ExternalGroupServices[] = $derived(data.externalServices ?? [])
18
+ let groupId = $derived(data.groupId)
19
+
20
+ let serviceNodeLookup = $state<Record<string, ServiceDefinition>>({})
21
+ let externalServiceLookup = $state<Record<string, { service: ServiceDefinition; group: GroupInfo }>>({})
22
+ let externalGroupNodeLookup = $state<Record<string, string>>({})
23
+ let groupGraph = $state<FlowGraphInput | null>(null)
24
+ let loadError = $state<string | null>(null)
25
+ let hasDiagramContent = $derived(!!(groupGraph && groupGraph.serviceNodes.length > 0))
26
+
27
+
28
+ $effect(() => {
29
+ if (!group) {
30
+ loadError = groupId ? `Unable to load group '${groupId}'.` : 'Missing group identifier.'
31
+ } else {
32
+ loadError = null
33
+ selectedGroup.set(data.group)
34
+ }
35
+ })
36
+
37
+ $effect(() => {
38
+ if (group) {
39
+ const result = buildGroupServicesGraph(group, services, allGroups, groupConnections, externalServices)
40
+ groupGraph = result.graph
41
+ serviceNodeLookup = result.serviceNodes
42
+ externalServiceLookup = result.externalNodes
43
+ externalGroupNodeLookup = Object.entries(result.externalNodes).reduce<Record<string, string>>((acc, [nodeId, entry]) => {
44
+ acc[nodeId] = entry.group.groupName
45
+ return acc
46
+ }, {})
47
+ console.debug('[group.svelte] built flow graph', {
48
+ group: group.groupName,
49
+ services: services.length,
50
+ externalEntries: externalServices.length,
51
+ })
52
+ } else {
53
+ groupGraph = null
54
+ serviceNodeLookup = {}
55
+ externalServiceLookup = {}
56
+ externalGroupNodeLookup = {}
57
+ }
58
+ })
59
+
60
+ function handleNodeDoubleClick(event: CustomEvent<string>) {
61
+ const nodeId = event.detail
62
+ const externalGroupId = externalGroupNodeLookup[nodeId]
63
+ console.debug('[group.svelte] nodeDoubleClick', {nodeId, externalGroupId})
64
+ if (externalGroupId) {
65
+ goto(`/group/${externalGroupId}`)
66
+ }
67
+ }
68
+ </script>
69
+
70
+ <svelte:head>
71
+ <title>Resource Mapper – {group?.name ?? 'Group'}</title>
72
+ </svelte:head>
73
+
74
+ {#if loadError}
75
+ <ErrorDisplay
76
+ title="Unable to load group"
77
+ message={loadError}
78
+ checkList={['Verify the group identifier in the URL', 'Ensure the YAML definition exists']}
79
+ onBack={() => goto('/')}
80
+ />
81
+ {:else if !group}
82
+ <LoadingOverlay message="Loading group..."/>
83
+ {:else if !hasDiagramContent}
84
+ <EmptyState title="No services" message="This group has no service diagram to display yet."/>
85
+ {:else}
86
+ <div class="flex h-full w-full gap-1 lg:flex-row">
87
+ <SvelteFlowProvider>
88
+ <FlowCanvas
89
+ graph={groupGraph}
90
+ pending={false}
91
+ on:nodeDoubleClick={handleNodeDoubleClick}
92
+ />
93
+ <!-- on:nodeClick={handleNodeClick}-->
94
+
95
+ <ServiceDetailSidebar
96
+ {group}
97
+ {serviceNodeLookup}
98
+ {externalServiceLookup}
99
+ />
100
+ </SvelteFlowProvider>
101
+ </div>
102
+ {/if}
@@ -1,48 +1,48 @@
1
- import type {PageLoad} from './$types'
2
- import {error} from '@sveltejs/kit'
3
- import {getGroup} from '$lib/data/groups'
4
- import {getExternalServicesForGroup, getServicesByGroup} from '$lib/data/services'
5
- import {getAllTeams} from '$lib/data/teams'
6
- import type {GroupInfo} from "$shared/types";
7
- import {getConnectionsFromGroup, getConnectionsToGroup} from "$lib/data/connections";
8
-
9
- export const load: PageLoad = async ({params}) => {
10
- const {groupId} = params
11
- if (!groupId) {
12
- throw error(400, 'Missing group identifier')
13
- }
14
-
15
- const [services, externalServices, teams, connectionsFrom, connectionsTo] = await Promise.all([
16
- getServicesByGroup(groupId),
17
- getExternalServicesForGroup(groupId),
18
- getAllTeams(),
19
- getConnectionsFromGroup(groupId),
20
- getConnectionsToGroup(groupId)
21
- ])
22
-
23
- const groupInfo = await getGroup(groupId);
24
- if (!groupInfo) {
25
- throw error(404, `Unknown group '${groupId}'`)
26
- }
27
-
28
- const allGroups: Map<string, GroupInfo> = new Map();
29
- allGroups.set(groupInfo.id, groupInfo)
30
-
31
- externalServices.forEach((externalService) => {
32
- if (!allGroups.has(externalService.group.id)) {
33
- allGroups.set(externalService.group.id, externalService.group)
34
- }
35
- })
36
- const allConnections = connectionsFrom.concat(connectionsTo);
37
-
38
- return {
39
- groupId,
40
- group: groupInfo,
41
- groups: allGroups,
42
- connections: allConnections,
43
- services,
44
- externalServices,
45
- teams
46
- }
47
- }
48
-
1
+ import type {PageLoad} from './$types'
2
+ import {error} from '@sveltejs/kit'
3
+ import {getGroup} from '$lib/data/groups'
4
+ import {getExternalServicesForGroup, getServicesByGroup} from '$lib/data/services'
5
+ import {getAllTeams} from '$lib/data/teams'
6
+ import type {GroupInfo} from "$shared/types";
7
+ import {getConnectionsFromGroup, getConnectionsToGroup} from "$lib/data/connections";
8
+
9
+ export const load: PageLoad = async ({params}) => {
10
+ const {groupId} = params
11
+ if (!groupId) {
12
+ throw error(400, 'Missing group identifier')
13
+ }
14
+
15
+ const [services, externalServices, teams, connectionsFrom, connectionsTo] = await Promise.all([
16
+ getServicesByGroup(groupId),
17
+ getExternalServicesForGroup(groupId),
18
+ getAllTeams(),
19
+ getConnectionsFromGroup(groupId),
20
+ getConnectionsToGroup(groupId)
21
+ ])
22
+
23
+ const groupInfo = await getGroup(groupId);
24
+ if (!groupInfo) {
25
+ throw error(404, `Unknown group '${groupId}'`)
26
+ }
27
+
28
+ const allGroups: Map<string, GroupInfo> = new Map();
29
+ allGroups.set(groupInfo.id, groupInfo)
30
+
31
+ externalServices.forEach((externalService) => {
32
+ if (!allGroups.has(externalService.group.id)) {
33
+ allGroups.set(externalService.group.id, externalService.group)
34
+ }
35
+ })
36
+ const allConnections = connectionsFrom.concat(connectionsTo);
37
+
38
+ return {
39
+ groupId,
40
+ group: groupInfo,
41
+ groups: allGroups,
42
+ connections: allConnections,
43
+ services,
44
+ externalServices,
45
+ teams
46
+ }
47
+ }
48
+
@@ -1,3 +1,3 @@
1
- # allow crawling everything by default
2
- User-agent: *
3
- Disallow:
1
+ # allow crawling everything by default
2
+ User-agent: *
3
+ Disallow:
package/svelte.config.js CHANGED
@@ -1,28 +1,28 @@
1
- import adapter from '@sveltejs/adapter-static';
2
- import path from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
-
5
- const dirname = path.dirname(fileURLToPath(import.meta.url));
6
-
7
- const outDir = process.env.MAPPER_BUILD_OUT || 'build';
8
-
9
- /** @type {import('@sveltejs/kit').Config} */
10
- const config = {
11
- kit: {
12
- adapter: adapter({
13
- pages: outDir,
14
- assets: outDir,
15
- fallback: "index.html",
16
- precompress: true,
17
- strict: true
18
- }),
19
- prerender: {
20
- entries: ['*']
21
- },
22
- alias: {
23
- $shared: path.resolve(dirname, '../shared/src'),
24
- }
25
- }
26
- };
27
-
1
+ import adapter from '@sveltejs/adapter-static';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ const dirname = path.dirname(fileURLToPath(import.meta.url));
6
+
7
+ const outDir = process.env.MAPPER_BUILD_OUT || 'build';
8
+
9
+ /** @type {import('@sveltejs/kit').Config} */
10
+ const config = {
11
+ kit: {
12
+ adapter: adapter({
13
+ pages: outDir,
14
+ assets: outDir,
15
+ fallback: "index.html",
16
+ precompress: true,
17
+ strict: true
18
+ }),
19
+ prerender: {
20
+ entries: ['*']
21
+ },
22
+ alias: {
23
+ $shared: path.resolve(dirname, '../shared/src'),
24
+ }
25
+ }
26
+ };
27
+
28
28
  export default config;
@@ -1,12 +1,12 @@
1
- module.exports = {
2
- darkMode: 'class',
3
- content: [
4
- './src/**/*.{html,js,svelte,ts}',
5
- '../shared/src/**/*.{ts}',
6
- '../engine/src/**/*.{ts}'
7
- ],
8
- theme: {
9
- extend: {},
10
- },
11
- plugins: [],
12
- };
1
+ module.exports = {
2
+ darkMode: 'class',
3
+ content: [
4
+ './src/**/*.{html,js,svelte,ts}',
5
+ '../shared/src/**/*.{ts}',
6
+ '../engine/src/**/*.{ts}'
7
+ ],
8
+ theme: {
9
+ extend: {},
10
+ },
11
+ plugins: [],
12
+ };
package/tsconfig.json CHANGED
@@ -1,22 +1,22 @@
1
- {
2
- "extends": [
3
- "../../tsconfig.base.json",
4
- "./.svelte-kit/tsconfig.json"
5
- ],
6
- "compilerOptions": {
7
- "outDir": "dist"
8
- },
9
- "include": [
10
- "src",
11
- ".",
12
- "src/app.d.ts"
13
- ],
14
- "references": [
15
- {
16
- "path": "../shared"
17
- },
18
- {
19
- "path": "../engine"
20
- }
21
- ]
22
- }
1
+ {
2
+ "extends": [
3
+ "../../tsconfig.base.json",
4
+ "./.svelte-kit/tsconfig.json"
5
+ ],
6
+ "compilerOptions": {
7
+ "outDir": "dist"
8
+ },
9
+ "include": [
10
+ "src",
11
+ ".",
12
+ "src/app.d.ts"
13
+ ],
14
+ "references": [
15
+ {
16
+ "path": "../shared"
17
+ },
18
+ {
19
+ "path": "../engine"
20
+ }
21
+ ]
22
+ }