Enforce required label form fields before preview and create

This commit is contained in:
2026-04-06 17:54:45 +02:00
parent d4205f93b8
commit 96b263c899
+52 -6
View File
@@ -43,9 +43,9 @@ export function renderLabelCreatePage() {
<div class="row g-4">
<div class="col-12 col-xl-7">
<div class="card border-0 shadow-sm">
<div class="card border-0 shadow-sm">
<div class="card-body p-4">
<form class="vstack gap-3" @submit.prevent="create()" autocomplete="off">
<form class="vstack gap-3" @submit.prevent="create()" autocomplete="off" x-ref="labelForm">
<div class="position-relative search-field-with-clear">
<label class="form-label">Search item definitions</label>
<input class="form-control pe-5" type="text" x-model="form.search" @input="onSearchInput()" placeholder="Search by item name" autocomplete="off" />
@@ -98,8 +98,8 @@ export function renderLabelCreatePage() {
</button>
</div>
<div class="col-12 col-md-4">
<label class="form-label">Stock type</label>
<select class="form-select" x-model="form.stockType" x-ref="stockTypeSelect" autocomplete="off">
<label class="form-label">Stock type <span class="text-danger">*</span></label>
<select class="form-select" x-model="form.stockType" x-ref="stockTypeSelect" autocomplete="off" required>
<template x-for="option in stockTypeOptions" :key="option.value">
<option :value="option.value" x-text="option.label"></option>
</template>
@@ -232,6 +232,7 @@ export function renderLabelCreatePage() {
class="form-control pe-5"
type="text"
x-model="locationSearch"
x-ref="locationInput"
@input="onLocationInput()"
@keydown.escape="locationPickerOpen = false"
@click="openLocationPicker()"
@@ -284,8 +285,8 @@ export function renderLabelCreatePage() {
<div class="form-text" x-show="selectedLocationPath" x-text="selectedLocationPath"></div>
</div>
<div class="col-12 col-md-6">
<label class="form-label">Production date</label>
<input class="form-control" type="date" x-model="form.productionDate" />
<label class="form-label">Production date <span class="text-danger">*</span></label>
<input class="form-control" type="date" x-model="form.productionDate" required />
</div>
<div class="col-12 col-md-6 grouped-field-with-clear">
<div class="grouped-field-footer mb-1">
@@ -647,12 +648,14 @@ export function labelCreatePageData(store) {
this.form.locationId = String(location.id);
this.locationSearch = location.name;
this.locationPickerOpen = false;
this.syncLocationValidity();
this.persistDraft();
},
clearLocation() {
this.form.locationId = '';
this.locationSearch = '';
this.locationPickerOpen = true;
this.syncLocationValidity();
this.persistDraft();
},
openLocationPicker() {
@@ -669,6 +672,7 @@ export function labelCreatePageData(store) {
if (this.selectedLocation && this.locationSearch !== this.selectedLocation.name) {
this.form.locationId = '';
}
this.syncLocationValidity();
},
handleLocationFocusOut(event) {
const nextTarget = event.relatedTarget;
@@ -721,6 +725,7 @@ export function labelCreatePageData(store) {
);
this.locationSearch = selected ? selected.name : '';
this.syncLocationValidity();
},
applyItemLocation(locationUuidB64) {
if (!locationUuidB64) {
@@ -737,6 +742,34 @@ export function labelCreatePageData(store) {
this.form.locationId = String(location.id);
this.locationSearch = location.name;
this.syncLocationValidity();
},
syncLocationValidity() {
const input = this.$refs.locationInput;
if (!input) {
return;
}
if (!this.locationSearch.trim()) {
input.setCustomValidity('Please select a storage location.');
return;
}
if (!this.form.locationId) {
input.setCustomValidity('Please choose a location from the list.');
return;
}
input.setCustomValidity('');
},
validateBeforeSubmit() {
this.syncLocationValidity();
const form = this.$refs.labelForm;
if (!form) {
return true;
}
return form.reportValidity();
},
syncExpireDateFromDays() {
if (this.form.expireDays === '') {
@@ -826,6 +859,14 @@ export function labelCreatePageData(store) {
};
},
async preview() {
this.submitError = '';
this.fieldErrors = {};
if (!this.validateBeforeSubmit()) {
this.previewState.error = 'Please fill out the required fields before previewing the label.';
return;
}
await runAsyncState(this.previewState, async () => {
this.successMessage = '';
const result = await previewLabel(store, this.buildPayload());
@@ -840,6 +881,11 @@ export function labelCreatePageData(store) {
this.submitError = '';
this.fieldErrors = {};
if (!this.validateBeforeSubmit()) {
this.submitError = 'Please fill out the required fields before creating the stock entry.';
return;
}
await runAsyncState(this.createState, async () => {
try {
const entry = await createStockEntry(store, this.buildPayload());