forked from mirrors/homebox
feat: allow nested relationships for locations and items (#102)
Basic implementation that allows organizing Locations and Items within each other.
This commit is contained in:
parent
fe6cd431a6
commit
a4b4fe3454
37 changed files with 2329 additions and 126 deletions
|
@ -4,6 +4,7 @@
|
|||
import { useLabelStore } from "~~/stores/labels";
|
||||
import { useLocationStore } from "~~/stores/locations";
|
||||
import { capitalize } from "~~/lib/strings";
|
||||
import Autocomplete from "~~/components/Form/Autocomplete.vue";
|
||||
|
||||
definePageMeta({
|
||||
middleware: ["auth"],
|
||||
|
@ -37,8 +38,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (data.parent) {
|
||||
parent.value = data.parent;
|
||||
}
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
refresh();
|
||||
});
|
||||
|
@ -48,6 +54,7 @@
|
|||
...item.value,
|
||||
locationId: item.value.location?.id,
|
||||
labelIds: item.value.labels.map(l => l.id),
|
||||
parentId: parent.value ? parent.value.id : null,
|
||||
};
|
||||
|
||||
const { error } = await api.items.update(itemId.value, payload);
|
||||
|
@ -256,7 +263,6 @@
|
|||
|
||||
async function updateAttachment() {
|
||||
editState.loading = true;
|
||||
console.log(editState.type);
|
||||
const { error, data } = await api.items.updateAttachment(itemId.value, editState.id, {
|
||||
title: editState.title,
|
||||
type: editState.type,
|
||||
|
@ -306,6 +312,9 @@
|
|||
timeValue: null,
|
||||
});
|
||||
}
|
||||
|
||||
const { query, results } = useItemSearch(api, { immediate: false });
|
||||
const parent = ref();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -314,8 +323,8 @@
|
|||
<template #title> Attachment Edit </template>
|
||||
|
||||
<FormTextField v-model="editState.title" label="Attachment Title" />
|
||||
{{ editState.type }}
|
||||
<FormSelect
|
||||
v-model="editState.obj"
|
||||
v-model:value="editState.type"
|
||||
label="Attachment Type"
|
||||
value-key="value"
|
||||
|
@ -354,8 +363,24 @@
|
|||
</template>
|
||||
</BaseSectionHeader>
|
||||
<div class="px-5 mb-6 grid md:grid-cols-2 gap-4">
|
||||
<FormSelect v-if="item" v-model="item.location" label="Location" :items="locations ?? []" />
|
||||
<FormSelect
|
||||
v-if="item"
|
||||
v-model="item.location"
|
||||
label="Location"
|
||||
:items="locations ?? []"
|
||||
compare-key="id"
|
||||
/>
|
||||
<FormMultiselect v-model="item.labels" label="Labels" :items="labels ?? []" />
|
||||
|
||||
<Autocomplete
|
||||
v-if="!preferences.editorSimpleView"
|
||||
v-model="parent"
|
||||
v-model:search="query"
|
||||
:items="results"
|
||||
item-text="name"
|
||||
label="Parent Item"
|
||||
no-results-text="Type to search..."
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-gray-300 sm:p-0">
|
||||
|
|
|
@ -76,6 +76,10 @@
|
|||
name: "Description",
|
||||
text: item.value?.description,
|
||||
},
|
||||
{
|
||||
name: "Quantity",
|
||||
text: item.value?.quantity,
|
||||
},
|
||||
{
|
||||
name: "Serial Number",
|
||||
text: item.value?.serialNumber,
|
||||
|
@ -287,12 +291,23 @@
|
|||
<span class="text-base-content">
|
||||
{{ item ? item.name : "" }}
|
||||
</span>
|
||||
<div v-if="item.parent" class="text-sm breadcrumbs pb-0">
|
||||
<ul class="text-base-content/70">
|
||||
<li>
|
||||
<NuxtLink :to="`/item/${item.parent.id}`"> {{ item.parent.name }}</NuxtLink>
|
||||
</li>
|
||||
<li>{{ item.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<template #description>
|
||||
<p class="text-sm text-base-content font-bold pb-0 mb-0">
|
||||
{{ item.location.name }} - Quantity {{ item.quantity }}
|
||||
</p>
|
||||
<div v-if="item.labels && item.labels.length > 0" class="flex flex-wrap gap-3 mt-3">
|
||||
<LabelChip v-for="label in item.labels" :key="label.id" class="badge-primary" :label="label" />
|
||||
<div class="flex flex-wrap gap-2 mt-3">
|
||||
<NuxtLink ref="badge" class="badge p-3" :to="`/location/${item.location.id}`">
|
||||
<Icon name="heroicons-map-pin" class="mr-2 swap-on"></Icon>
|
||||
{{ item.location.name }}
|
||||
</NuxtLink>
|
||||
<template v-if="item.labels && item.labels.length > 0">
|
||||
<LabelChip v-for="label in item.labels" :key="label.id" class="badge-primary" :label="label" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</BaseSectionHeader>
|
||||
|
@ -378,5 +393,12 @@
|
|||
</BaseCard>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="my-6 px-3">
|
||||
<BaseSectionHeader v-if="item && item.children && item.children.length > 0"> Child Items </BaseSectionHeader>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<ItemCard v-for="child in item.children" :key="child.id" :item="child" />
|
||||
</div>
|
||||
</section>
|
||||
</BaseContainer>
|
||||
</template>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue