diff --git a/frontend/components/Item/Selector.vue b/frontend/components/Item/Selector.vue index dad8354e..800be83b 100644 --- a/frontend/components/Item/Selector.vue +++ b/frontend/components/Item/Selector.vue @@ -65,6 +65,7 @@ searchPlaceholder?: string; noResultsText?: string; placeholder?: string; + excludeItems?: ItemsObject[]; } const emit = defineEmits(["update:modelValue", "update:search"]); @@ -78,6 +79,7 @@ searchPlaceholder: undefined, noResultsText: undefined, placeholder: undefined, + excludeItems: undefined, }); const id = useId(); @@ -137,12 +139,19 @@ } const filtered = computed(() => { - if (!search.value) return props.items; - if (isStrings(props.items)) { - return props.items.filter(item => item.toLowerCase().includes(search.value.toLowerCase())); + let baseItems = props.items; + + if (!isStrings(baseItems) && props.excludeItems) { + const excludeIds = props.excludeItems.map(i => i.id); + baseItems = baseItems.filter(item => !excludeIds?.includes(item.id)); + } + if (!search.value) return baseItems; + + if (isStrings(baseItems)) { + return baseItems.filter(item => item.toLowerCase().includes(search.value.toLowerCase())); } else { // Fuzzy search on itemText - return fuzzysort.go(search.value, props.items, { key: props.itemText, all: true }).map(i => i.obj); + return fuzzysort.go(search.value, baseItems, { key: props.itemText, all: true }).map(i => i.obj); } }); diff --git a/frontend/components/Location/Selector.vue b/frontend/components/Location/Selector.vue index bd22ebf4..258211c2 100644 --- a/frontend/components/Location/Selector.vue +++ b/frontend/components/Location/Selector.vue @@ -58,6 +58,7 @@ type Props = { modelValue?: LocationSummary | null; + currentLocation?: LocationSummary; }; const props = defineProps(); @@ -66,7 +67,7 @@ const open = ref(false); const search = ref(""); const id = useId(); - const locations = useFlatLocations(); + const locations = useFlatLocations(props.currentLocation); const value = useVModel(props, "modelValue", emit); function selectLocation(location: LocationSummary) { diff --git a/frontend/composables/use-location-helpers.ts b/frontend/composables/use-location-helpers.ts index bff2d839..f429fe06 100644 --- a/frontend/composables/use-location-helpers.ts +++ b/frontend/composables/use-location-helpers.ts @@ -1,5 +1,5 @@ import type { Ref } from "vue"; -import type { TreeItem } from "~~/lib/api/types/data-contracts"; +import type { TreeItem, LocationSummary } from "~~/lib/api/types/data-contracts"; export interface FlatTreeItem { id: string; @@ -35,9 +35,29 @@ function flatTree(tree: TreeItem[]): FlatTreeItem[] { return v; } -export function useFlatLocations(): Ref { - const locations = useLocationStore(); +function filterOutSubtree(tree: TreeItem[], excludeId: string): TreeItem[] { + // Recursively filters out a subtree starting from excludeId + const result: TreeItem[] = []; + for (const item of tree) { + if (item.id === excludeId) { + continue; + } + + const newItem = { ...item }; + if (item.children) { + newItem.children = filterOutSubtree(item.children, excludeId); + } + + result.push(newItem); + } + + return result; +} + +export function useFlatLocations(excludeSubtreeForLocation?: LocationSummary): Ref { + const locations = useLocationStore(); + if (locations.tree === null) { locations.refreshTree(); } @@ -47,6 +67,10 @@ export function useFlatLocations(): Ref { return []; } - return flatTree(locations.tree); + const filteredTree = excludeSubtreeForLocation + ? filterOutSubtree(locations.tree, excludeSubtreeForLocation.id) + : locations.tree; + + return flatTree(filteredTree); }); } diff --git a/frontend/pages/item/[id]/index/edit.vue b/frontend/pages/item/[id]/index/edit.vue index c4fdcf22..b32c401c 100644 --- a/frontend/pages/item/[id]/index/edit.vue +++ b/frontend/pages/item/[id]/index/edit.vue @@ -577,6 +577,7 @@ item-text="name" :label="$t('items.parent_item')" no-results-text="Type to search..." + :exclude-items="[item]" @update:model-value="maybeSyncWithParentLocation()" />
diff --git a/frontend/pages/location/[id].vue b/frontend/pages/location/[id].vue index 526046db..6554e40f 100644 --- a/frontend/pages/location/[id].vue +++ b/frontend/pages/location/[id].vue @@ -147,7 +147,7 @@ :label="$t('components.location.create_modal.location_description')" :max-length="1000" /> - +