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"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"purchasePrice": {
|
"purchasePrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"purchaseTime": {
|
"purchaseTime": {
|
||||||
"description": "Purchase",
|
"description": "Purchase",
|
||||||
|
@ -959,7 +960,8 @@ const docTemplate = `{
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"soldPrice": {
|
"soldPrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"soldTime": {
|
"soldTime": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
@ -1025,7 +1027,8 @@ const docTemplate = `{
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"purchasePrice": {
|
"purchasePrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"purchaseTime": {
|
"purchaseTime": {
|
||||||
"description": "Purchase",
|
"description": "Purchase",
|
||||||
|
@ -1042,7 +1045,8 @@ const docTemplate = `{
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"soldPrice": {
|
"soldPrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"soldTime": {
|
"soldTime": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
@ -1105,7 +1109,8 @@ const docTemplate = `{
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"purchasePrice": {
|
"purchasePrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"purchaseTime": {
|
"purchaseTime": {
|
||||||
"description": "Purchase",
|
"description": "Purchase",
|
||||||
|
@ -1122,7 +1127,8 @@ const docTemplate = `{
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"soldPrice": {
|
"soldPrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"soldTime": {
|
"soldTime": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
|
|
@ -934,7 +934,8 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"purchasePrice": {
|
"purchasePrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"purchaseTime": {
|
"purchaseTime": {
|
||||||
"description": "Purchase",
|
"description": "Purchase",
|
||||||
|
@ -951,7 +952,8 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"soldPrice": {
|
"soldPrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"soldTime": {
|
"soldTime": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
@ -1017,7 +1019,8 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"purchasePrice": {
|
"purchasePrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"purchaseTime": {
|
"purchaseTime": {
|
||||||
"description": "Purchase",
|
"description": "Purchase",
|
||||||
|
@ -1034,7 +1037,8 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"soldPrice": {
|
"soldPrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"soldTime": {
|
"soldTime": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
@ -1097,7 +1101,8 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"purchasePrice": {
|
"purchasePrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"purchaseTime": {
|
"purchaseTime": {
|
||||||
"description": "Purchase",
|
"description": "Purchase",
|
||||||
|
@ -1114,7 +1119,8 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"soldPrice": {
|
"soldPrice": {
|
||||||
"type": "number"
|
"type": "string",
|
||||||
|
"example": "0"
|
||||||
},
|
},
|
||||||
"soldTime": {
|
"soldTime": {
|
||||||
"description": "Sold",
|
"description": "Sold",
|
||||||
|
|
|
@ -97,7 +97,8 @@ definitions:
|
||||||
purchaseFrom:
|
purchaseFrom:
|
||||||
type: string
|
type: string
|
||||||
purchasePrice:
|
purchasePrice:
|
||||||
type: number
|
example: "0"
|
||||||
|
type: string
|
||||||
purchaseTime:
|
purchaseTime:
|
||||||
description: Purchase
|
description: Purchase
|
||||||
type: string
|
type: string
|
||||||
|
@ -109,7 +110,8 @@ definitions:
|
||||||
soldNotes:
|
soldNotes:
|
||||||
type: string
|
type: string
|
||||||
soldPrice:
|
soldPrice:
|
||||||
type: number
|
example: "0"
|
||||||
|
type: string
|
||||||
soldTime:
|
soldTime:
|
||||||
description: Sold
|
description: Sold
|
||||||
type: string
|
type: string
|
||||||
|
@ -154,7 +156,8 @@ definitions:
|
||||||
purchaseFrom:
|
purchaseFrom:
|
||||||
type: string
|
type: string
|
||||||
purchasePrice:
|
purchasePrice:
|
||||||
type: number
|
example: "0"
|
||||||
|
type: string
|
||||||
purchaseTime:
|
purchaseTime:
|
||||||
description: Purchase
|
description: Purchase
|
||||||
type: string
|
type: string
|
||||||
|
@ -166,7 +169,8 @@ definitions:
|
||||||
soldNotes:
|
soldNotes:
|
||||||
type: string
|
type: string
|
||||||
soldPrice:
|
soldPrice:
|
||||||
type: number
|
example: "0"
|
||||||
|
type: string
|
||||||
soldTime:
|
soldTime:
|
||||||
description: Sold
|
description: Sold
|
||||||
type: string
|
type: string
|
||||||
|
@ -209,7 +213,8 @@ definitions:
|
||||||
purchaseFrom:
|
purchaseFrom:
|
||||||
type: string
|
type: string
|
||||||
purchasePrice:
|
purchasePrice:
|
||||||
type: number
|
example: "0"
|
||||||
|
type: string
|
||||||
purchaseTime:
|
purchaseTime:
|
||||||
description: Purchase
|
description: Purchase
|
||||||
type: string
|
type: string
|
||||||
|
@ -221,7 +226,8 @@ definitions:
|
||||||
soldNotes:
|
soldNotes:
|
||||||
type: string
|
type: string
|
||||||
soldPrice:
|
soldPrice:
|
||||||
type: number
|
example: "0"
|
||||||
|
type: string
|
||||||
soldTime:
|
soldTime:
|
||||||
description: Sold
|
description: Sold
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -76,8 +76,10 @@ func (e *ItemsRepository) Update(ctx context.Context, data types.ItemUpdate) (*e
|
||||||
SetSoldNotes(data.SoldNotes).
|
SetSoldNotes(data.SoldNotes).
|
||||||
SetNotes(data.Notes).
|
SetNotes(data.Notes).
|
||||||
SetLifetimeWarranty(data.LifetimeWarranty).
|
SetLifetimeWarranty(data.LifetimeWarranty).
|
||||||
|
SetInsured(data.Insured).
|
||||||
SetWarrantyExpires(data.WarrantyExpires).
|
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)
|
currentLabels, err := e.db.Item.Query().Where(item.ID(data.ID)).QueryLabel().All(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -39,6 +39,11 @@ func ToItemSummary(item *ent.Item) *types.ItemSummary {
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
Insured: item.Insured,
|
Insured: item.Insured,
|
||||||
|
|
||||||
|
// Warranty
|
||||||
|
LifetimeWarranty: item.LifetimeWarranty,
|
||||||
|
WarrantyExpires: item.WarrantyExpires,
|
||||||
|
WarrantyDetails: item.WarrantyDetails,
|
||||||
|
|
||||||
// Edges
|
// Edges
|
||||||
Location: location,
|
Location: location,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
|
|
|
@ -39,12 +39,12 @@ type ItemUpdate struct {
|
||||||
// Purchase
|
// Purchase
|
||||||
PurchaseTime time.Time `json:"purchaseTime"`
|
PurchaseTime time.Time `json:"purchaseTime"`
|
||||||
PurchaseFrom string `json:"purchaseFrom"`
|
PurchaseFrom string `json:"purchaseFrom"`
|
||||||
PurchasePrice float64 `json:"purchasePrice"`
|
PurchasePrice float64 `json:"purchasePrice,string"`
|
||||||
|
|
||||||
// Sold
|
// Sold
|
||||||
SoldTime time.Time `json:"soldTime"`
|
SoldTime time.Time `json:"soldTime"`
|
||||||
SoldTo string `json:"soldTo"`
|
SoldTo string `json:"soldTo"`
|
||||||
SoldPrice float64 `json:"soldPrice"`
|
SoldPrice float64 `json:"soldPrice,string"`
|
||||||
SoldNotes string `json:"soldNotes"`
|
SoldNotes string `json:"soldNotes"`
|
||||||
|
|
||||||
// Extras
|
// Extras
|
||||||
|
@ -78,12 +78,12 @@ type ItemSummary struct {
|
||||||
// Purchase
|
// Purchase
|
||||||
PurchaseTime time.Time `json:"purchaseTime"`
|
PurchaseTime time.Time `json:"purchaseTime"`
|
||||||
PurchaseFrom string `json:"purchaseFrom"`
|
PurchaseFrom string `json:"purchaseFrom"`
|
||||||
PurchasePrice float64 `json:"purchasePrice"`
|
PurchasePrice float64 `json:"purchasePrice,string"`
|
||||||
|
|
||||||
// Sold
|
// Sold
|
||||||
SoldTime time.Time `json:"soldTime"`
|
SoldTime time.Time `json:"soldTime"`
|
||||||
SoldTo string `json:"soldTo"`
|
SoldTo string `json:"soldTo"`
|
||||||
SoldPrice float64 `json:"soldPrice"`
|
SoldPrice float64 `json:"soldPrice,string"`
|
||||||
SoldNotes string `json:"soldNotes"`
|
SoldNotes string `json:"soldNotes"`
|
||||||
|
|
||||||
// Extras
|
// 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) {
|
function select(e: MouseEvent, day: Date) {
|
||||||
console.log(day);
|
|
||||||
selected.value = day;
|
selected.value = day;
|
||||||
console.log(selected.value);
|
|
||||||
// @ts-ignore - this is a vue3 bug
|
// @ts-ignore - this is a vue3 bug
|
||||||
e.target.blur();
|
e.target.blur();
|
||||||
resetTime();
|
resetTime();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="!inline" class="form-control">
|
<div v-if="!inline" class="form-control w-full">
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span class="label-text">{{ label }}</span>
|
<span class="label-text">{{ label }}</span>
|
||||||
</label>
|
</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">
|
<label v-if="limit" class="label">
|
||||||
<span class="label-text-alt"></span>
|
<span class="label-text-alt"></span>
|
||||||
<span class="label-text-alt"> {{ valueLen }}/{{ limit }}</span>
|
<span class="label-text-alt"> {{ valueLen }}/{{ limit }}</span>
|
||||||
|
@ -14,10 +14,12 @@
|
||||||
<span class="label-text">{{ label }}</span>
|
<span class="label-text">{{ label }}</span>
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
|
ref="el"
|
||||||
v-model="value"
|
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
|
auto-grow
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
|
auto-height
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</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 value = useVModel(props, "modelValue", emit);
|
||||||
const valueLen = computed(() => {
|
const valueLen = computed(() => {
|
||||||
return value.value ? value.value.length : 0;
|
return value.value ? value.value.length : 0;
|
||||||
|
|
|
@ -20,3 +20,16 @@ export function validDate(dt: Date | string | null | undefined): boolean {
|
||||||
|
|
||||||
return true;
|
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 {
|
dropFields<T>(obj: T, keys: Array<keyof T> = []): T {
|
||||||
const result = { ...obj };
|
const result = { ...obj };
|
||||||
console.log("dropFields", result);
|
|
||||||
[...keys, "createdAt", "updatedAt"].forEach(key => {
|
[...keys, "createdAt", "updatedAt"].forEach(key => {
|
||||||
console.log(key);
|
|
||||||
// @ts-ignore - we are checking for the key above
|
// @ts-ignore - we are checking for the key above
|
||||||
if (hasKey(result, key)) {
|
if (hasKey(result, key)) {
|
||||||
// @ts-ignore - we are guarding against this above
|
// @ts-ignore - we are guarding against this above
|
||||||
delete result[key];
|
delete result[key];
|
||||||
console.log("dropping", key);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log("dropFields", result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,9 @@ export interface ItemOut {
|
||||||
/** Extras */
|
/** Extras */
|
||||||
notes: string;
|
notes: string;
|
||||||
purchaseFrom: string;
|
purchaseFrom: string;
|
||||||
purchasePrice: number;
|
|
||||||
|
/** @example 0 */
|
||||||
|
purchasePrice: string;
|
||||||
|
|
||||||
/** Purchase */
|
/** Purchase */
|
||||||
purchaseTime: Date;
|
purchaseTime: Date;
|
||||||
|
@ -79,7 +81,9 @@ export interface ItemOut {
|
||||||
/** Identifications */
|
/** Identifications */
|
||||||
serialNumber: string;
|
serialNumber: string;
|
||||||
soldNotes: string;
|
soldNotes: string;
|
||||||
soldPrice: number;
|
|
||||||
|
/** @example 0 */
|
||||||
|
soldPrice: string;
|
||||||
|
|
||||||
/** Sold */
|
/** Sold */
|
||||||
soldTime: Date;
|
soldTime: Date;
|
||||||
|
@ -108,7 +112,9 @@ export interface ItemSummary {
|
||||||
/** Extras */
|
/** Extras */
|
||||||
notes: string;
|
notes: string;
|
||||||
purchaseFrom: string;
|
purchaseFrom: string;
|
||||||
purchasePrice: number;
|
|
||||||
|
/** @example 0 */
|
||||||
|
purchasePrice: string;
|
||||||
|
|
||||||
/** Purchase */
|
/** Purchase */
|
||||||
purchaseTime: Date;
|
purchaseTime: Date;
|
||||||
|
@ -117,7 +123,9 @@ export interface ItemSummary {
|
||||||
/** Identifications */
|
/** Identifications */
|
||||||
serialNumber: string;
|
serialNumber: string;
|
||||||
soldNotes: string;
|
soldNotes: string;
|
||||||
soldPrice: number;
|
|
||||||
|
/** @example 0 */
|
||||||
|
soldPrice: string;
|
||||||
|
|
||||||
/** Sold */
|
/** Sold */
|
||||||
soldTime: Date;
|
soldTime: Date;
|
||||||
|
@ -145,7 +153,9 @@ export interface ItemUpdate {
|
||||||
/** Extras */
|
/** Extras */
|
||||||
notes: string;
|
notes: string;
|
||||||
purchaseFrom: string;
|
purchaseFrom: string;
|
||||||
purchasePrice: number;
|
|
||||||
|
/** @example 0 */
|
||||||
|
purchasePrice: string;
|
||||||
|
|
||||||
/** Purchase */
|
/** Purchase */
|
||||||
purchaseTime: Date;
|
purchaseTime: Date;
|
||||||
|
@ -154,7 +164,9 @@ export interface ItemUpdate {
|
||||||
/** Identifications */
|
/** Identifications */
|
||||||
serialNumber: string;
|
serialNumber: string;
|
||||||
soldNotes: string;
|
soldNotes: string;
|
||||||
soldPrice: number;
|
|
||||||
|
/** @example 0 */
|
||||||
|
soldPrice: string;
|
||||||
|
|
||||||
/** Sold */
|
/** Sold */
|
||||||
soldTime: Date;
|
soldTime: Date;
|
||||||
|
|
|
@ -55,7 +55,6 @@
|
||||||
|
|
||||||
function setFile(e: Event & { target: HTMLInputElement }) {
|
function setFile(e: Event & { target: HTMLInputElement }) {
|
||||||
importCsv.value = e.target.files[0];
|
importCsv.value = e.target.files[0];
|
||||||
console.log("importCsv.value", importCsv.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const toast = useNotifier();
|
const toast = useNotifier();
|
||||||
|
|
|
@ -35,11 +35,6 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
originalItem.value = {
|
|
||||||
name: data.name,
|
|
||||||
quantity: data.quantity,
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -50,8 +45,6 @@
|
||||||
labelIds: item.value.labels.map(l => l.id),
|
labelIds: item.value.labels.map(l => l.id),
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(payload);
|
|
||||||
|
|
||||||
const { error } = await api.items.update(itemId.value, payload);
|
const { error } = await api.items.update(itemId.value, payload);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -64,7 +57,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
type FormField = {
|
type FormField = {
|
||||||
type: "text" | "textarea" | "select" | "date" | "label" | "location";
|
type: "text" | "textarea" | "select" | "date" | "label" | "location" | "number" | "checkbox";
|
||||||
label: string;
|
label: string;
|
||||||
ref: string;
|
ref: string;
|
||||||
};
|
};
|
||||||
|
@ -75,6 +68,11 @@
|
||||||
label: "Name",
|
label: "Name",
|
||||||
ref: "name",
|
ref: "name",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "number",
|
||||||
|
label: "Quantity",
|
||||||
|
ref: "quantity",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "textarea",
|
type: "textarea",
|
||||||
label: "Description",
|
label: "Description",
|
||||||
|
@ -100,6 +98,11 @@
|
||||||
label: "Notes",
|
label: "Notes",
|
||||||
ref: "notes",
|
ref: "notes",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "checkbox",
|
||||||
|
label: "Insured",
|
||||||
|
ref: "insured",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const purchaseFields: FormField[] = [
|
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 = [
|
const soldFields = [
|
||||||
{
|
{
|
||||||
type: "text",
|
type: "text",
|
||||||
|
@ -147,13 +168,10 @@
|
||||||
<BaseSectionHeader v-if="item" class="p-5">
|
<BaseSectionHeader v-if="item" class="p-5">
|
||||||
<Icon name="mdi-package-variant" class="-mt-1 mr-2 text-gray-600" />
|
<Icon name="mdi-package-variant" class="-mt-1 mr-2 text-gray-600" />
|
||||||
<span class="text-gray-600">
|
<span class="text-gray-600">
|
||||||
{{ originalItem.name }}
|
{{ item.name }}
|
||||||
</span>
|
</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>
|
<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="modal-action mt-3">
|
||||||
<div class="mr-auto tooltip" data-tip="Hide the cruft! ">
|
<div class="mr-auto tooltip" data-tip="Hide the cruft! ">
|
||||||
<label class="label cursor-pointer mr-auto">
|
<label class="label cursor-pointer mr-auto">
|
||||||
|
@ -170,14 +188,14 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</BaseSectionHeader>
|
</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 />
|
<FormSelect v-model="item.location" label="Location" :items="locations ?? []" select-first />
|
||||||
<FormMultiselect v-model="item.labels" label="Labels" :items="labels ?? []" />
|
<FormMultiselect v-model="item.labels" label="Labels" :items="labels ?? []" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="border-t border-gray-300 sm:p-0">
|
<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 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 />
|
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
|
||||||
<FormTextField
|
<FormTextField
|
||||||
v-else-if="field.type === 'text'"
|
v-else-if="field.type === 'text'"
|
||||||
|
@ -185,12 +203,25 @@
|
||||||
:label="field.label"
|
:label="field.label"
|
||||||
inline
|
inline
|
||||||
/>
|
/>
|
||||||
|
<FormTextField
|
||||||
|
v-else-if="field.type === 'number'"
|
||||||
|
v-model.number="item[field.ref]"
|
||||||
|
type="number"
|
||||||
|
:label="field.label"
|
||||||
|
inline
|
||||||
|
/>
|
||||||
<FormDatePicker
|
<FormDatePicker
|
||||||
v-else-if="field.type === 'date'"
|
v-else-if="field.type === 'date'"
|
||||||
v-model="item[field.ref]"
|
v-model="item[field.ref]"
|
||||||
:label="field.label"
|
:label="field.label"
|
||||||
inline
|
inline
|
||||||
/>
|
/>
|
||||||
|
<FormCheckbox
|
||||||
|
v-else-if="field.type === 'checkbox'"
|
||||||
|
v-model="item[field.ref]"
|
||||||
|
:label="field.label"
|
||||||
|
inline
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -206,7 +237,7 @@
|
||||||
:key="field.ref"
|
:key="field.ref"
|
||||||
class="sm:divide-y sm:divide-gray-300 grid grid-cols-1"
|
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 />
|
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
|
||||||
<FormTextField
|
<FormTextField
|
||||||
v-else-if="field.type === 'text'"
|
v-else-if="field.type === 'text'"
|
||||||
|
@ -214,12 +245,67 @@
|
||||||
:label="field.label"
|
:label="field.label"
|
||||||
inline
|
inline
|
||||||
/>
|
/>
|
||||||
|
<FormTextField
|
||||||
|
v-else-if="field.type === 'number'"
|
||||||
|
v-model.number="item[field.ref]"
|
||||||
|
type="number"
|
||||||
|
:label="field.label"
|
||||||
|
inline
|
||||||
|
/>
|
||||||
<FormDatePicker
|
<FormDatePicker
|
||||||
v-else-if="field.type === 'date'"
|
v-else-if="field.type === 'date'"
|
||||||
v-model="item[field.ref]"
|
v-model="item[field.ref]"
|
||||||
:label="field.label"
|
:label="field.label"
|
||||||
inline
|
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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -231,7 +317,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="border-t border-gray-300 sm:p-0">
|
<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 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 />
|
<FormTextArea v-if="field.type === 'textarea'" v-model="item[field.ref]" :label="field.label" inline />
|
||||||
<FormTextField
|
<FormTextField
|
||||||
v-else-if="field.type === 'text'"
|
v-else-if="field.type === 'text'"
|
||||||
|
@ -239,12 +325,25 @@
|
||||||
:label="field.label"
|
:label="field.label"
|
||||||
inline
|
inline
|
||||||
/>
|
/>
|
||||||
|
<FormTextField
|
||||||
|
v-else-if="field.type === 'number'"
|
||||||
|
v-model.number="item[field.ref]"
|
||||||
|
type="number"
|
||||||
|
:label="field.label"
|
||||||
|
inline
|
||||||
|
/>
|
||||||
<FormDatePicker
|
<FormDatePicker
|
||||||
v-else-if="field.type === 'date'"
|
v-else-if="field.type === 'date'"
|
||||||
v-model="item[field.ref]"
|
v-model="item[field.ref]"
|
||||||
:label="field.label"
|
:label="field.label"
|
||||||
inline
|
inline
|
||||||
/>
|
/>
|
||||||
|
<FormCheckbox
|
||||||
|
v-else-if="field.type === 'checkbox'"
|
||||||
|
v-model="item[field.ref]"
|
||||||
|
:label="field.label"
|
||||||
|
inline
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
const itemId = computed<string>(() => route.params.id as string);
|
const itemId = computed<string>(() => route.params.id as string);
|
||||||
const preferences = useViewPreferences();
|
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);
|
const { data, error } = await api.items.get(itemId.value);
|
||||||
if (error) {
|
if (error) {
|
||||||
toast.error("Failed to load item");
|
toast.error("Failed to load item");
|
||||||
|
@ -20,6 +20,11 @@
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Trigger Refresh on navigate
|
||||||
|
onMounted(() => {
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
|
||||||
const itemSummary = computed(() => {
|
const itemSummary = computed(() => {
|
||||||
return {
|
return {
|
||||||
Description: item.value?.description || "",
|
Description: item.value?.description || "",
|
||||||
|
@ -63,7 +68,7 @@
|
||||||
const purchaseDetails = computed(() => {
|
const purchaseDetails = computed(() => {
|
||||||
return {
|
return {
|
||||||
"Purchased From": item.value?.purchaseFrom || "",
|
"Purchased From": item.value?.purchaseFrom || "",
|
||||||
"Purchased Price": item.value?.purchasePrice || "",
|
"Purchased Price": item.value?.purchasePrice ? fmtCurrency(item.value.purchasePrice) : "",
|
||||||
"Purchased At": item.value?.purchaseTime || "",
|
"Purchased At": item.value?.purchaseTime || "",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -79,7 +84,7 @@
|
||||||
const soldDetails = computed(() => {
|
const soldDetails = computed(() => {
|
||||||
return {
|
return {
|
||||||
"Sold To": item.value?.soldTo || "",
|
"Sold To": item.value?.soldTo || "",
|
||||||
"Sold Price": item.value?.soldPrice || "",
|
"Sold Price": item.value?.soldPrice ? fmtCurrency(item.value.soldPrice) : "",
|
||||||
"Sold At": item.value?.soldTime || "",
|
"Sold At": item.value?.soldTime || "",
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -117,7 +122,9 @@
|
||||||
<span class="text-gray-600">
|
<span class="text-gray-600">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</span>
|
</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>
|
<template #after>
|
||||||
<div v-if="item.labels && item.labels.length > 0" class="flex flex-wrap gap-3 mt-3">
|
<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" />
|
<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