forked from mirrors/homebox
feat: add archive item options (#122)
Add archive option feature. Archived items can only be seen on the items page when including archived is selected. Archived items are excluded from the count and from other views
This commit is contained in:
parent
c722495fdd
commit
a886fa86ca
27 changed files with 325 additions and 38 deletions
|
@ -2,7 +2,7 @@
|
|||
<div v-if="!inline" class="form-control w-full">
|
||||
<label class="label cursor-pointer">
|
||||
<span class="label-text"> {{ label }}</span>
|
||||
<input v-model="value" type="checkbox" class="checkbox" />
|
||||
<input v-model="value" type="checkbox" class="checkbox checkbox-primary" />
|
||||
</label>
|
||||
</div>
|
||||
<div v-else class="label cursor-pointer sm:grid sm:grid-cols-4 sm:items-start sm:gap-4">
|
||||
|
@ -11,7 +11,7 @@
|
|||
{{ label }}
|
||||
</span>
|
||||
</label>
|
||||
<input v-model="value" type="checkbox" class="checkbox" />
|
||||
<input v-model="value" type="checkbox" class="checkbox checkbox-primary" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<h2 class="card-title">
|
||||
<Icon name="mdi-package-variant" />
|
||||
{{ item.name }}
|
||||
<Icon v-if="item.archived" class="ml-auto" name="mdi-archive-outline" />
|
||||
</h2>
|
||||
<p>{{ description }}</p>
|
||||
<div class="flex gap-2 flex-wrap justify-end">
|
||||
|
|
3
frontend/components/global/Spacer.vue
Normal file
3
frontend/components/global/Spacer.vue
Normal file
|
@ -0,0 +1,3 @@
|
|||
<template>
|
||||
<div class="grow-1 max-w-full"></div>
|
||||
</template>
|
|
@ -10,13 +10,19 @@ export function useItemSearch(client: UserClient, opts?: SearchOptions) {
|
|||
const locations = ref<LocationSummary[]>([]);
|
||||
const labels = ref<LabelSummary[]>([]);
|
||||
const results = ref<ItemSummary[]>([]);
|
||||
const includeArchived = ref(false);
|
||||
|
||||
watchDebounced(query, search, { debounce: 250, maxWait: 1000 });
|
||||
async function search() {
|
||||
const locIds = locations.value.map(l => l.id);
|
||||
const labelIds = labels.value.map(l => l.id);
|
||||
|
||||
const { data, error } = await client.items.getAll({ q: query.value, locations: locIds, labels: labelIds });
|
||||
const { data, error } = await client.items.getAll({
|
||||
q: query.value,
|
||||
locations: locIds,
|
||||
labels: labelIds,
|
||||
includeArchived: includeArchived.value,
|
||||
});
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
import { AttachmentTypes, PaginationResult } from "../types/non-generated";
|
||||
|
||||
export type ItemsQuery = {
|
||||
includeArchived?: boolean;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
locations?: string[];
|
||||
|
|
|
@ -63,6 +63,7 @@ export interface ItemField {
|
|||
}
|
||||
|
||||
export interface ItemOut {
|
||||
archived: boolean;
|
||||
attachments: ItemAttachment[];
|
||||
children: ItemSummary[];
|
||||
createdAt: Date;
|
||||
|
@ -107,6 +108,7 @@ export interface ItemOut {
|
|||
}
|
||||
|
||||
export interface ItemSummary {
|
||||
archived: boolean;
|
||||
createdAt: Date;
|
||||
description: string;
|
||||
id: string;
|
||||
|
@ -121,6 +123,7 @@ export interface ItemSummary {
|
|||
}
|
||||
|
||||
export interface ItemUpdate {
|
||||
archived: boolean;
|
||||
description: string;
|
||||
fields: ItemField[];
|
||||
id: string;
|
||||
|
|
|
@ -115,6 +115,11 @@
|
|||
label: "Insured",
|
||||
ref: "insured",
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Archived",
|
||||
ref: "archived",
|
||||
},
|
||||
];
|
||||
|
||||
const purchaseFields: FormField[] = [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { Detail, Details } from "~~/components/global/DetailsSection/types";
|
||||
import { CustomDetail, Detail, Details } from "~~/components/global/DetailsSection/types";
|
||||
import { ItemAttachment } from "~~/lib/api/types/data-contracts";
|
||||
|
||||
definePageMeta({
|
||||
|
@ -70,7 +70,7 @@
|
|||
);
|
||||
});
|
||||
|
||||
const itemDetails = computed(() => {
|
||||
const itemDetails = computed<Details>(() => {
|
||||
return [
|
||||
{
|
||||
name: "Description",
|
||||
|
@ -107,11 +107,11 @@
|
|||
const url = maybeUrl(field.textValue);
|
||||
if (url.isUrl) {
|
||||
return {
|
||||
type: "link",
|
||||
name: field.name,
|
||||
text: url.text,
|
||||
type: "link",
|
||||
href: url.url,
|
||||
};
|
||||
} as CustomDetail;
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -23,7 +23,12 @@
|
|||
const locations = selectedLocations.value.map(l => l.id);
|
||||
const labels = selectedLabels.value.map(l => l.id);
|
||||
|
||||
const { data, error } = await api.items.getAll({ q: query.value, locations, labels });
|
||||
const { data, error } = await api.items.getAll({
|
||||
q: query.value,
|
||||
locations,
|
||||
labels,
|
||||
includeArchived: includeArchived.value,
|
||||
});
|
||||
if (error) {
|
||||
loading.value = false;
|
||||
return;
|
||||
|
@ -46,6 +51,7 @@
|
|||
const advanced = ref(false);
|
||||
const selectedLocations = ref([]);
|
||||
const selectedLabels = ref([]);
|
||||
const includeArchived = ref(false);
|
||||
|
||||
watchEffect(() => {
|
||||
if (!advanced.value) {
|
||||
|
@ -57,6 +63,7 @@
|
|||
watchDebounced(query, search, { debounce: 250, maxWait: 1000 });
|
||||
watchDebounced(selectedLocations, search, { debounce: 250, maxWait: 1000 });
|
||||
watchDebounced(selectedLabels, search, { debounce: 250, maxWait: 1000 });
|
||||
watch(includeArchived, search);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -77,6 +84,13 @@
|
|||
<div class="px-4 pb-4">
|
||||
<FormMultiselect v-model="selectedLabels" label="Labels" :items="labels ?? []" />
|
||||
<FormMultiselect v-model="selectedLocations" label="Locations" :items="locations ?? []" />
|
||||
<div class="flex pb-2 pt-5">
|
||||
<label class="label cursor-pointer mr-auto">
|
||||
<input v-model="includeArchived" type="checkbox" class="toggle toggle-primary" />
|
||||
<span class="label-text ml-4"> Include Archived Items </span>
|
||||
</label>
|
||||
<Spacer />
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
<section class="mt-10">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue