mirror of
https://github.com/hay-kot/homebox.git
synced 2025-08-03 16:20:27 +00:00
finish types for basic items editor
This commit is contained in:
parent
f432330e50
commit
fb0898aa71
15 changed files with 259 additions and 60 deletions
|
@ -942,7 +942,8 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
|
@ -959,7 +960,8 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
|
@ -1025,7 +1027,8 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
|
@ -1042,7 +1045,8 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
|
@ -1105,7 +1109,8 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
|
@ -1122,7 +1127,8 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
|
|
|
@ -934,7 +934,8 @@
|
|||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
|
@ -951,7 +952,8 @@
|
|||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
|
@ -1017,7 +1019,8 @@
|
|||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
|
@ -1034,7 +1037,8 @@
|
|||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
|
@ -1097,7 +1101,8 @@
|
|||
"type": "string"
|
||||
},
|
||||
"purchasePrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"purchaseTime": {
|
||||
"description": "Purchase",
|
||||
|
@ -1114,7 +1119,8 @@
|
|||
"type": "string"
|
||||
},
|
||||
"soldPrice": {
|
||||
"type": "number"
|
||||
"type": "string",
|
||||
"example": "0"
|
||||
},
|
||||
"soldTime": {
|
||||
"description": "Sold",
|
||||
|
|
|
@ -97,7 +97,8 @@ definitions:
|
|||
purchaseFrom:
|
||||
type: string
|
||||
purchasePrice:
|
||||
type: number
|
||||
example: "0"
|
||||
type: string
|
||||
purchaseTime:
|
||||
description: Purchase
|
||||
type: string
|
||||
|
@ -109,7 +110,8 @@ definitions:
|
|||
soldNotes:
|
||||
type: string
|
||||
soldPrice:
|
||||
type: number
|
||||
example: "0"
|
||||
type: string
|
||||
soldTime:
|
||||
description: Sold
|
||||
type: string
|
||||
|
@ -154,7 +156,8 @@ definitions:
|
|||
purchaseFrom:
|
||||
type: string
|
||||
purchasePrice:
|
||||
type: number
|
||||
example: "0"
|
||||
type: string
|
||||
purchaseTime:
|
||||
description: Purchase
|
||||
type: string
|
||||
|
@ -166,7 +169,8 @@ definitions:
|
|||
soldNotes:
|
||||
type: string
|
||||
soldPrice:
|
||||
type: number
|
||||
example: "0"
|
||||
type: string
|
||||
soldTime:
|
||||
description: Sold
|
||||
type: string
|
||||
|
@ -209,7 +213,8 @@ definitions:
|
|||
purchaseFrom:
|
||||
type: string
|
||||
purchasePrice:
|
||||
type: number
|
||||
example: "0"
|
||||
type: string
|
||||
purchaseTime:
|
||||
description: Purchase
|
||||
type: string
|
||||
|
@ -221,7 +226,8 @@ definitions:
|
|||
soldNotes:
|
||||
type: string
|
||||
soldPrice:
|
||||
type: number
|
||||
example: "0"
|
||||
type: string
|
||||
soldTime:
|
||||
description: Sold
|
||||
type: string
|
||||
|
|
|
@ -76,8 +76,10 @@ func (e *ItemsRepository) Update(ctx context.Context, data types.ItemUpdate) (*e
|
|||
SetSoldNotes(data.SoldNotes).
|
||||
SetNotes(data.Notes).
|
||||
SetLifetimeWarranty(data.LifetimeWarranty).
|
||||
SetInsured(data.Insured).
|
||||
SetWarrantyExpires(data.WarrantyExpires).
|
||||
SetWarrantyDetails(data.WarrantyDetails)
|
||||
SetWarrantyDetails(data.WarrantyDetails).
|
||||
SetQuantity(data.Quantity)
|
||||
|
||||
currentLabels, err := e.db.Item.Query().Where(item.ID(data.ID)).QueryLabel().All(ctx)
|
||||
if err != nil {
|
||||
|
|
|
@ -39,6 +39,11 @@ func ToItemSummary(item *ent.Item) *types.ItemSummary {
|
|||
Quantity: item.Quantity,
|
||||
Insured: item.Insured,
|
||||
|
||||
// Warranty
|
||||
LifetimeWarranty: item.LifetimeWarranty,
|
||||
WarrantyExpires: item.WarrantyExpires,
|
||||
WarrantyDetails: item.WarrantyDetails,
|
||||
|
||||
// Edges
|
||||
Location: location,
|
||||
Labels: labels,
|
||||
|
|
|
@ -39,12 +39,12 @@ type ItemUpdate struct {
|
|||
// Purchase
|
||||
PurchaseTime time.Time `json:"purchaseTime"`
|
||||
PurchaseFrom string `json:"purchaseFrom"`
|
||||
PurchasePrice float64 `json:"purchasePrice"`
|
||||
PurchasePrice float64 `json:"purchasePrice,string"`
|
||||
|
||||
// Sold
|
||||
SoldTime time.Time `json:"soldTime"`
|
||||
SoldTo string `json:"soldTo"`
|
||||
SoldPrice float64 `json:"soldPrice"`
|
||||
SoldPrice float64 `json:"soldPrice,string"`
|
||||
SoldNotes string `json:"soldNotes"`
|
||||
|
||||
// Extras
|
||||
|
@ -78,12 +78,12 @@ type ItemSummary struct {
|
|||
// Purchase
|
||||
PurchaseTime time.Time `json:"purchaseTime"`
|
||||
PurchaseFrom string `json:"purchaseFrom"`
|
||||
PurchasePrice float64 `json:"purchasePrice"`
|
||||
PurchasePrice float64 `json:"purchasePrice,string"`
|
||||
|
||||
// Sold
|
||||
SoldTime time.Time `json:"soldTime"`
|
||||
SoldTo string `json:"soldTo"`
|
||||
SoldPrice float64 `json:"soldPrice"`
|
||||
SoldPrice float64 `json:"soldPrice,string"`
|
||||
SoldNotes string `json:"soldNotes"`
|
||||
|
||||
// Extras
|
||||
|
|
35
frontend/components/Form/Checkbox.vue
Normal file
35
frontend/components/Form/Checkbox.vue
Normal file
|
@ -0,0 +1,35 @@
|
|||
<template>
|
||||
<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" />
|
||||
</label>
|
||||
</div>
|
||||
<div v-else class="label cursor-pointer sm:grid sm:grid-cols-4 sm:items-start sm:gap-4">
|
||||
<label>
|
||||
<span class="label-text">
|
||||
{{ label }}
|
||||
</span>
|
||||
</label>
|
||||
<input v-model="value" type="checkbox" class="checkbox" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
|
||||
const value = useVModel(props, "modelValue");
|
||||
</script>
|
|
@ -96,9 +96,7 @@
|
|||
});
|
||||
|
||||
function select(e: MouseEvent, day: Date) {
|
||||
console.log(day);
|
||||
selected.value = day;
|
||||
console.log(selected.value);
|
||||
// @ts-ignore - this is a vue3 bug
|
||||
e.target.blur();
|
||||
resetTime();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div v-if="!inline" class="form-control">
|
||||
<div v-if="!inline" class="form-control w-full">
|
||||
<label class="label">
|
||||
<span class="label-text">{{ label }}</span>
|
||||
</label>
|
||||
<textarea v-model="value" class="textarea textarea-bordered h-24" :placeholder="placeholder" />
|
||||
<textarea ref="el" v-model="value" class="textarea w-full textarea-bordered h-28" :placeholder="placeholder" />
|
||||
<label v-if="limit" class="label">
|
||||
<span class="label-text-alt"></span>
|
||||
<span class="label-text-alt"> {{ valueLen }}/{{ limit }}</span>
|
||||
|
@ -14,10 +14,12 @@
|
|||
<span class="label-text">{{ label }}</span>
|
||||
</label>
|
||||
<textarea
|
||||
ref="el"
|
||||
v-model="value"
|
||||
class="textarea textarea-bordered col-span-3 mt-3 h-24"
|
||||
class="textarea textarea-bordered w-full col-span-3 mt-3 h-28"
|
||||
auto-grow
|
||||
:placeholder="placeholder"
|
||||
auto-height
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -51,6 +53,19 @@
|
|||
},
|
||||
});
|
||||
|
||||
const el = ref();
|
||||
function setHeight() {
|
||||
el.value.style.height = "auto";
|
||||
el.value.style.height = el.value.scrollHeight + 5 + "px";
|
||||
}
|
||||
|
||||
onUpdated(() => {
|
||||
console.log("updated");
|
||||
if (props.inline) {
|
||||
setHeight();
|
||||
}
|
||||
});
|
||||
|
||||
const value = useVModel(props, "modelValue", emit);
|
||||
const valueLen = computed(() => {
|
||||
return value.value ? value.value.length : 0;
|
||||
|
|
|
@ -20,3 +20,16 @@ export function validDate(dt: Date | string | null | undefined): boolean {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function fmtCurrency(value: number | string, currency = "USD", locale = "en-Us"): string {
|
||||
if (typeof value === "string") {
|
||||
value = parseFloat(value);
|
||||
}
|
||||
|
||||
const formatter = new Intl.NumberFormat(locale, {
|
||||
style: "currency",
|
||||
currency,
|
||||
minimumFractionDigits: 2,
|
||||
});
|
||||
return formatter.format(value);
|
||||
}
|
||||
|
|
|
@ -45,17 +45,13 @@ export class BaseAPI {
|
|||
*/
|
||||
dropFields<T>(obj: T, keys: Array<keyof T> = []): T {
|
||||
const result = { ...obj };
|
||||
console.log("dropFields", result);
|
||||
[...keys, "createdAt", "updatedAt"].forEach(key => {
|
||||
console.log(key);
|
||||
// @ts-ignore - we are checking for the key above
|
||||
if (hasKey(result, key)) {
|
||||
// @ts-ignore - we are guarding against this above
|
||||
delete result[key];
|
||||
console.log("dropping", key);
|
||||
}
|
||||
});
|
||||
console.log("dropFields", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,9 @@ export interface ItemOut {
|
|||
/** Extras */
|
||||
notes: string;
|
||||
purchaseFrom: string;
|
||||
purchasePrice: number;
|
||||
|
||||
/** @example 0 */
|
||||
purchasePrice: string;
|
||||
|
||||
/** Purchase */
|
||||
purchaseTime: Date;
|
||||
|
@ -79,7 +81,9 @@ export interface ItemOut {
|
|||
/** Identifications */
|
||||
serialNumber: string;
|
||||
soldNotes: string;
|
||||
soldPrice: number;
|
||||
|
||||
/** @example 0 */
|
||||
soldPrice: string;
|
||||
|
||||
/** Sold */
|
||||
soldTime: Date;
|
||||
|
@ -108,7 +112,9 @@ export interface ItemSummary {
|
|||
/** Extras */
|
||||
notes: string;
|
||||
purchaseFrom: string;
|
||||
purchasePrice: number;
|
||||
|
||||
/** @example 0 */
|
||||
purchasePrice: string;
|
||||
|
||||
/** Purchase */
|
||||
purchaseTime: Date;
|
||||
|
@ -117,7 +123,9 @@ export interface ItemSummary {
|
|||
/** Identifications */
|
||||
serialNumber: string;
|
||||
soldNotes: string;
|
||||
soldPrice: number;
|
||||
|
||||
/** @example 0 */
|
||||
soldPrice: string;
|
||||
|
||||
/** Sold */
|
||||
soldTime: Date;
|
||||
|
@ -145,7 +153,9 @@ export interface ItemUpdate {
|
|||
/** Extras */
|
||||
notes: string;
|
||||
purchaseFrom: string;
|
||||
purchasePrice: number;
|
||||
|
||||
/** @example 0 */
|
||||
purchasePrice: string;
|
||||
|
||||
/** Purchase */
|
||||
purchaseTime: Date;
|
||||
|
@ -154,7 +164,9 @@ export interface ItemUpdate {
|
|||
/** Identifications */
|
||||
serialNumber: string;
|
||||
soldNotes: string;
|
||||
soldPrice: number;
|
||||
|
||||
/** @example 0 */
|
||||
soldPrice: string;
|
||||
|
||||
/** Sold */
|
||||
soldTime: Date;
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
|
||||
function setFile(e: Event & { target: HTMLInputElement }) {
|
||||
importCsv.value = e.target.files[0];
|
||||
console.log("importCsv.value", importCsv.value);
|
||||
}
|
||||
|
||||
const toast = useNotifier();
|
||||
|
|
|
@ -35,11 +35,6 @@
|
|||
return;
|
||||
}
|
||||
|
||||
originalItem.value = {
|
||||
name: data.name,
|
||||
quantity: data.quantity,
|
||||
};
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
|
@ -50,8 +45,6 @@
|
|||
labelIds: item.value.labels.map(l => l.id),
|
||||
};
|
||||
|
||||
console.log(payload);
|
||||
|
||||
const { error } = await api.items.update(itemId.value, payload);
|
||||
|
||||
if (error) {
|
||||
|
@ -64,7 +57,7 @@
|
|||
}
|
||||
|
||||
type FormField = {
|
||||
type: "text" | "textarea" | "select" | "date" | "label" | "location";
|
||||
type: "text" | "textarea" | "select" | "date" | "label" | "location" | "number" | "checkbox";
|
||||
label: string;
|
||||
ref: string;
|
||||
};
|
||||
|
@ -75,6 +68,11 @@
|
|||
label: "Name",
|
||||
ref: "name",
|
||||
},
|
||||
{
|
||||
type: "number",
|
||||
label: "Quantity",
|
||||
ref: "quantity",
|
||||
},
|
||||
{
|
||||
type: "textarea",
|
||||
label: "Description",
|
||||
|
@ -100,6 +98,11 @@
|
|||
label: "Notes",
|
||||
ref: "notes",
|
||||
},
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Insured",
|
||||
ref: "insured",
|
||||
},
|
||||
];
|
||||
|
||||
const purchaseFields: FormField[] = [
|
||||
|
@ -120,6 +123,24 @@
|
|||
},
|
||||
];
|
||||
|
||||
const warrantyFields: FormField[] = [
|
||||
{
|
||||
type: "checkbox",
|
||||
label: "Lifetime Warranty",
|
||||
ref: "lifetimeWarranty",
|
||||
},
|
||||
{
|
||||
type: "date",
|
||||
label: "Warranty Expires",
|
||||
ref: "warrantyExpires",
|
||||
},
|
||||
{
|
||||
type: "textarea",
|
||||
label: "Warranty Notes",
|
||||
ref: "warrantyDetails",
|
||||
},
|
||||
];
|
||||
|
||||
const soldFields = [
|
||||
{
|
||||
type: "text",
|
||||
|
@ -147,13 +168,10 @@
|
|||
<BaseSectionHeader v-if="item" class="p-5">
|
||||
<Icon name="mdi-package-variant" class="-mt-1 mr-2 text-gray-600" />
|
||||
<span class="text-gray-600">
|
||||
{{ originalItem.name }}
|
||||
{{ item.name }}
|
||||
</span>
|
||||
<p class="text-sm text-gray-600 font-bold pb-0 mb-0">Quantity {{ originalItem.quantity }}</p>
|
||||
<p class="text-sm text-gray-600 font-bold pb-0 mb-0">Quantity {{ item.quantity }}</p>
|
||||
<template #after>
|
||||
<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>
|
||||
<div class="modal-action mt-3">
|
||||
<div class="mr-auto tooltip" data-tip="Hide the cruft! ">
|
||||
<label class="label cursor-pointer mr-auto">
|
||||
|
@ -170,14 +188,14 @@
|
|||
</div>
|
||||
</template>
|
||||
</BaseSectionHeader>
|
||||
<div class="px-5 mb-6">
|
||||
<div class="px-5 mb-6 grid md:grid-cols-2 gap-4">
|
||||
<FormSelect v-model="item.location" label="Location" :items="locations ?? []" select-first />
|
||||
<FormMultiselect v-model="item.labels" label="Labels" :items="labels ?? []" />
|
||||
</div>
|
||||
|
||||
<div class="border-t border-gray-300 sm:p-0">
|
||||
<div v-for="field in mainFields" :key="field.ref" class="sm:divide-y sm:divide-gray-300 grid grid-cols-1">
|
||||
<div class="pt-2 pb-4 sm:px-6 border-b border-gray-300">
|
||||
<div class="pt-2 px-4 pb-4 sm:px-6 border-b border-gray-300">
|
||||
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'text'"
|
||||
|
@ -185,12 +203,25 @@
|
|||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model.number="item[field.ref]"
|
||||
type="number"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormDatePicker
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormCheckbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -206,7 +237,7 @@
|
|||
:key="field.ref"
|
||||
class="sm:divide-y sm:divide-gray-300 grid grid-cols-1"
|
||||
>
|
||||
<div class="pt-2 pb-4 sm:px-6 border-b border-gray-300">
|
||||
<div class="pt-2 px-4 pb-4 sm:px-6 border-b border-gray-300">
|
||||
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'text'"
|
||||
|
@ -214,12 +245,67 @@
|
|||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model.number="item[field.ref]"
|
||||
type="number"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormDatePicker
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormCheckbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!preferences.editorSimpleView" class="overflow-visible card bg-base-100 shadow-xl sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h3 class="text-lg font-medium leading-6">Warranty Details</h3>
|
||||
</div>
|
||||
<div class="border-t border-gray-300 sm:p-0">
|
||||
<div
|
||||
v-for="field in warrantyFields"
|
||||
:key="field.ref"
|
||||
class="sm:divide-y sm:divide-gray-300 grid grid-cols-1"
|
||||
>
|
||||
<div class="pt-2 px-4 pb-4 sm:px-6 border-b border-gray-300">
|
||||
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'text'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model.number="item[field.ref]"
|
||||
type="number"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormDatePicker
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormCheckbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -231,7 +317,7 @@
|
|||
</div>
|
||||
<div class="border-t border-gray-300 sm:p-0">
|
||||
<div v-for="field in soldFields" :key="field.ref" class="sm:divide-y sm:divide-gray-300 grid grid-cols-1">
|
||||
<div class="pt-2 pb-4 sm:px-6 border-b border-gray-300">
|
||||
<div class="pt-2 pb-4 px-4 sm:px-6 border-b border-gray-300">
|
||||
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'text'"
|
||||
|
@ -239,12 +325,25 @@
|
|||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormTextField
|
||||
v-else-if="field.type === 'number'"
|
||||
v-model.number="item[field.ref]"
|
||||
type="number"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormDatePicker
|
||||
v-else-if="field.type === 'date'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
<FormCheckbox
|
||||
v-else-if="field.type === 'checkbox'"
|
||||
v-model="item[field.ref]"
|
||||
:label="field.label"
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
const itemId = computed<string>(() => route.params.id as string);
|
||||
const preferences = useViewPreferences();
|
||||
|
||||
const { data: item } = useAsyncData(async () => {
|
||||
const { data: item, refresh } = useAsyncData(itemId.value, async () => {
|
||||
const { data, error } = await api.items.get(itemId.value);
|
||||
if (error) {
|
||||
toast.error("Failed to load item");
|
||||
|
@ -20,6 +20,11 @@
|
|||
return data;
|
||||
});
|
||||
|
||||
// Trigger Refresh on navigate
|
||||
onMounted(() => {
|
||||
refresh();
|
||||
});
|
||||
|
||||
const itemSummary = computed(() => {
|
||||
return {
|
||||
Description: item.value?.description || "",
|
||||
|
@ -63,7 +68,7 @@
|
|||
const purchaseDetails = computed(() => {
|
||||
return {
|
||||
"Purchased From": item.value?.purchaseFrom || "",
|
||||
"Purchased Price": item.value?.purchasePrice || "",
|
||||
"Purchased Price": item.value?.purchasePrice ? fmtCurrency(item.value.purchasePrice) : "",
|
||||
"Purchased At": item.value?.purchaseTime || "",
|
||||
};
|
||||
});
|
||||
|
@ -79,7 +84,7 @@
|
|||
const soldDetails = computed(() => {
|
||||
return {
|
||||
"Sold To": item.value?.soldTo || "",
|
||||
"Sold Price": item.value?.soldPrice || "",
|
||||
"Sold Price": item.value?.soldPrice ? fmtCurrency(item.value.soldPrice) : "",
|
||||
"Sold At": item.value?.soldTime || "",
|
||||
};
|
||||
});
|
||||
|
@ -117,7 +122,9 @@
|
|||
<span class="text-gray-600">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
<p class="text-sm text-gray-600 font-bold pb-0 mb-0">Quantity {{ item.quantity }}</p>
|
||||
<p class="text-sm text-gray-600 font-bold pb-0 mb-0">
|
||||
{{ item.location.name }} - Quantity {{ item.quantity }}
|
||||
</p>
|
||||
<template #after>
|
||||
<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" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue