mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-21 21:33:02 +01:00
Get front end tests passing (#299)
* chore: get front end tests passing * chore: add @vue/runtime-core to fix types for $t * chore: sort lockfile * Discard changes to frontend/pnpm-lock.yaml * chore: sort lockfile * chore: fix some type errors * chore: switch from nuxi typecheck to vue-tsc to force a known good version * chore: linting * chore: update pnpm version in frontend test * feat: add proper pagination type (need to sort why it still doesn't work) * chore: format imports and initialize totalPrice in label page to null when no label is present * chore: update pnpm to v9.12.2, merge ItemSummaryPaginationResult with PaginationResult, and handle error in label generator more gracefully * chore: lint --------- Co-authored-by: Matt Kilgore <matthew@kilgore.dev>
This commit is contained in:
4
.github/workflows/partial-frontend.yaml
vendored
4
.github/workflows/partial-frontend.yaml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: pnpm/action-setup@v3.0.0
|
- uses: pnpm/action-setup@v3.0.0
|
||||||
with:
|
with:
|
||||||
version: 6.0.2
|
version: 9.12.2
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --shamefully-hoist
|
run: pnpm install --shamefully-hoist
|
||||||
@@ -54,7 +54,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: pnpm/action-setup@v3.0.0
|
- uses: pnpm/action-setup@v3.0.0
|
||||||
with:
|
with:
|
||||||
version: 6.0.2
|
version: 9.12.2
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|||||||
@@ -28,3 +28,61 @@
|
|||||||
::-webkit-scrollbar-thumb:hover {
|
::-webkit-scrollbar-thumb:hover {
|
||||||
background-color: #9B9B9B;
|
background-color: #9B9B9B;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scroll-bg::-webkit-scrollbar {
|
||||||
|
width: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-bg::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
@apply bg-base-300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown > :first-child {
|
||||||
|
margin-top: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(p, ul, ol, dl, blockquote, h1, h2, h3, h4, h5, h6) {
|
||||||
|
margin-top: var(--y-gap);
|
||||||
|
margin-bottom: var(--y-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(ul) {
|
||||||
|
list-style: disc;
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(ol) {
|
||||||
|
list-style: decimal;
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
/* Heading Styles */
|
||||||
|
.markdown :where(h1) {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(h2) {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(h3) {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(h4) {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(h5) {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown :where(h6) {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
class="flex items-center text-3xl font-bold tracking-tight"
|
class="flex items-center text-3xl font-bold tracking-tight"
|
||||||
:class="{
|
:class="{
|
||||||
'text-neutral-content': dark,
|
'text-neutral-content': dark,
|
||||||
'text-content': !dark,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
|
|||||||
@@ -85,7 +85,10 @@
|
|||||||
type Props = {
|
type Props = {
|
||||||
label: string;
|
label: string;
|
||||||
modelValue: SupportValues | null | undefined;
|
modelValue: SupportValues | null | undefined;
|
||||||
items: string[] | object[];
|
items: {
|
||||||
|
id: string;
|
||||||
|
treeString: string;
|
||||||
|
}[];
|
||||||
display?: string;
|
display?: string;
|
||||||
multiple?: boolean;
|
multiple?: boolean;
|
||||||
};
|
};
|
||||||
@@ -156,7 +159,7 @@
|
|||||||
|
|
||||||
const matches = index.value.search("*" + search.value + "*");
|
const matches = index.value.search("*" + search.value + "*");
|
||||||
|
|
||||||
let resultIDs = []
|
const resultIDs = [];
|
||||||
for (let i = 0; i < matches.length; i++) {
|
for (let i = 0; i < matches.length; i++) {
|
||||||
const match = matches[i];
|
const match = matches[i];
|
||||||
const item = props.items[parseInt(match.ref)];
|
const item = props.items[parseInt(match.ref)];
|
||||||
@@ -170,9 +173,11 @@
|
|||||||
* Resolve the issue of language not being supported
|
* Resolve the issue of language not being supported
|
||||||
*/
|
*/
|
||||||
for (let i = 0; i < props.items.length; i++) {
|
for (let i = 0; i < props.items.length; i++) {
|
||||||
const item = props.items[i]
|
const item = props.items[i];
|
||||||
if(resultIDs.find(item_ => item_ === item.id) != undefined){continue}
|
if (resultIDs.find(item_ => item_ === item.id) !== undefined) {
|
||||||
if(item.treeString.indexOf(search.value) > -1){
|
continue;
|
||||||
|
}
|
||||||
|
if (item.treeString.includes(search.value)) {
|
||||||
const display = extractDisplay(item);
|
const display = extractDisplay(item);
|
||||||
list.push({ id: i, display, value: item });
|
list.push({ id: i, display, value: item });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
:class="{
|
:class="{
|
||||||
'text-red-600':
|
'text-red-600':
|
||||||
typeof value === 'string' &&
|
typeof value === 'string' &&
|
||||||
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
|
((maxLength !== -1 && value.length > maxLength) || (minLength !== -1 && value.length < minLength)),
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
|
{{ typeof value === "string" && (maxLength !== -1 || minLength !== -1) ? `${value.length}/${maxLength}` : "" }}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea ref="el" v-model="value" class="textarea textarea-bordered h-28 w-full" :placeholder="placeholder" />
|
<textarea ref="el" v-model="value" class="textarea textarea-bordered h-28 w-full" :placeholder="placeholder" />
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
:class="{
|
:class="{
|
||||||
'text-red-600':
|
'text-red-600':
|
||||||
typeof value === 'string' &&
|
typeof value === 'string' &&
|
||||||
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
|
((maxLength !== -1 && value.length > maxLength) || (minLength !== -1 && value.length < minLength)),
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
|
{{ typeof value === "string" && (maxLength !== -1 || minLength !== -1) ? `${value.length}/${maxLength}` : "" }}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
@@ -63,10 +63,12 @@
|
|||||||
},
|
},
|
||||||
maxLength: {
|
maxLength: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
default: -1,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
minLength: {
|
minLength: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
default: -1,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -84,7 +86,4 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const value = useVModel(props, "modelValue", emit);
|
const value = useVModel(props, "modelValue", emit);
|
||||||
const valueLen = computed(() => {
|
|
||||||
return value.value ? value.value.length : 0;
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
:class="{
|
:class="{
|
||||||
'text-red-600':
|
'text-red-600':
|
||||||
typeof value === 'string' &&
|
typeof value === 'string' &&
|
||||||
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
|
((maxLength !== -1 && value.length > maxLength) || (minLength !== -1 && value.length < minLength)),
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
|
{{ typeof value === "string" && (maxLength !== -1 || minLength !== -1) ? `${value.length}/${maxLength}` : "" }}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
@@ -28,10 +28,10 @@
|
|||||||
:class="{
|
:class="{
|
||||||
'text-red-600':
|
'text-red-600':
|
||||||
typeof value === 'string' &&
|
typeof value === 'string' &&
|
||||||
((maxLength && value.length > maxLength) || (minLength && value.length < minLength)),
|
((maxLength !== -1 && value.length > maxLength) || (minLength !== -1 && value.length < minLength)),
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ typeof value === "string" && (maxLength || minLength) ? `${value.length}/${maxLength}` : "" }}
|
{{ typeof value === "string" && (maxLength !== -1 || minLength !== -1) ? `${value.length}/${maxLength}` : "" }}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
@@ -76,10 +76,12 @@
|
|||||||
},
|
},
|
||||||
maxLength: {
|
maxLength: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
default: -1,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
minLength: {
|
minLength: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
default: -1,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-span-4 flex grow flex-col gap-y-1 rounded-b bg-base-100 p-4 pt-2">
|
<div class="col-span-4 flex grow flex-col gap-y-1 rounded-b bg-base-100 p-4 pt-2">
|
||||||
<h2 class="line-clamp-2 text-ellipsis text-lg font-bold text-wrap">{{ item.name }}</h2>
|
<h2 class="line-clamp-2 text-ellipsis text-wrap text-lg font-bold">{{ item.name }}</h2>
|
||||||
<div class="divider my-0"></div>
|
<div class="divider my-0"></div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<div v-if="item.insured" class="tooltip z-10" data-tip="Insured">
|
<div v-if="item.insured" class="tooltip z-10" data-tip="Insured">
|
||||||
|
|||||||
@@ -12,7 +12,11 @@
|
|||||||
:max-length="255"
|
:max-length="255"
|
||||||
:min-length="1"
|
:min-length="1"
|
||||||
/>
|
/>
|
||||||
<FormTextArea v-model="form.description" :label="$t('components.item.create_modal.item_description')" :max-length="1000" />
|
<FormTextArea
|
||||||
|
v-model="form.description"
|
||||||
|
:label="$t('components.item.create_modal.item_description')"
|
||||||
|
:max-length="1000"
|
||||||
|
/>
|
||||||
<FormMultiselect v-model="form.labels" :label="$t('global.labels')" :items="labels ?? []" />
|
<FormMultiselect v-model="form.labels" :label="$t('global.labels')" :items="labels ?? []" />
|
||||||
|
|
||||||
<div class="modal-action mb-6">
|
<div class="modal-action mb-6">
|
||||||
@@ -39,7 +43,7 @@
|
|||||||
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
|
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
|
||||||
<MdiChevronDown class="size-5" name="mdi-chevron-down" />
|
<MdiChevronDown class="size-5" name="mdi-chevron-down" />
|
||||||
</label>
|
</label>
|
||||||
<ul tabindex="0" class="dropdown-content menu rounded-box bg-base-100 right-0 w-64 p-2 shadow">
|
<ul tabindex="0" class="dropdown-content menu rounded-box right-0 w-64 bg-base-100 p-2 shadow">
|
||||||
<li>
|
<li>
|
||||||
<button type="button" @click="create(false)">{{ $t("global.create_and_add") }}</button>
|
<button type="button" @click="create(false)">{{ $t("global.create_and_add") }}</button>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<ul tabindex="0" class="dropdown-content rounded-box flex w-64 flex-col gap-2 bg-base-100 p-2 pl-3 shadow">
|
<ul tabindex="0" class="dropdown-content rounded-box flex w-64 flex-col gap-2 bg-base-100 p-2 pl-3 shadow">
|
||||||
<li>Headers:</li>
|
<li>Headers:</li>
|
||||||
<li v-for="(h, i) in headers" class="flex flex-row items-center gap-1">
|
<li v-for="(h, i) in headers" :key="h.value" class="flex flex-row items-center gap-1">
|
||||||
<button
|
<button
|
||||||
class="btn btn-square btn-ghost btn-xs"
|
class="btn btn-square btn-ghost btn-xs"
|
||||||
:class="{
|
:class="{
|
||||||
@@ -150,7 +150,10 @@
|
|||||||
|
|
||||||
const defaultHeaders = [
|
const defaultHeaders = [
|
||||||
{
|
{
|
||||||
text: "items.name", value: "name", enabled: true, type: "name"
|
text: "items.name",
|
||||||
|
value: "name",
|
||||||
|
enabled: true,
|
||||||
|
type: "name",
|
||||||
},
|
},
|
||||||
{ text: "items.quantity", value: "quantity", align: "center", enabled: true },
|
{ text: "items.quantity", value: "quantity", align: "center", enabled: true },
|
||||||
{ text: "items.insured", value: "insured", align: "center", enabled: true, type: "boolean" },
|
{ text: "items.insured", value: "insured", align: "center", enabled: true, type: "boolean" },
|
||||||
@@ -162,16 +165,13 @@
|
|||||||
] satisfies TableHeader[];
|
] satisfies TableHeader[];
|
||||||
|
|
||||||
const headers = ref<TableHeader[]>(
|
const headers = ref<TableHeader[]>(
|
||||||
(preferences.value.tableHeaders ?? []).concat(
|
(preferences.value.tableHeaders ?? [])
|
||||||
defaultHeaders.filter(h => !preferences.value.tableHeaders?.find(h2 => h2.value === h.value))
|
.concat(defaultHeaders.filter(h => !preferences.value.tableHeaders?.find(h2 => h2.value === h.value)))
|
||||||
)
|
|
||||||
// this is a hack to make sure that any changes to the defaultHeaders are reflected in the preferences
|
// this is a hack to make sure that any changes to the defaultHeaders are reflected in the preferences
|
||||||
.map(h => (
|
.map(h => ({
|
||||||
{
|
...(defaultHeaders.find(h2 => h2.value === h.value) as TableHeader),
|
||||||
...defaultHeaders.find(h2 => h2.value === h.value) as TableHeader,
|
enabled: h.enabled,
|
||||||
enabled: h.enabled
|
}))
|
||||||
}
|
|
||||||
))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(headers.value);
|
console.log(headers.value);
|
||||||
|
|||||||
@@ -11,7 +11,11 @@
|
|||||||
:max-length="255"
|
:max-length="255"
|
||||||
:min-length="1"
|
:min-length="1"
|
||||||
/>
|
/>
|
||||||
<FormTextArea v-model="form.description" :label="$t('components.label.create_modal.label_description')" :max-length="255" />
|
<FormTextArea
|
||||||
|
v-model="form.description"
|
||||||
|
:label="$t('components.label.create_modal.label_description')"
|
||||||
|
:max-length="255"
|
||||||
|
/>
|
||||||
<div class="modal-action">
|
<div class="modal-action">
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> {{ $t("global.create") }} </BaseButton>
|
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> {{ $t("global.create") }} </BaseButton>
|
||||||
|
|||||||
@@ -12,7 +12,11 @@
|
|||||||
:max-length="255"
|
:max-length="255"
|
||||||
:min-length="1"
|
:min-length="1"
|
||||||
/>
|
/>
|
||||||
<FormTextArea v-model="form.description" :label="$t('components.location.create_modal.location_description')" :max-length="1000" />
|
<FormTextArea
|
||||||
|
v-model="form.description"
|
||||||
|
:label="$t('components.location.create_modal.location_description')"
|
||||||
|
:max-length="1000"
|
||||||
|
/>
|
||||||
<LocationSelector v-model="form.parent" />
|
<LocationSelector v-model="form.parent" />
|
||||||
<div class="modal-action">
|
<div class="modal-action">
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
@@ -21,7 +25,7 @@
|
|||||||
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
|
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
|
||||||
<MdiChevronDown class="size-5" />
|
<MdiChevronDown class="size-5" />
|
||||||
</label>
|
</label>
|
||||||
<ul tabindex="0" class="dropdown-content menu rounded-box bg-base-100 right-0 w-64 p-2 shadow">
|
<ul tabindex="0" class="dropdown-content menu rounded-box right-0 w-64 bg-base-100 p-2 shadow">
|
||||||
<li>
|
<li>
|
||||||
<button type="button" @click="create(false)">{{ $t("global.create_and_add") }}</button>
|
<button type="button" @click="create(false)">{{ $t("global.create_and_add") }}</button>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<FormAutocomplete2 v-if="locations" v-model="value" :items="locations" display="name" :label="$t('components.location.selector.parent_location')">
|
<FormAutocomplete2
|
||||||
|
v-if="locations"
|
||||||
|
v-model="value"
|
||||||
|
:items="locations"
|
||||||
|
display="name"
|
||||||
|
:label="$t('components.location.selector.parent_location')"
|
||||||
|
>
|
||||||
<template #display="{ item, selected, active }">
|
<template #display="{ item, selected, active }">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<!-- eslint-disable-next-line tailwindcss/no-custom-classname -->
|
||||||
<div class="root border-2 p-4">
|
<div class="root border-2 p-4">
|
||||||
<p v-if="locs.length === 0" class="text-center text-sm">
|
<p v-if="locs.length === 0" class="text-center text-sm">
|
||||||
{{ $t("location.tree.no_locations") }}
|
{{ $t("location.tree.no_locations") }}
|
||||||
|
|||||||
@@ -25,17 +25,17 @@
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: maintenanceDataList, refresh: refreshList } = useAsyncData<MaintenanceEntryWithDetails[]>(
|
const { data: maintenanceDataList, refresh: refreshList } = useAsyncData(
|
||||||
async () => {
|
async () => {
|
||||||
const { data } =
|
const { data } =
|
||||||
props.currentItemId !== undefined
|
props.currentItemId !== undefined
|
||||||
? await api.items.maintenance.getLog(props.currentItemId, { status: maintenanceFilterStatus.value })
|
? await api.items.maintenance.getLog(props.currentItemId, { status: maintenanceFilterStatus.value })
|
||||||
: await api.maintenance.getAll({ status: maintenanceFilterStatus.value });
|
: await api.maintenance.getAll({ status: maintenanceFilterStatus.value });
|
||||||
console.log(data);
|
console.log(data);
|
||||||
return data as MaintenanceEntryWithDetails[];
|
return data;
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
watch: maintenanceFilterStatus,
|
watch: [maintenanceFilterStatus],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
<StatCard
|
<StatCard
|
||||||
v-for="stat in stats"
|
v-for="stat in stats"
|
||||||
:key="stat.id"
|
:key="stat.id"
|
||||||
class="stats border-l-primary block shadow-xl"
|
class="stats block border-l-primary shadow-xl"
|
||||||
:title="stat.title"
|
:title="stat.title"
|
||||||
:value="stat.value"
|
:value="stat.value"
|
||||||
:type="stat.type"
|
:type="stat.type"
|
||||||
@@ -189,7 +189,7 @@
|
|||||||
<div v-if="props.currentItemId" class="hidden first:block">
|
<div v-if="props.currentItemId" class="hidden first:block">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="border-base-content relative block w-full rounded-lg border-2 border-dashed p-12 text-center"
|
class="relative block w-full rounded-lg border-2 border-dashed border-base-content p-12 text-center"
|
||||||
@click="maintenanceEditModal?.openCreateModal(props.currentItemId)"
|
@click="maintenanceEditModal?.openCreateModal(props.currentItemId)"
|
||||||
>
|
>
|
||||||
<MdiWrenchClock class="inline size-16" />
|
<MdiWrenchClock class="inline size-16" />
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<div class="markdown text-wrap" v-html="raw"></div>
|
<div class="markdown text-wrap" v-html="raw"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -31,53 +32,4 @@
|
|||||||
* {
|
* {
|
||||||
--y-gap: 0.65rem;
|
--y-gap: 0.65rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown > :first-child {
|
|
||||||
margin-top: 0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown :where(p, ul, ol, dl, blockquote, h1, h2, h3, h4, h5, h6) {
|
|
||||||
margin-top: var(--y-gap);
|
|
||||||
margin-bottom: var(--y-gap);
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown :where(ul) {
|
|
||||||
list-style: disc;
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown :where(ol) {
|
|
||||||
list-style: decimal;
|
|
||||||
margin-left: 2rem;
|
|
||||||
}
|
|
||||||
/* Heading Styles */
|
|
||||||
.markdown :where(h1) {
|
|
||||||
font-size: 2rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown :where(h2) {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown :where(h3) {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown :where(h4) {
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown :where(h5) {
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.markdown :where(h6) {
|
|
||||||
font-size: 0.75rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ export function useLocaleTimeAgo(date: Date) {
|
|||||||
|
|
||||||
const I18N_MESSAGES: UseTimeAgoMessages<UseTimeAgoUnitNamesDefault> = {
|
const I18N_MESSAGES: UseTimeAgoMessages<UseTimeAgoUnitNamesDefault> = {
|
||||||
justNow: t("components.global.date_time.just-now"),
|
justNow: t("components.global.date_time.just-now"),
|
||||||
past: (n) => (n.match(/\d/) ? t("components.global.date_time.ago", [n]) : n),
|
past: n => (n.match(/\d/) ? t("components.global.date_time.ago", [n]) : n),
|
||||||
future: (n) => (n.match(/\d/) ? t("components.global.date_time.in", [n]) : n),
|
future: n => (n.match(/\d/) ? t("components.global.date_time.in", [n]) : n),
|
||||||
month: (n, past) =>
|
month: (n, past) =>
|
||||||
n === 1
|
n === 1
|
||||||
? past
|
? past
|
||||||
@@ -71,17 +71,9 @@ export function useLocaleTimeAgo(date: Date) {
|
|||||||
? t("components.global.date_time.last-week")
|
? t("components.global.date_time.last-week")
|
||||||
: t("components.global.date_time.next-week")
|
: t("components.global.date_time.next-week")
|
||||||
: `${n} ${t(`components.global.date_time.weeks`)}`,
|
: `${n} ${t(`components.global.date_time.weeks`)}`,
|
||||||
hour: (n) => `${n} ${
|
hour: n => `${n} ${n === 1 ? t("components.global.date_time.hour") : t("components.global.date_time.hours")}`,
|
||||||
n === 1 ? t("components.global.date_time.hour") : t("components.global.date_time.hours")
|
minute: n => `${n} ${n === 1 ? t("components.global.date_time.minute") : t("components.global.date_time.minutes")}`,
|
||||||
}`,
|
second: n => `${n} ${n === 1 ? t("components.global.date_time.second") : t("components.global.date_time.seconds")}`,
|
||||||
minute: (n) => `${n} ${
|
|
||||||
n === 1 ? t("components.global.date_time.minute") : t("components.global.date_time.minutes")
|
|
||||||
}`,
|
|
||||||
second: (n) => `${n} ${
|
|
||||||
n === 1
|
|
||||||
? t("components.global.date_time.second")
|
|
||||||
: t("components.global.date_time.seconds")
|
|
||||||
}`,
|
|
||||||
invalid: "",
|
invalid: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -91,10 +83,7 @@ export function useLocaleTimeAgo(date: Date) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fmtDate(
|
export function fmtDate(value: string | Date, fmt: DateTimeFormat = "human"): string {
|
||||||
value: string | Date,
|
|
||||||
fmt: DateTimeFormat = "human"
|
|
||||||
): string {
|
|
||||||
const months = [
|
const months = [
|
||||||
"January",
|
"January",
|
||||||
"February",
|
"February",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { Ref } from "vue";
|
import type { Ref } from "vue";
|
||||||
import type { TableHeader } from "components/Item/View/Table.types";
|
import type { TableHeader } from "~/components/Item/View/Table.types";
|
||||||
import type { DaisyTheme } from "~~/lib/data/themes";
|
import type { DaisyTheme } from "~~/lib/data/themes";
|
||||||
|
|
||||||
export type ViewType = "table" | "card" | "tree";
|
export type ViewType = "table" | "card" | "tree";
|
||||||
|
|||||||
@@ -12,15 +12,15 @@
|
|||||||
<AppToast />
|
<AppToast />
|
||||||
<div class="drawer drawer-mobile">
|
<div class="drawer drawer-mobile">
|
||||||
<input id="my-drawer-2" v-model="drawerToggle" type="checkbox" class="drawer-toggle" />
|
<input id="my-drawer-2" v-model="drawerToggle" type="checkbox" class="drawer-toggle" />
|
||||||
<div class="drawer-content bg-base-300 justify-center pt-20 lg:pt-0">
|
<div class="drawer-content justify-center bg-base-300 pt-20 lg:pt-0">
|
||||||
<AppHeaderDecor v-if="preferences.displayHeaderDecor" class="-mt-10 hidden lg:block" />
|
<AppHeaderDecor v-if="preferences.displayHeaderDecor" class="-mt-10 hidden lg:block" />
|
||||||
<!-- Button -->
|
<!-- Button -->
|
||||||
<div class="navbar drawer-button bg-primary fixed top-0 z-[99] shadow-md lg:hidden">
|
<div class="navbar drawer-button fixed top-0 z-[99] bg-primary shadow-md lg:hidden">
|
||||||
<label for="my-drawer-2" class="btn btn-square btn-ghost drawer-button text-base-100 lg:hidden">
|
<label for="my-drawer-2" class="btn btn-square btn-ghost drawer-button text-base-100 lg:hidden">
|
||||||
<MdiMenu class="size-6" />
|
<MdiMenu class="size-6" />
|
||||||
</label>
|
</label>
|
||||||
<NuxtLink to="/home">
|
<NuxtLink to="/home">
|
||||||
<h2 class="text-base-100 flex text-3xl font-bold tracking-tight">
|
<h2 class="flex text-3xl font-bold tracking-tight text-base-100">
|
||||||
HomeB
|
HomeB
|
||||||
<AppLogo class="-mb-3 w-8" />
|
<AppLogo class="-mb-3 w-8" />
|
||||||
x
|
x
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<footer v-if="status" class="bg-base-300 text-secondary-content bottom-0 w-full pb-4 text-center">
|
<footer v-if="status" class="bottom-0 w-full bg-base-300 pb-4 text-center text-secondary-content">
|
||||||
<p class="text-center text-sm">
|
<p class="text-center text-sm">
|
||||||
{{ $t("global.version", { version: status.build.version }) }} ~
|
{{ $t("global.version", { version: status.build.version }) }} ~
|
||||||
{{ $t("global.build", { build: status.build.commit }) }}
|
{{ $t("global.build", { build: status.build.commit }) }}
|
||||||
@@ -42,17 +42,17 @@
|
|||||||
<label for="my-drawer-2" class="drawer-overlay"></label>
|
<label for="my-drawer-2" class="drawer-overlay"></label>
|
||||||
|
|
||||||
<!-- Top Section -->
|
<!-- Top Section -->
|
||||||
<div class="bg-base-200 flex min-w-40 max-w-min flex-col p-5 md:py-10">
|
<div class="flex min-w-40 max-w-min flex-col bg-base-200 p-5 md:py-10">
|
||||||
<div class="space-y-8">
|
<div class="space-y-8">
|
||||||
<div class="flex flex-col items-center gap-4">
|
<div class="flex flex-col items-center gap-4">
|
||||||
<p>{{ $t("global.welcome", { username: username }) }}</p>
|
<p>{{ $t("global.welcome", { username: username }) }}</p>
|
||||||
<NuxtLink class="avatar placeholder" to="/home">
|
<NuxtLink class="avatar placeholder" to="/home">
|
||||||
<div class="bg-base-300 text-neutral-content w-24 rounded-full p-4">
|
<div class="w-24 rounded-full bg-base-300 p-4 text-neutral-content">
|
||||||
<AppLogo />
|
<AppLogo />
|
||||||
</div>
|
</div>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-base-200 flex flex-col">
|
<div class="flex flex-col bg-base-200">
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<div class="dropdown visible w-full">
|
<div class="dropdown visible w-full">
|
||||||
<label tabindex="0" class="text-no-transform btn btn-primary btn-block text-lg">
|
<label tabindex="0" class="text-no-transform btn btn-primary btn-block text-lg">
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{{ $t("global.create") }}
|
{{ $t("global.create") }}
|
||||||
</label>
|
</label>
|
||||||
<ul tabindex="0" class="dropdown-content menu rounded-box bg-base-100 w-full p-2 shadow">
|
<ul tabindex="0" class="dropdown-content menu rounded-box w-full bg-base-100 p-2 shadow">
|
||||||
<li v-for="btn in dropdown" :key="btn.id">
|
<li v-for="btn in dropdown" :key="btn.id">
|
||||||
<button @click="btn.action">
|
<button @click="btn.action">
|
||||||
{{ btn.name.value }}
|
{{ btn.name.value }}
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Bottom -->
|
<!-- Bottom -->
|
||||||
<button class="rounded-btn hover:bg-base-300 mx-2 mt-auto p-3" @click="logout">
|
<button class="rounded-btn mx-2 mt-auto p-3 hover:bg-base-300" @click="logout">
|
||||||
{{ $t("global.sign_out") }}
|
{{ $t("global.sign_out") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -148,9 +148,7 @@ describe("user should be able to create an item and add an attachment", () => {
|
|||||||
{
|
{
|
||||||
const { response, data } = await api.items.maintenance.getLog(item.id);
|
const { response, data } = await api.items.maintenance.getLog(item.id);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
expect(data.entries).toHaveLength(maintenanceEntries.length);
|
expect(data).toHaveLength(maintenanceEntries.length);
|
||||||
expect(data.costAverage).toBeGreaterThan(0);
|
|
||||||
expect(data.costTotal).toBeGreaterThan(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import type {
|
|||||||
MaintenanceEntryCreate,
|
MaintenanceEntryCreate,
|
||||||
MaintenanceEntryWithDetails,
|
MaintenanceEntryWithDetails,
|
||||||
} from "../types/data-contracts";
|
} from "../types/data-contracts";
|
||||||
import type { AttachmentTypes, PaginationResult } from "../types/non-generated";
|
import type { AttachmentTypes, ItemSummaryPaginationResult } from "../types/non-generated";
|
||||||
import type { MaintenanceFilters } from "./maintenance.ts";
|
import type { MaintenanceFilters } from "./maintenance.ts";
|
||||||
import type { Requests } from "~~/lib/requests";
|
import type { Requests } from "~~/lib/requests";
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ export class ItemsApi extends BaseAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getAll(q: ItemsQuery = {}) {
|
getAll(q: ItemsQuery = {}) {
|
||||||
return this.http.get<PaginationResult<ItemSummary>>({ url: route("/items", q) });
|
return this.http.get<ItemSummaryPaginationResult<ItemSummary>>({ url: route("/items", q) });
|
||||||
}
|
}
|
||||||
|
|
||||||
create(item: ItemCreate) {
|
create(item: ItemCreate) {
|
||||||
|
|||||||
@@ -16,3 +16,7 @@ export interface PaginationResult<T> {
|
|||||||
pageSize: number;
|
pageSize: number;
|
||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ItemSummaryPaginationResult<T> extends PaginationResult<T> {
|
||||||
|
totalPrice: number;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"lint": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore .",
|
"lint": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore .",
|
||||||
"lint:fix": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore . --fix",
|
"lint:fix": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore . --fix",
|
||||||
"lint:ci": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore . --max-warnings 1",
|
"lint:ci": "eslint --ext \".ts,.js,.vue\" --ignore-path ../.gitignore . --max-warnings 1",
|
||||||
"typecheck": "nuxi typecheck",
|
"typecheck": "pnpm dlx vue-tsc@2.1.6 --noEmit",
|
||||||
"test:ci": "TEST_SHUTDOWN_API_SERVER=true vitest --run --config ./test/vitest.config.ts",
|
"test:ci": "TEST_SHUTDOWN_API_SERVER=true vitest --run --config ./test/vitest.config.ts",
|
||||||
"test:local": "TEST_SHUTDOWN_API_SERVER=false && vitest --run --config ./test/vitest.config.ts",
|
"test:local": "TEST_SHUTDOWN_API_SERVER=false && vitest --run --config ./test/vitest.config.ts",
|
||||||
"test:watch": " TEST_SHUTDOWN_API_SERVER=false vitest --config ./test/vitest.config.ts"
|
"test:watch": " TEST_SHUTDOWN_API_SERVER=false vitest --config ./test/vitest.config.ts"
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||||
"@typescript-eslint/parser": "^6.21.0",
|
"@typescript-eslint/parser": "^6.21.0",
|
||||||
"@vite-pwa/nuxt": "^0.5.0",
|
"@vite-pwa/nuxt": "^0.5.0",
|
||||||
|
"@vue/runtime-core": "^3.5.12",
|
||||||
"eslint": "^8.57.1",
|
"eslint": "^8.57.1",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
|
|||||||
@@ -234,7 +234,7 @@
|
|||||||
details.push({
|
details.push({
|
||||||
name,
|
name,
|
||||||
text: "",
|
text: "",
|
||||||
slot: slot,
|
slot,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -624,13 +624,4 @@
|
|||||||
dialog::backdrop {
|
dialog::backdrop {
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroll-bg::-webkit-scrollbar {
|
|
||||||
width: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-bg::-webkit-scrollbar-thumb {
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
@apply bg-base-300;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
if (item.value.soldPrice) {
|
if (item.value.soldPrice) {
|
||||||
soldPrice = item.value.soldPrice;
|
soldPrice = item.value.soldPrice;
|
||||||
}
|
}
|
||||||
if (item.value.purchaseTime) {
|
if (item.value.purchaseTime && typeof item.value.purchaseTime !== "string") {
|
||||||
purchaseTime = new Date(item.value.purchaseTime.getTime() - item.value.purchaseTime.getTimezoneOffset() * 60000);
|
purchaseTime = new Date(item.value.purchaseTime.getTime() - item.value.purchaseTime.getTimezoneOffset() * 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
assetId: item.value.assetId,
|
assetId: item.value.assetId,
|
||||||
purchasePrice,
|
purchasePrice,
|
||||||
soldPrice,
|
soldPrice,
|
||||||
purchaseTime,
|
purchaseTime: purchaseTime as Date,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { error } = await api.items.update(itemId.value, payload);
|
const { error } = await api.items.update(itemId.value, payload);
|
||||||
@@ -611,7 +611,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 flex justify-end px-5 pb-4">
|
<div class="mt-4 flex justify-end px-5 pb-4">
|
||||||
<BaseButton size="sm" @click="addField"> {{$t("global.add")}} </BaseButton>
|
<BaseButton size="sm" @click="addField"> {{ $t("global.add") }} </BaseButton>
|
||||||
</div>
|
</div>
|
||||||
</BaseCard>
|
</BaseCard>
|
||||||
|
|
||||||
@@ -621,7 +621,7 @@
|
|||||||
class="card overflow-visible bg-base-100 shadow-xl sm:rounded-lg"
|
class="card overflow-visible bg-base-100 shadow-xl sm:rounded-lg"
|
||||||
>
|
>
|
||||||
<div class="px-4 py-5 sm:px-6">
|
<div class="px-4 py-5 sm:px-6">
|
||||||
<h3 class="text-lg font-medium leading-6"> {{ $t("items.attachments") }} </h3>
|
<h3 class="text-lg font-medium leading-6">{{ $t("items.attachments") }}</h3>
|
||||||
<p class="text-xs">{{ $t("items.changes_persisted_immediately") }}</p>
|
<p class="text-xs">{{ $t("items.changes_persisted_immediately") }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-t border-gray-300 p-4">
|
<div class="border-t border-gray-300 p-4">
|
||||||
|
|||||||
@@ -76,7 +76,10 @@
|
|||||||
|
|
||||||
const items = computedAsync(async () => {
|
const items = computedAsync(async () => {
|
||||||
if (!label.value) {
|
if (!label.value) {
|
||||||
return [];
|
return {
|
||||||
|
items: [],
|
||||||
|
totalPrice: null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const resp = await api.items.getAll({
|
const resp = await api.items.getAll({
|
||||||
@@ -85,7 +88,10 @@
|
|||||||
|
|
||||||
if (resp.error) {
|
if (resp.error) {
|
||||||
toast.error("Failed to load items");
|
toast.error("Failed to load items");
|
||||||
return [];
|
return {
|
||||||
|
items: [],
|
||||||
|
totalPrice: null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.data;
|
return resp.data;
|
||||||
@@ -104,9 +110,13 @@
|
|||||||
:max-length="255"
|
:max-length="255"
|
||||||
:min-length="1"
|
:min-length="1"
|
||||||
/>
|
/>
|
||||||
<FormTextArea v-model="updateData.description" :label="$t('components.label.create_modal.label_description')" :max-length="255" />
|
<FormTextArea
|
||||||
|
v-model="updateData.description"
|
||||||
|
:label="$t('components.label.create_modal.label_description')"
|
||||||
|
:max-length="255"
|
||||||
|
/>
|
||||||
<div class="modal-action">
|
<div class="modal-action">
|
||||||
<BaseButton type="submit" :loading="updating"> {{$t("global.update")}} </BaseButton>
|
<BaseButton type="submit" :loading="updating"> {{ $t("global.update") }} </BaseButton>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</BaseModal>
|
</BaseModal>
|
||||||
|
|||||||
@@ -111,8 +111,18 @@
|
|||||||
<BaseModal v-model="updateModal">
|
<BaseModal v-model="updateModal">
|
||||||
<template #title> {{ $t("locations.update_location") }} </template>
|
<template #title> {{ $t("locations.update_location") }} </template>
|
||||||
<form v-if="location" @submit.prevent="update">
|
<form v-if="location" @submit.prevent="update">
|
||||||
<FormTextField v-model="updateData.name" :autofocus="true" :label="$t('components.location.create_modal.location_name')" :max-length="255" :min-length="1" />
|
<FormTextField
|
||||||
<FormTextArea v-model="updateData.description" :label="$t('components.location.create_modal.location_description')" :max-length="1000" />
|
v-model="updateData.name"
|
||||||
|
:autofocus="true"
|
||||||
|
:label="$t('components.location.create_modal.location_name')"
|
||||||
|
:max-length="255"
|
||||||
|
:min-length="1"
|
||||||
|
/>
|
||||||
|
<FormTextArea
|
||||||
|
v-model="updateData.description"
|
||||||
|
:label="$t('components.location.create_modal.location_description')"
|
||||||
|
:max-length="1000"
|
||||||
|
/>
|
||||||
<LocationSelector v-model="parent" />
|
<LocationSelector v-model="parent" />
|
||||||
<div class="modal-action">
|
<div class="modal-action">
|
||||||
<BaseButton type="submit" :loading="updating"> {{ $t("global.update") }} </BaseButton>
|
<BaseButton type="submit" :loading="updating"> {{ $t("global.update") }} </BaseButton>
|
||||||
@@ -180,7 +190,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section v-if="location && location.children.length > 0" class="mt-6">
|
<section v-if="location && location.children.length > 0" class="mt-6">
|
||||||
<BaseSectionHeader class="mb-5"> {{ t("locations.child_locations") }} </BaseSectionHeader>
|
<BaseSectionHeader class="mb-5"> {{ $t("locations.child_locations") }} </BaseSectionHeader>
|
||||||
<div class="grid grid-cols-1 gap-2 sm:grid-cols-3">
|
<div class="grid grid-cols-1 gap-2 sm:grid-cols-3">
|
||||||
<LocationCard v-for="item in location.children" :key="item.id" :location="item" />
|
<LocationCard v-for="item in location.children" :key="item.id" :location="item" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
import MdiFill from "~icons/mdi/fill";
|
import MdiFill from "~icons/mdi/fill";
|
||||||
import MdiPencil from "~icons/mdi/pencil";
|
import MdiPencil from "~icons/mdi/pencil";
|
||||||
import MdiAccountMultiple from "~icons/mdi/account-multiple";
|
import MdiAccountMultiple from "~icons/mdi/account-multiple";
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: ["auth"],
|
middleware: ["auth"],
|
||||||
@@ -20,7 +19,6 @@ import { useI18n } from "vue-i18n";
|
|||||||
const api = useUserApi();
|
const api = useUserApi();
|
||||||
const confirm = useConfirm();
|
const confirm = useConfirm();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
const currencies = computedAsync(async () => {
|
const currencies = computedAsync(async () => {
|
||||||
const resp = await api.group.currencies();
|
const resp = await api.group.currencies();
|
||||||
@@ -378,8 +376,15 @@ import { useI18n } from "vue-i18n";
|
|||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">{{ $t("profile.language") }}</span>
|
<span class="label-text">{{ $t("profile.language") }}</span>
|
||||||
</label>
|
</label>
|
||||||
<select v-model="$i18n.locale" @change="(event) => {setLanguage((event.target as HTMLSelectElement).value )}"
|
<select
|
||||||
class="select select-bordered">
|
v-model="$i18n.locale"
|
||||||
|
class="select select-bordered"
|
||||||
|
@change="
|
||||||
|
event => {
|
||||||
|
setLanguage((event.target as HTMLSelectElement).value);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
<option v-for="lang in $i18n.availableLocales" :key="lang" :value="lang">
|
<option v-for="lang in $i18n.availableLocales" :key="lang" :value="lang">
|
||||||
{{ $t(`languages.${lang}`) }} ({{ $t(`languages.${lang}`, 1, { locale: lang }) }})
|
{{ $t(`languages.${lang}`) }} ({{ $t(`languages.${lang}`, 1, { locale: lang }) }})
|
||||||
</option>
|
</option>
|
||||||
@@ -447,7 +452,7 @@ import { useI18n } from "vue-i18n";
|
|||||||
|
|
||||||
<div v-if="group && currencies && currencies.length > 0" class="p-5 pt-0">
|
<div v-if="group && currencies && currencies.length > 0" class="p-5 pt-0">
|
||||||
<FormSelect v-model="currency" :label="$t('profile.currency_format')" :items="currencies" />
|
<FormSelect v-model="currency" :label="$t('profile.currency_format')" :items="currencies" />
|
||||||
<p class="m-2 text-sm">{{$t("profile.example")}}: {{ currencyExample }}</p>
|
<p class="m-2 text-sm">{{ $t("profile.example") }}: {{ currencyExample }}</p>
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<BaseButton size="sm" @click="updateGroup"> {{ $t("profile.update_group") }} </BaseButton>
|
<BaseButton size="sm" @click="updateGroup"> {{ $t("profile.update_group") }} </BaseButton>
|
||||||
|
|||||||
@@ -200,7 +200,9 @@
|
|||||||
const { data, error } = await api.items.getAll();
|
const { data, error } = await api.items.getAll();
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return [];
|
return {
|
||||||
|
items: [],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@@ -219,7 +221,12 @@
|
|||||||
|
|
||||||
const items: LabelData[] = [];
|
const items: LabelData[] = [];
|
||||||
for (let i = displayProperties.assetRange; i < displayProperties.assetRangeMax; i++) {
|
for (let i = displayProperties.assetRange; i < displayProperties.assetRangeMax; i++) {
|
||||||
items.push(getItem(i, allFields?.value?.items?.[i] ?? null));
|
const item = allFields?.value?.items?.[i];
|
||||||
|
if (item?.location) {
|
||||||
|
items.push(getItem(i, item as { location: { name: string }; name: string }));
|
||||||
|
} else {
|
||||||
|
items.push(getItem(i, null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
<div class="divide-y divide-gray-300 border-t border-gray-300 px-6 pb-3">
|
<div class="divide-y divide-gray-300 border-t border-gray-300 px-6 pb-3">
|
||||||
<DetailAction @action="modals.import = true">
|
<DetailAction @action="modals.import = true">
|
||||||
<template #title> {{ $t("tools.import_export_set.import") }} </template>
|
<template #title> {{ $t("tools.import_export_set.import") }} </template>
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<div v-html="$t('tools.import_export_set.import_sub')"></div>
|
<div v-html="$t('tools.import_export_set.import_sub')"></div>
|
||||||
<template #button> {{ $t("tools.import_export_set.import_button") }} </template>
|
<template #button> {{ $t("tools.import_export_set.import_button") }} </template>
|
||||||
</DetailAction>
|
</DetailAction>
|
||||||
@@ -55,6 +56,7 @@
|
|||||||
<MdiAlert class="mr-2" />
|
<MdiAlert class="mr-2" />
|
||||||
<span> {{ $t("tools.actions") }} </span>
|
<span> {{ $t("tools.actions") }} </span>
|
||||||
<template #description>
|
<template #description>
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<div v-html="$t('tools.actions_sub')"></div>
|
<div v-html="$t('tools.actions_sub')"></div>
|
||||||
</template>
|
</template>
|
||||||
</BaseSectionHeader>
|
</BaseSectionHeader>
|
||||||
@@ -72,11 +74,13 @@
|
|||||||
</DetailAction>
|
</DetailAction>
|
||||||
<DetailAction @action="resetItemDateTimes">
|
<DetailAction @action="resetItemDateTimes">
|
||||||
<template #title> {{ $t("tools.actions_set.zero_datetimes") }} </template>
|
<template #title> {{ $t("tools.actions_set.zero_datetimes") }} </template>
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<div v-html="$t('tools.actions_set.zero_datetimes_sub')"></div>
|
<div v-html="$t('tools.actions_set.zero_datetimes_sub')"></div>
|
||||||
<template #button> {{ $t("tools.actions_set.zero_datetimes_button") }} </template>
|
<template #button> {{ $t("tools.actions_set.zero_datetimes_button") }} </template>
|
||||||
</DetailAction>
|
</DetailAction>
|
||||||
<DetailAction @action="setPrimaryPhotos">
|
<DetailAction @action="setPrimaryPhotos">
|
||||||
<template #title> {{ $t("tools.actions_set.set_primary_photo") }} </template>
|
<template #title> {{ $t("tools.actions_set.set_primary_photo") }} </template>
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<div v-html="$t('tools.actions_set.set_primary_photo_sub')"></div>
|
<div v-html="$t('tools.actions_set.set_primary_photo_sub')"></div>
|
||||||
<template #button> {{ $t("tools.actions_set.set_primary_photo_button") }} </template>
|
<template #button> {{ $t("tools.actions_set.set_primary_photo_button") }} </template>
|
||||||
</DetailAction>
|
</DetailAction>
|
||||||
|
|||||||
37
frontend/pnpm-lock.yaml
generated
37
frontend/pnpm-lock.yaml
generated
@@ -105,6 +105,9 @@ importers:
|
|||||||
'@vite-pwa/nuxt':
|
'@vite-pwa/nuxt':
|
||||||
specifier: ^0.5.0
|
specifier: ^0.5.0
|
||||||
version: 0.5.0(magicast@0.3.5)(rollup@4.24.0)(vite@4.5.5(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3)(workbox-build@7.1.1)(workbox-window@7.1.0)
|
version: 0.5.0(magicast@0.3.5)(rollup@4.24.0)(vite@4.5.5(@types/node@22.7.4)(terser@5.34.1))(webpack-sources@3.2.3)(workbox-build@7.1.1)(workbox-window@7.1.0)
|
||||||
|
'@vue/runtime-core':
|
||||||
|
specifier: ^3.5.12
|
||||||
|
version: 3.5.12
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^8.57.1
|
specifier: ^8.57.1
|
||||||
version: 8.57.1
|
version: 8.57.1
|
||||||
@@ -2083,9 +2086,15 @@ packages:
|
|||||||
'@vue/reactivity@3.4.8':
|
'@vue/reactivity@3.4.8':
|
||||||
resolution: {integrity: sha512-UJYMQ3S2rqIGw9IvKomD4Xw2uS5VlcKEEmwcfboGOdrI79oqebxnCgTvXWLMClvg3M5SF0Cyn+9eDQoyGMLu9Q==}
|
resolution: {integrity: sha512-UJYMQ3S2rqIGw9IvKomD4Xw2uS5VlcKEEmwcfboGOdrI79oqebxnCgTvXWLMClvg3M5SF0Cyn+9eDQoyGMLu9Q==}
|
||||||
|
|
||||||
|
'@vue/reactivity@3.5.12':
|
||||||
|
resolution: {integrity: sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==}
|
||||||
|
|
||||||
'@vue/runtime-core@3.4.8':
|
'@vue/runtime-core@3.4.8':
|
||||||
resolution: {integrity: sha512-sMRXOy89KnwY6fWG5epgPOsCWzpo/64FrA0QkjIeNeGnoA2YyZ6bBUxpFUyqhJ8VbrDhXEFH+6LHMOYrpzX/ZQ==}
|
resolution: {integrity: sha512-sMRXOy89KnwY6fWG5epgPOsCWzpo/64FrA0QkjIeNeGnoA2YyZ6bBUxpFUyqhJ8VbrDhXEFH+6LHMOYrpzX/ZQ==}
|
||||||
|
|
||||||
|
'@vue/runtime-core@3.5.12':
|
||||||
|
resolution: {integrity: sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==}
|
||||||
|
|
||||||
'@vue/runtime-dom@3.4.8':
|
'@vue/runtime-dom@3.4.8':
|
||||||
resolution: {integrity: sha512-L4gZcYo8f3d7rQqQIHkPvyczkjjQ55cJqz2G0v6Ptmqa1mO2zkqN9F8lBT6aGPYy3hd0RDiINbs4jxhSvvy10Q==}
|
resolution: {integrity: sha512-L4gZcYo8f3d7rQqQIHkPvyczkjjQ55cJqz2G0v6Ptmqa1mO2zkqN9F8lBT6aGPYy3hd0RDiINbs4jxhSvvy10Q==}
|
||||||
|
|
||||||
@@ -2100,6 +2109,9 @@ packages:
|
|||||||
'@vue/shared@3.5.11':
|
'@vue/shared@3.5.11':
|
||||||
resolution: {integrity: sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==}
|
resolution: {integrity: sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==}
|
||||||
|
|
||||||
|
'@vue/shared@3.5.12':
|
||||||
|
resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==}
|
||||||
|
|
||||||
'@vuepic/vue-datepicker@8.8.1':
|
'@vuepic/vue-datepicker@8.8.1':
|
||||||
resolution: {integrity: sha512-8ehfUz1m69Vuc16Pm4ukgb3Mg1VT14x4EsG1ag4O/qbSNRWztTo+pUV4JnFt0FGLl5gGb6NXlxIvR7EjLgD7Gg==}
|
resolution: {integrity: sha512-8ehfUz1m69Vuc16Pm4ukgb3Mg1VT14x4EsG1ag4O/qbSNRWztTo+pUV4JnFt0FGLl5gGb6NXlxIvR7EjLgD7Gg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -7271,7 +7283,7 @@ snapshots:
|
|||||||
|
|
||||||
'@nuxtjs/eslint-config-typescript@12.1.0(eslint@8.57.1)(typescript@5.6.2)':
|
'@nuxtjs/eslint-config-typescript@12.1.0(eslint@8.57.1)(typescript@5.6.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@nuxtjs/eslint-config': 12.0.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
|
'@nuxtjs/eslint-config': 12.0.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2)
|
'@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2)
|
||||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2)
|
'@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.2)
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
@@ -7285,10 +7297,10 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
'@nuxtjs/eslint-config@12.0.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)':
|
'@nuxtjs/eslint-config@12.0.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-config-standard: 17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1)
|
eslint-config-standard: 17.1.0(eslint-plugin-import@2.31.0)(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1)
|
||||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
eslint-plugin-n: 15.7.0(eslint@8.57.1)
|
eslint-plugin-n: 15.7.0(eslint@8.57.1)
|
||||||
eslint-plugin-node: 11.1.0(eslint@8.57.1)
|
eslint-plugin-node: 11.1.0(eslint@8.57.1)
|
||||||
@@ -7953,11 +7965,20 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@vue/shared': 3.4.8
|
'@vue/shared': 3.4.8
|
||||||
|
|
||||||
|
'@vue/reactivity@3.5.12':
|
||||||
|
dependencies:
|
||||||
|
'@vue/shared': 3.5.12
|
||||||
|
|
||||||
'@vue/runtime-core@3.4.8':
|
'@vue/runtime-core@3.4.8':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/reactivity': 3.4.8
|
'@vue/reactivity': 3.4.8
|
||||||
'@vue/shared': 3.4.8
|
'@vue/shared': 3.4.8
|
||||||
|
|
||||||
|
'@vue/runtime-core@3.5.12':
|
||||||
|
dependencies:
|
||||||
|
'@vue/reactivity': 3.5.12
|
||||||
|
'@vue/shared': 3.5.12
|
||||||
|
|
||||||
'@vue/runtime-dom@3.4.8':
|
'@vue/runtime-dom@3.4.8':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vue/runtime-core': 3.4.8
|
'@vue/runtime-core': 3.4.8
|
||||||
@@ -7974,6 +7995,8 @@ snapshots:
|
|||||||
|
|
||||||
'@vue/shared@3.5.11': {}
|
'@vue/shared@3.5.11': {}
|
||||||
|
|
||||||
|
'@vue/shared@3.5.12': {}
|
||||||
|
|
||||||
'@vuepic/vue-datepicker@8.8.1(vue@3.4.8(typescript@5.6.2))':
|
'@vuepic/vue-datepicker@8.8.1(vue@3.4.8(typescript@5.6.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
date-fns: 3.6.0
|
date-fns: 3.6.0
|
||||||
@@ -8981,7 +9004,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
|
|
||||||
eslint-config-standard@17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1))(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1):
|
eslint-config-standard@17.1.0(eslint-plugin-import@2.31.0)(eslint-plugin-n@15.7.0(eslint@8.57.1))(eslint-plugin-promise@6.6.0(eslint@8.57.1))(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
@@ -9002,7 +9025,7 @@ snapshots:
|
|||||||
debug: 4.3.7
|
debug: 4.3.7
|
||||||
enhanced-resolve: 5.17.1
|
enhanced-resolve: 5.17.1
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
|
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
fast-glob: 3.3.2
|
fast-glob: 3.3.2
|
||||||
get-tsconfig: 4.8.1
|
get-tsconfig: 4.8.1
|
||||||
is-bun-module: 1.2.1
|
is-bun-module: 1.2.1
|
||||||
@@ -9015,7 +9038,7 @@ snapshots:
|
|||||||
- eslint-import-resolver-webpack
|
- eslint-import-resolver-webpack
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1):
|
eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7
|
debug: 3.2.7
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
@@ -9049,7 +9072,7 @@ snapshots:
|
|||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 8.57.1
|
eslint: 8.57.1
|
||||||
eslint-import-resolver-node: 0.3.9
|
eslint-import-resolver-node: 0.3.9
|
||||||
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1)
|
eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1)
|
||||||
hasown: 2.0.2
|
hasown: 2.0.2
|
||||||
is-core-module: 2.15.1
|
is-core-module: 2.15.1
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import path from "path";
|
|||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
|
// @ts-ignore
|
||||||
test: {
|
test: {
|
||||||
globalSetup: "./test/setup.ts",
|
globalSetup: "./test/setup.ts",
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user