diff --git a/backend/directus-config/development/snapshot/fields/relations/direction.json b/backend/directus-config/development/snapshot/fields/relations/direction.json new file mode 100644 index 00000000..61cbe89d --- /dev/null +++ b/backend/directus-config/development/snapshot/fields/relations/direction.json @@ -0,0 +1,56 @@ +{ + "collection": "relations", + "field": "direction", + "type": "string", + "meta": { + "collection": "relations", + "conditions": null, + "display": null, + "display_options": null, + "field": "direction", + "group": null, + "hidden": false, + "interface": "select-dropdown", + "note": null, + "options": { + "choices": [ + { + "icon": "arrow_forward", + "text": "outgoing", + "value": "outgoing" + }, + { + "icon": "arrow_back", + "text": "ingoing", + "value": "ingoing" + } + ] + }, + "readonly": false, + "required": false, + "sort": 4, + "special": null, + "translations": null, + "validation": null, + "validation_message": null, + "width": "full" + }, + "schema": { + "name": "direction", + "table": "relations", + "data_type": "character varying", + "default_value": "outgoing", + "max_length": 255, + "numeric_precision": null, + "numeric_scale": null, + "is_nullable": true, + "is_unique": false, + "is_indexed": false, + "is_primary_key": false, + "is_generated": false, + "generation_expression": null, + "has_auto_increment": false, + "foreign_key_table": null, + "foreign_key_column": null + } +} diff --git a/backend/directus-config/development/snapshot/fields/relations/heading.json b/backend/directus-config/development/snapshot/fields/relations/heading.json new file mode 100644 index 00000000..6b53f17f --- /dev/null +++ b/backend/directus-config/development/snapshot/fields/relations/heading.json @@ -0,0 +1,43 @@ +{ + "collection": "relations", + "field": "heading", + "type": "string", + "meta": { + "collection": "relations", + "conditions": null, + "display": null, + "display_options": null, + "field": "heading", + "group": null, + "hidden": false, + "interface": "input", + "note": null, + "options": null, + "readonly": false, + "required": false, + "sort": 3, + "special": null, + "translations": null, + "validation": null, + "validation_message": null, + "width": "full" + }, + "schema": { + "name": "heading", + "table": "relations", + "data_type": "character varying", + "default_value": "Relations", + "max_length": 255, + "numeric_precision": null, + "numeric_scale": null, + "is_nullable": true, + "is_unique": false, + "is_indexed": false, + "is_primary_key": false, + "is_generated": false, + "generation_expression": null, + "has_auto_increment": false, + "foreign_key_table": null, + "foreign_key_column": null + } +} diff --git a/backend/directus-config/development/snapshot/fields/relations/hideWhenEmpty.json b/backend/directus-config/development/snapshot/fields/relations/hideWhenEmpty.json new file mode 100644 index 00000000..d9f435d4 --- /dev/null +++ b/backend/directus-config/development/snapshot/fields/relations/hideWhenEmpty.json @@ -0,0 +1,45 @@ +{ + "collection": "relations", + "field": "hideWhenEmpty", + "type": "boolean", + "meta": { + "collection": "relations", + "conditions": null, + "display": null, + "display_options": null, + "field": "hideWhenEmpty", + "group": null, + "hidden": false, + "interface": "boolean", + "note": null, + "options": null, + "readonly": false, + "required": false, + "sort": 5, + "special": [ + "cast-boolean" + ], + "translations": null, + "validation": null, + "validation_message": null, + "width": "full" + }, + "schema": { + "name": "hideWhenEmpty", + "table": "relations", + "data_type": "boolean", + "default_value": true, + "max_length": null, + "numeric_precision": null, + "numeric_scale": null, + "is_nullable": true, + "is_unique": false, + "is_indexed": false, + "is_primary_key": false, + "is_generated": false, + "generation_expression": null, + "has_auto_increment": false, + "foreign_key_table": null, + "foreign_key_column": null + } +} diff --git a/lib/src/Components/Profile/Subcomponents/RelationsView.tsx b/lib/src/Components/Profile/Subcomponents/RelationsView.tsx index 2348b646..a1fc1f02 100644 --- a/lib/src/Components/Profile/Subcomponents/RelationsView.tsx +++ b/lib/src/Components/Profile/Subcomponents/RelationsView.tsx @@ -1,3 +1,6 @@ +import { Link } from 'react-router-dom' + +import { useAppState } from '#components/AppShell/hooks/useAppState' import { useItems } from '#components/Map/hooks/useItems' import type { Item } from '#types/Item' @@ -5,27 +8,79 @@ import type { Item } from '#types/Item' interface Props { item: Item relation: string + heading: string + direction?: 'outgoing' | 'ingoing' | 'bidirectional' + hideWhenEmpty?: boolean } -export const RelationsView = ({ item, relation }: Props) => { +export const RelationsView = ({ + item, + relation, + heading, + direction = 'outgoing', + hideWhenEmpty = true, +}: Props) => { const items = useItems() + const appState = useAppState() if (!item.relations) return const relationsOfRightType = item.relations.filter((r) => r.type === relation) - const relatedItems = items.filter((i) => relationsOfRightType.some((r) => r.id === i.id)) + const relatedItems = (() => { + const outgoingItems = items.filter((i) => + relationsOfRightType.some((r) => r.related_items_id === i.id), + ) + + const ingoingItems = items.filter((i) => + i.relations?.some((r) => r.type === relation && r.related_items_id === item.id), + ) + + switch (direction) { + case 'outgoing': + return outgoingItems + case 'ingoing': + return ingoingItems + case 'bidirectional': { + // Combine both arrays and remove duplicates + const allItems = [...outgoingItems, ...ingoingItems] + return allItems.filter( + (item, index, self) => index === self.findIndex((i) => i.id === item.id), + ) + } + default: + return outgoingItems + } + })() const hasRelatedItems = relatedItems.length > 0 + if (hideWhenEmpty && !hasRelatedItems) { + return null + } + return ( -