- {#if isConnecting && isTarget}
-
- {/if}

{
- let newEdge = { data: { ...relationship.properties } } as Edge;
- if (relationship.start !== null && relationship.start !== undefined) {
- newEdge.source = relationship.start.toString();
+ let newEdge = { data: { ...relationship.Props } } as Edge;
+ newEdge.data!.type = relationship.Type?.toLowerCase();
+ if (relationship.StartElementId !== null && relationship.StartElementId !== undefined) {
+ newEdge.source = relationship.StartElementId;
}
- if (relationship.end !== null && relationship.end !== undefined) {
- newEdge.target = relationship.end.toString();
+ if (relationship.EndElementId !== null && relationship.EndElementId !== undefined) {
+ newEdge.target = relationship.EndElementId;
}
return newEdge;
diff --git a/apps/app/src/lib/graph/layout.ts b/apps/app/src/lib/graph/layout.ts
index 4f3c963..46c0ab6 100644
--- a/apps/app/src/lib/graph/layout.ts
+++ b/apps/app/src/lib/graph/layout.ts
@@ -2,7 +2,6 @@ import dagre from '@dagrejs/dagre';
import type { Layout } from './model';
import type { Edge, Node } from '@xyflow/svelte';
import { Position } from '@xyflow/svelte';
-import PersonNode from './PersonNode.svelte';
export class FamilyTree extends dagre.graphlib.Graph {
constructor() {
@@ -18,27 +17,25 @@ export class FamilyTree extends dagre.graphlib.Graph {
): Layout {
const isHorizontal = direction === 'LR';
this.setGraph({ rankdir: direction });
-
+ this.setDefaultEdgeLabel(() => ({}))
nodes.forEach((node) => {
- this.setNode(node.id, { width: nodeWidth, height: nodeHeight});
+ this.setNode(node.id, { width: nodeWidth, height: nodeHeight });
});
edges.forEach((edge) => {
- if (edge.data?.type === 'child') {
+ if (edge.data!.type === 'child') {
this.setEdge(edge.source, edge.target);
}
});
dagre.layout(this);
+ let newEdges: Edge[] = [];
edges.forEach((edge) => {
- if (edge.data?.type === 'parent' || edge.data?.type === 'sibling') {
- this.setEdge(edge.source, edge.target);
- }
- });
-
- edges.forEach((edge) => {
+ let newEdge = edge;
if (edge.data?.type === 'spouse') {
+ newEdge.style = "dashed; stroke: #000; stroke-width: 2px; color: red;";
+
const sourceNode = this.node(edge.source);
const targetNode = this.node(edge.target);
@@ -80,6 +77,10 @@ export class FamilyTree extends dagre.graphlib.Graph {
targetNode.x = desiredX;
targetNode.y = sourceNode.y;
}
+ newEdge.type = 'smoothstep'
+
+
+ newEdges.push(newEdge);
});
const layoutedNodes = nodes.map((node) => {
@@ -91,7 +92,7 @@ export class FamilyTree extends dagre.graphlib.Graph {
// so it matches the React Flow node anchor point (top left).
return {
...node,
- type: 'personNode',
+ type: 'personNode',
position: {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2
diff --git a/apps/app/src/lib/graph/model.ts b/apps/app/src/lib/graph/model.ts
index 394e68f..1f5f608 100644
--- a/apps/app/src/lib/graph/model.ts
+++ b/apps/app/src/lib/graph/model.ts
@@ -1,5 +1,5 @@
import type { Node, Edge, NodeTypes } from '@xyflow/svelte';
-import PersonNode from './PersonNode.svelte';
+import PersonNode from './PersonNode.svelte';
export const nodeTypes: NodeTypes = { personNode: PersonNode };
diff --git a/apps/app/src/routes/+page.server.ts b/apps/app/src/routes/+page.server.ts
index c017f1e..7024d20 100644
--- a/apps/app/src/routes/+page.server.ts
+++ b/apps/app/src/routes/+page.server.ts
@@ -3,6 +3,7 @@ import { parseFamilyTree } from '$lib/graph/fetch_family_tree';
import type { components } from '$lib/api/api.gen';
import type { RequestEvent } from './$types';
import { browser } from '$app/environment';
+import type { Layout } from '$lib/graph/model';
export async function load(event: RequestEvent) {
if (event.locals.session === null /*|| event.locals.familytree === nul*/) {
@@ -24,7 +25,8 @@ export async function load(event: RequestEvent) {
const data = (await response.json()) as components['schemas']['FamilyTree'];
- let layout = parseFamilyTree(data)
+ let layout = parseFamilyTree(data) as Layout & {id: string};
+ layout.id = event.locals.session.userId;
return layout;
}
diff --git a/apps/app/src/routes/+page.svelte b/apps/app/src/routes/+page.svelte
index 333761c..6efb3e6 100644
--- a/apps/app/src/routes/+page.svelte
+++ b/apps/app/src/routes/+page.svelte
@@ -26,7 +26,7 @@
import { FamilyTree } from '$lib/graph/layout';
import { tailwindClassToPixels } from '$lib/tailwindSizeToPx';
import type { Layout } from '$lib/graph/model';
- let { data }: { data: Layout } = $props();
+ let { data }: { data: Layout & { id: string } } = $props();
let selectedPerson: components['schemas']['PersonProperties'] & { id: number | null } = $state({
id: null
@@ -66,7 +66,29 @@
openPersonMenu = undefined;
},
deleteNode: () => {
- relationshipStart = Number(node.id);
+ if (Number(data.id) === Number(node.id)) {
+ relationshipStart = null;
+ openPersonMenu = undefined;
+
+ return;
+ }
+ fetch('/api/person/' + node.id, {
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ })
+ .then((response) => {
+ if (response.ok) {
+ nodes = nodes.filter((n) => n.id !== node.id);
+ edges = edges.filter((e) => e.source !== node.id && e.target !== node.id);
+ } else {
+ alert('Error deleting person');
+ }
+ })
+ .catch((error) => {
+ console.error('Error:', error);
+ });
openPersonMenu = undefined;
},
createRelationshipAndNode: () => {
@@ -102,13 +124,16 @@
edges = [...edges, ...newEdges];
}
- familyTreeDAG.getLayoutedElements(
+ let newLayout = familyTreeDAG.getLayoutedElements(
nodes,
edges,
tailwindClassToPixels('w-40') || 160,
tailwindClassToPixels('h-40') || 160,
'TB'
);
+
+ edges = newLayout.Edges;
+ nodes = newLayout.Nodes;
};
let handleNodeClickFunc = handleNodeClick(
@@ -118,8 +143,28 @@
}
) => {
openPersonPanel = true;
- console.log('person', person);
selectedPerson = person;
+ fetch('/api/person/' + person.id, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ })
+ .then((response) => {
+ if (response.ok) {
+ return response.json() as Promise
;
+ } else {
+ alert('Error fetching person data');
+ return null;
+ }
+ })
+ .then((data) => {
+ if (data) {
+ selectedPerson = data.Props as components['schemas']['PersonProperties'] & {
+ id: number | null;
+ };
+ }
+ });
}
);
@@ -161,6 +206,9 @@
{/if}
{#if createPerson}
{
+ createPerson = false;
+ }}
{onCreation}
closeModal={() => {
createPerson = false;