mirror of
https://github.com/vcscsvcscs/GenerationsHeritage.git
synced 2025-08-14 06:49:05 +02:00
Add person menu
This commit is contained in:
41
frontend/src/lib/family_tree/PersonMenu.svelte
Normal file
41
frontend/src/lib/family_tree/PersonMenu.svelte
Normal file
@@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
export let onClick: () => void;
|
||||
export let deleteNode: () => void;
|
||||
export let addRelationship: () => void;
|
||||
export let addFamilymember: () => void;
|
||||
export let id: string;
|
||||
export let top: number | undefined;
|
||||
export let left: number | undefined;
|
||||
export let right: number | undefined;
|
||||
export let bottom: number | undefined;
|
||||
</script>
|
||||
|
||||
<div
|
||||
style="top: {top}px; left: {left}px; right: {right}px; bottom: {bottom}px;"
|
||||
class="context-menu bg-primary-100 rounded-lg shadow-lg"
|
||||
on:click={onClick}
|
||||
>
|
||||
<p style="margin: 0.5em;">
|
||||
<small>node: {id}</small>
|
||||
</p>
|
||||
<button on:click={addRelationship}>Add Relationship</button>
|
||||
<button on:click={addFamilymember}>Add familymember</button>
|
||||
<button on:click={deleteNode}>Delete</button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.context-menu {
|
||||
border-style: solid;
|
||||
box-shadow: 10px 19px 20px rgba(0, 0, 0, 10%);
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.context-menu button {
|
||||
border: none;
|
||||
display: block;
|
||||
padding: 0.5em;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@@ -37,9 +37,10 @@
|
||||
</figure>
|
||||
</div>
|
||||
<h2 class="card-title text-base-content">
|
||||
{data.Lastname}
|
||||
|
||||
{data.Firstname}
|
||||
{data.Middlename}
|
||||
{data.Lastname}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
40
frontend/src/lib/family_tree/setFamilyTreeNodes.ts
Normal file
40
frontend/src/lib/family_tree/setFamilyTreeNodes.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { fetch_family_tree } from '$lib/family_tree/getFamilyTree';
|
||||
import { getLayoutedElements } from '$lib/family_tree/dagreLayout';
|
||||
import { AddToNodesData, AddToEdgesData } from '$lib/family_tree/dataAdapter';
|
||||
import type { Node, Edge } from '@xyflow/svelte';
|
||||
import { useEdges, useNodes } from '@xyflow/svelte';
|
||||
|
||||
const nodes = useNodes();
|
||||
const edges = useEdges();
|
||||
|
||||
export function setFamilyTreeNodes() {
|
||||
console.log('fetching nodes');
|
||||
fetch_family_tree().then((data) => {
|
||||
let nodes_data: Node[] = [];
|
||||
function pushNodeToData(node: Node) {
|
||||
nodes_data.push(node);
|
||||
}
|
||||
|
||||
AddToNodesData(data, 0, pushNodeToData);
|
||||
AddToNodesData(data, 2, pushNodeToData);
|
||||
AddToNodesData(data, 4, pushNodeToData);
|
||||
AddToNodesData(data, 6, pushNodeToData);
|
||||
AddToNodesData(data, 8, pushNodeToData);
|
||||
|
||||
let edges_data: Edge[] = [];
|
||||
function pushEdgeToData(edge: Edge) {
|
||||
edges_data.push(edge);
|
||||
}
|
||||
|
||||
AddToEdgesData(data, 1, pushEdgeToData);
|
||||
AddToEdgesData(data, 3, pushEdgeToData);
|
||||
AddToEdgesData(data, 5, pushEdgeToData);
|
||||
AddToEdgesData(data, 7, pushEdgeToData);
|
||||
|
||||
const layoutedElements = getLayoutedElements(nodes_data, edges_data, 'TB');
|
||||
|
||||
$nodes = layoutedElements.nodes;
|
||||
$edges = layoutedElements.edges;
|
||||
});
|
||||
console.log('nodes fetched and set');
|
||||
}
|
@@ -5,52 +5,20 @@
|
||||
import type { Node, Edge, NodeTypes } from '@xyflow/svelte';
|
||||
import { isAuthenticated } from '../lib/stores';
|
||||
import PersonNode from './../lib/family_tree/PersonNode.svelte';
|
||||
import { setFamilyTreeNodes } from '../lib/family_tree/setFamilyTreeNodes';
|
||||
import { login } from '../lib/auth';
|
||||
import { fetch_family_tree } from '$lib/family_tree/getFamilyTree';
|
||||
import { getLayoutedElements } from '$lib/family_tree/dagreLayout';
|
||||
import { AddToNodesData, AddToEdgesData } from '$lib/family_tree/dataAdapter';
|
||||
let edges_data: {
|
||||
id: string;
|
||||
source: string;
|
||||
target: string;
|
||||
data: { type: string; verified: boolean };
|
||||
}[] = [];
|
||||
|
||||
import PersonMenu from '$lib/family_tree/PersonMenu.svelte';
|
||||
import PersonPanel from '$lib/family_tree/PersonPanel.svelte';
|
||||
const nodes = writable<Node[]>([]);
|
||||
const edges = writable<Edge[]>([]);
|
||||
onMount(() => {
|
||||
if (!$isAuthenticated) {
|
||||
console.log('user authenticated:', $isAuthenticated);
|
||||
console.log('user is not authenticated');
|
||||
login();
|
||||
} else {
|
||||
console.log('user authenticated:', $isAuthenticated);
|
||||
console.log('fetching nodes');
|
||||
fetch_family_tree().then((data) => {
|
||||
let nodes_data: Node[] = [];
|
||||
function pushNodeToData(node: Node) {
|
||||
nodes_data.push(node);
|
||||
}
|
||||
|
||||
AddToNodesData(data, 0, pushNodeToData);
|
||||
AddToNodesData(data, 2, pushNodeToData);
|
||||
AddToNodesData(data, 4, pushNodeToData);
|
||||
AddToNodesData(data, 6, pushNodeToData);
|
||||
AddToNodesData(data, 8, pushNodeToData);
|
||||
|
||||
let edges_data: Edge[] = [];
|
||||
function pushEdgeToData(edge: Edge) {
|
||||
edges_data.push(edge);
|
||||
}
|
||||
|
||||
AddToEdgesData(data, 1, pushEdgeToData);
|
||||
AddToEdgesData(data, 3, pushEdgeToData);
|
||||
AddToEdgesData(data, 5, pushEdgeToData);
|
||||
AddToEdgesData(data, 7, pushEdgeToData);
|
||||
|
||||
const layoutedElements = getLayoutedElements(nodes_data, edges_data, 'TB');
|
||||
|
||||
$nodes = layoutedElements.nodes;
|
||||
$edges = layoutedElements.edges;
|
||||
});
|
||||
console.log('user is authenticated');
|
||||
setFamilyTreeNodes();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -58,6 +26,8 @@
|
||||
custom: PersonNode
|
||||
};
|
||||
|
||||
let personPanel: {} | null;
|
||||
|
||||
let menu: { id: string; top?: number; left?: number; right?: number; bottom?: number } | null;
|
||||
let width: number;
|
||||
let height: number;
|
||||
@@ -69,7 +39,7 @@
|
||||
// Calculate position of the context menu. We want to make sure it
|
||||
// doesn't get positioned off-screen.
|
||||
menu = {
|
||||
id: node.id,
|
||||
id: node.data.ID,
|
||||
top: event.clientY < height - 200 ? event.clientY : undefined,
|
||||
left: event.clientX < width - 200 ? event.clientX : undefined,
|
||||
right: event.clientX >= width - 200 ? width - event.clientX : undefined,
|
||||
@@ -85,9 +55,30 @@
|
||||
|
||||
<div style="height:100vh;">
|
||||
<SvelteFlowProvider>
|
||||
<SvelteFlow {nodes} {nodeTypes} {edges} class="bg-base-100" fitView onlyRenderVisibleElements>
|
||||
<SvelteFlow
|
||||
{nodes}
|
||||
{nodeTypes}
|
||||
{edges}
|
||||
on:nodecontextmenu={handleContextMenu}
|
||||
on:nodeclick
|
||||
on:paneclick={handlePaneClick}
|
||||
class="bg-base-100"
|
||||
fitView
|
||||
onlyRenderVisibleElements
|
||||
>
|
||||
<Controls class="bg-base-300 text-base-content" />
|
||||
<MiniMap class="bg-base-200"/>
|
||||
<MiniMap class="bg-base-200" />
|
||||
{#if menu}
|
||||
<PersonMenu
|
||||
onClick={handlePaneClick}
|
||||
id={menu.id}
|
||||
top={menu.top}
|
||||
left={menu.left}
|
||||
right={menu.right}
|
||||
bottom={menu.bottom}
|
||||
/>
|
||||
{/if}
|
||||
<PersonPanel showPanel={personPanel != null} data={personPanel} />
|
||||
</SvelteFlow>
|
||||
</SvelteFlowProvider>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user