This commit is contained in:
2026-06-03 13:58:12 -05:00
commit 2f13b8c590
54 changed files with 5136 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
<template>
<v-navigation-drawer :model-value="modelValue" location="right" temporary width="520" @update:model-value="$emit('update:modelValue', $event)">
<div class="page-band">
<h2 class="text-h6 font-weight-bold">{{ assetForm.id ? 'Edit asset' : 'New asset' }}</h2>
</div>
<div class="pa-4">
<v-select :model-value="selectedTemplateId" :items="templateOptions" label="Template" clearable @update:model-value="$emit('select-template', $event)" />
<div class="form-grid">
<v-text-field v-model="localAsset.asset_id" label="Asset ID" />
<v-select v-model="localAsset.entity_id" :items="entityOptions" label="Entity" />
<v-text-field v-model="localAsset.description" class="full" label="Description" />
<v-select v-model="localAsset.category" :items="categoryItems" label="Category" />
<v-select v-model="localAsset.status" :items="statusItems" label="Status" />
<v-text-field v-model.number="localAsset.acquisition_cost" type="number" label="Acquisition cost" />
<v-text-field v-model.number="localAsset.salvage_value" type="number" label="Salvage value" />
<v-text-field v-model="localAsset.acquired_date" type="date" label="Acquired date" />
<v-text-field v-model="localAsset.in_service_date" type="date" label="In-service date" />
<v-text-field v-model.number="localAsset.useful_life_months" type="number" label="Useful life months" />
<v-select v-model="localAsset.depreciation_method" :items="methodItems" item-title="title" item-value="value" label="Method" />
<v-text-field v-model="localAsset.location" label="Location" />
<v-text-field v-model="localAsset.department" label="Department" />
<v-text-field v-model="localAsset.custodian" label="Custodian" />
<v-text-field v-model="localAsset.vendor" label="Vendor" />
<v-text-field v-model="localAsset.serial_number" label="Serial number" />
<v-text-field v-model="localAsset.invoice_number" label="Invoice number" />
<v-text-field v-model="localAsset.gl_asset_account" label="Asset GL" />
<v-text-field v-model="localAsset.gl_expense_account" label="Expense GL" />
<v-textarea v-model="localAsset.notes" class="full" label="Notes" rows="2" />
</div>
<template v-if="selectedTemplateFields.length">
<v-divider class="my-4" />
<h3 class="section-title mb-3">Template fields</h3>
<div class="form-grid">
<template v-for="field in selectedTemplateFields" :key="field.key">
<v-switch
v-if="field.type === 'bool'"
v-model="localAsset.custom_fields[field.key]"
:label="field.label"
color="primary"
density="compact"
hide-details
/>
<v-text-field
v-else
v-model="localAsset.custom_fields[field.key]"
:label="field.label"
:type="inputTypeForCustomField(field)"
:rules="field.required ? [requiredRule] : []"
/>
</template>
</div>
</template>
<v-alert v-if="drawerError" class="mt-4" density="compact" type="error">{{ drawerError }}</v-alert>
<div class="toolbar-row mt-4">
<v-spacer />
<v-btn variant="text" @click="$emit('update:modelValue', false)">Cancel</v-btn>
<v-btn color="primary" prepend-icon="mdi-content-save" :loading="saving" @click="$emit('save-asset', localAsset)">Save asset</v-btn>
</div>
</div>
</v-navigation-drawer>
</template>
<script>
import { inputTypeForCustomField } from '../utils/assets';
import { clonePlain } from '../utils/clone';
export default {
props: {
assetForm: { type: Object, required: true },
categoryItems: { type: Array, required: true },
drawerError: { type: String, default: '' },
entityOptions: { type: Array, required: true },
methodItems: { type: Array, required: true },
modelValue: { type: Boolean, default: false },
saving: { type: Boolean, default: false },
selectedTemplateFields: { type: Array, required: true },
selectedTemplateId: { type: [Number, String], default: null },
statusItems: { type: Array, required: true },
templateOptions: { type: Array, required: true }
},
emits: ['save-asset', 'select-template', 'update:modelValue'],
data() {
return {
localAsset: clonePlain(this.assetForm),
requiredRule: (value) => value !== null && value !== undefined && value !== '' || 'Required'
};
},
watch: {
assetForm: {
handler(value) {
this.localAsset = clonePlain(value);
},
deep: true
}
},
methods: {
inputTypeForCustomField
}
};
</script>