From 0d88193d45c8ae2fd278ec011483ef277b394174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Katharina=20W=C3=BCnsche?= Date: Tue, 20 Aug 2024 14:41:57 +0200 Subject: [PATCH] feat: adapt family tree for function hierarchy --- components/family-tree.vue | 112 ++++++++++++++++++++++-------- messages/de.json | 2 + messages/en.json | 4 +- pages/detail/function/[id].vue | 33 +++++++++ public/assets/icons/connected.svg | 1 + 5 files changed, 121 insertions(+), 31 deletions(-) create mode 100644 public/assets/icons/connected.svg diff --git a/components/family-tree.vue b/components/family-tree.vue index e56ba84..4c4edf6 100644 --- a/components/family-tree.vue +++ b/components/family-tree.vue @@ -22,9 +22,60 @@ const props = withDefaults( defineProps<{ relations: Array; name: string; + relationNames?: { + ancestor?: string; + child?: string; + sibling?: string; + partner?: string; + }; + legendNames?: { + ancestor?: string; + child?: string; + sibling?: string; + partner?: string; + descendantOf?: string; + }; + icons?: { + sibling?: string; + partner?: string; + }; + classnameForUrls?: string; + collapseThreshold?: number; }>(), - { relations: () => [] }, + { + relations: () => [], + classnameForUrls: "person", + collapseThreshold: 3, + }, ); + +const relationNames = computed(() => { + const defaultNames = { + ancestor: "ist Kind von", + child: "ist Elternteil von", + sibling: "ist Bruder/Schwester von", + partner: "hat Ehe mit", + }; + return { ...defaultNames, ...props.relationNames }; +}); +const icons = computed(() => { + const defaultIcons = { + sibling: "/assets/icons/users.svg", + partner: "/assets/icons/marriage.svg", + }; + return { ...defaultIcons, ...props.icons }; +}); +const legendNames = computed(() => { + const defaultLegendNames = { + ancestor: "FamilyTree.parents", + child: "FamilyTree.children", + sibling: "FamilyTree.siblings", + partner: "FamilyTree.partner", + descendantOf: "FamilyTree.is-descendant-of", + }; + return { ...defaultLegendNames, ...props.legendNames }; +}); + const familyTreeContainer = ref(); const ancestorContainer = ref(); const siblingContainer = ref(); @@ -40,22 +91,22 @@ function filterUniqueObjects(list: Array<{ id: number; name: string }>) { } const ancestors = computed(() => { return filterUniqueObjects( - props.relations.filter((r) => r.name === "ist Kind von").map((r) => r.to), + props.relations.filter((r) => r.name === relationNames.value.ancestor).map((r) => r.to), ); }); const children = computed(() => { return filterUniqueObjects( - props.relations.filter((r) => r.name === "ist Elternteil von").map((r) => r.to), + props.relations.filter((r) => r.name === relationNames.value.child).map((r) => r.to), ); }); const siblings = computed(() => { return filterUniqueObjects( - props.relations.filter((r) => r.name === "ist Bruder/Schwester von").map((r) => r.to), + props.relations.filter((r) => r.name === relationNames.value.sibling).map((r) => r.to), ); }); const partners = computed(() => { return filterUniqueObjects( - props.relations.filter((r) => r.name === "hat Ehe mit").map((r) => r.to), + props.relations.filter((r) => r.name === relationNames.value.partner).map((r) => r.to), ); }); @@ -68,7 +119,7 @@ function resizeHandler() { const childConnections = ref>(); function drawChildConnections() { const container = - showAllChilldren.value || children.value.length <= 3 + showAllChilldren.value || children.value.length <= props.collapseThreshold ? childContainer.value : uncollapseChildrenContainer.value; const childContainerChildren = [...(container?.children ?? [])]; @@ -141,7 +192,7 @@ onMounted(() => { location: siblings.value.length > 1 ? 12 : 0.5, create() { const d = document.createElement("div"); - d.innerHTML = `${t("FamilyTree.siblings")}`; + d.innerHTML = `${t(legendNames.value.sibling)}`; return d; }, }, @@ -158,7 +209,7 @@ onMounted(() => { location: partners.value.length > 1 ? 12 : 0.5, create() { const d = document.createElement("div"); - d.innerHTML = `${t("FamilyTree.partner")}`; + d.innerHTML = `${t(legendNames.value.partner)}`; return d; }, }, @@ -224,29 +275,30 @@ function toggleShowAllChildren() { class="absolute left-0 mt-2 w-max origin-top-left rounded-lg bg-neutral-50 p-1 shadow-lg ring-1 ring-black/5 dark:bg-neutral-800" >
-
- -
{{ t("FamilyTree.siblings") }}
+
+ +
{{ t(legendNames.sibling) }}
-
- -
{{ t("FamilyTree.partner") }}
+
+ +
{{ t(legendNames.partner) }}
-
+
-
{{ t("FamilyTree.is-descendant-of") }}
+
{{ t(legendNames.descendantOf) }}
{{ person.name }} @@ -279,7 +331,7 @@ function toggleShowAllChildren() { v-for="person in siblings" :key="person.id" class="w-32 p-2 text-right align-middle" - :to="localePath(`/detail/person/${person.id}`)" + :to="localePath(`/detail/${props.classnameForUrls}/${person.id}`)" > {{ person.name }} @@ -293,7 +345,7 @@ function toggleShowAllChildren() { {{ person.name }} @@ -301,14 +353,14 @@ function toggleShowAllChildren() {
diff --git a/messages/de.json b/messages/de.json index 9feb51d..7728bae 100644 --- a/messages/de.json +++ b/messages/de.json @@ -46,6 +46,8 @@ "partner": "Ehepartner:in", "children": "Kinder", "parents": "Eltern", + "subordinate-function": "Untergeordnete Funktion", + "connected-function": "Verbunden mit", "show-all-children": "Zeige alle {count} Kinder", "show-all-siblings": "Zeige alle {count} Geschwister", "collapse-children": "Kinder einklappen", diff --git a/messages/en.json b/messages/en.json index 0edaf09..e690d41 100644 --- a/messages/en.json +++ b/messages/en.json @@ -51,7 +51,9 @@ "collapse-children": "Collapse children", "collapse-siblings": "Collapse siblings", "is-descendant-of": "Descendant", - "legend": "Legend" + "legend": "Legend", + "subordinate-function": "Subordinate Funktion", + "connected-function": "Connected" }, "ImprintPage": { "meta": { diff --git a/pages/detail/function/[id].vue b/pages/detail/function/[id].vue index 0e03178..c3742f5 100644 --- a/pages/detail/function/[id].vue +++ b/pages/detail/function/[id].vue @@ -57,6 +57,18 @@ function closeVerticalTimeline() { function openVerticalTimeline() { showVerticalTimeline.value = true; } +const needsFamilyTree = computed(() => { + if (!data.value.relations.data) return false; + + const functionRelationNames = [ + "ist untergeordnet", + "hat untergeordnete Funktion", + "ist verbunden mit", + ]; + return Boolean( + data.value.relations.data.function?.find((r) => functionRelationNames.includes(r.name)), + ); +}); +