diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 5c5e288..f7e7642 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,7 +8,9 @@ "name": "frontend", "version": "0.0.1", "dependencies": { + "@dagrejs/dagre": "github:dagrejs/dagre", "@xyflow/svelte": "^0.0.41", + "oidc-client-ts": "^3.0.1", "svelte-eslint-parser": "^0.33.1" }, "devDependencies": { @@ -572,6 +574,22 @@ "node": ">=6.9.0" } }, + "node_modules/@dagrejs/dagre": { + "version": "1.1.3-pre", + "resolved": "git+ssh://git@github.com/dagrejs/dagre.git#e6d4c7f6f95834fc794d82e6c803ead3aa3816d2", + "license": "MIT", + "dependencies": { + "@dagrejs/graphlib": "2.2.2" + } + }, + "node_modules/@dagrejs/graphlib": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.2.2.tgz", + "integrity": "sha512-CbyGpCDKsiTg/wuk79S7Muoj8mghDGAESWGxcSyhHX5jD35vYMBZochYVFzlHxynpE9unpu6O+4ZuhrLxASsOg==", + "engines": { + "node": ">17.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", @@ -3205,6 +3223,14 @@ "node": ">=6" } }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "engines": { + "node": ">=18" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -3480,6 +3506,17 @@ "node": ">= 6" } }, + "node_modules/oidc-client-ts": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-3.0.1.tgz", + "integrity": "sha512-xX8unZNtmtw3sOz4FPSqDhkLFnxCDsdo2qhFEH2opgWnF/iXMFoYdBQzkwCxAZVgt3FT3DnuBY3k80EZHT0RYg==", + "dependencies": { + "jwt-decode": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 68495df..0f24fc8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,7 +30,9 @@ }, "type": "module", "dependencies": { + "@dagrejs/dagre": "github:dagrejs/dagre", "@xyflow/svelte": "^0.0.41", + "oidc-client-ts": "^3.0.1", "svelte-eslint-parser": "^0.33.1" } } diff --git a/frontend/src/app.html b/frontend/src/app.html index 929e4b5..b8fadaf 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -1,51 +1,79 @@ - + + + + + + %sveltekit.head% + - - - - - %sveltekit.head% - - - -
%sveltekit.body%
- ({})); + +const nodeWidth = 172; +const nodeHeight = 36; + +function getLayoutedElements(nodes: Node[], edges: Edge[], direction = 'TB') { + const isHorizontal = direction === 'LR'; + dagreGraph.setGraph({ rankdir: direction }); + + nodes.forEach((node) => { + dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight }); + }); + + edges.forEach((edge) => { + dagreGraph.setEdge(edge.source, edge.target); + }); + + dagre.layout(dagreGraph); + + nodes.forEach((node) => { + const nodeWithPosition = dagreGraph.node(node.id); + node.targetPosition = isHorizontal ? Position.Left : Position.Top; + node.sourcePosition = isHorizontal ? Position.Right : Position.Bottom; + + // We are shifting the dagre node position (anchor=center center) to the top left + // so it matches the React Flow node anchor point (top left). + node.position = { + x: nodeWithPosition.x - nodeWidth / 2, + y: nodeWithPosition.y - nodeHeight / 2 + }; + }); + + return { nodes, edges }; +} + +export { getLayoutedElements }; diff --git a/frontend/src/lib/family_tree/getFamilyTree.ts b/frontend/src/lib/family_tree/getFamilyTree.ts new file mode 100644 index 0000000..2727bc4 --- /dev/null +++ b/frontend/src/lib/family_tree/getFamilyTree.ts @@ -0,0 +1,27 @@ +import { PUBLIC_API_URL } from '$env/static/public'; +import { user } from '$lib/stores'; + +let auth_token: string; + +user.subscribe((value) => { + if (value) { + auth_token = value.access_token; + } +}); + +async function fetch_family_tree() { + const response = await fetch( + { PUBLIC_API_URL } + '/familyTree?id=8a8b9b05bdc24550a5cc73e0b55e8d7d', + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: auth_token + } + } + ); + const data = await response.json(); + return data; +} + +export { fetch_family_tree }; diff --git a/frontend/src/lib/stores.ts b/frontend/src/lib/stores.ts new file mode 100644 index 0000000..08cee58 --- /dev/null +++ b/frontend/src/lib/stores.ts @@ -0,0 +1,5 @@ +import { writable } from 'svelte/store'; +import type { User } from 'oidc-client-ts'; + +export const isAuthenticated = writable(false); +export const user = writable(null); diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index c698ada..2cf8c5e 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -1,47 +1,78 @@ -
- - + + diff --git a/frontend/src/routes/callback/+page.svelte b/frontend/src/routes/callback/+page.svelte new file mode 100644 index 0000000..234dfe6 --- /dev/null +++ b/frontend/src/routes/callback/+page.svelte @@ -0,0 +1,11 @@ + + + +
Logging in...
diff --git a/frontend/src/routes/siltent-refresh/+page.svelte b/frontend/src/routes/siltent-refresh/+page.svelte new file mode 100644 index 0000000..9914605 --- /dev/null +++ b/frontend/src/routes/siltent-refresh/+page.svelte @@ -0,0 +1,10 @@ + + +
Refreshing...
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json new file mode 100644 index 0000000..2200a64 --- /dev/null +++ b/frontend/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + }, + "include": ["src/**/*", "src/node_modules", ".svelte-kit/ambient.d.ts"] // see last element +}