Add label printing functionality and error handling in stock and label flows
This commit is contained in:
@@ -4,7 +4,11 @@ import {
|
||||
searchItemDefinitions,
|
||||
} from '../../api/stock.js';
|
||||
import { fetchLocations } from '../../api/locations.js';
|
||||
import { previewLabel } from '../../api/labels.js';
|
||||
import {
|
||||
formatPrintErrorMessage,
|
||||
previewLabel,
|
||||
printItemLabel,
|
||||
} from '../../api/labels.js';
|
||||
import { STORAGE_KEYS } from '../../app/config.js';
|
||||
import { debounce, normalizeValidationError } from '../shared/form-utils.js';
|
||||
import { loadStoredValue, saveStoredValue } from '../shared/storage.js';
|
||||
@@ -404,7 +408,7 @@ export function renderLabelCreatePage() {
|
||||
<div class="alert alert-success mb-0" x-text="successMessage"></div>
|
||||
</template>
|
||||
|
||||
<template x-if="upsertPreview && !upsertPreview.error">
|
||||
<template x-if="upsertPreview?.mode === 'preview' && !upsertPreview.error">
|
||||
<div class="alert alert-info mb-0 py-2" x-text="upsertPreviewSummary()"></div>
|
||||
</template>
|
||||
|
||||
@@ -412,18 +416,28 @@ export function renderLabelCreatePage() {
|
||||
<div class="alert alert-warning mb-0 py-2" x-text="upsertPreview.error"></div>
|
||||
</template>
|
||||
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<button class="btn btn-outline-primary" type="button" @click="preview()" :disabled="previewState.isLoading">
|
||||
<template x-if="printIssue">
|
||||
<div class="alert alert-warning mb-0 py-2" x-text="printIssue"></div>
|
||||
</template>
|
||||
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 label-actions-row">
|
||||
<div class="d-flex flex-wrap gap-2 label-actions-primary">
|
||||
<button class="btn btn-outline-primary label-action-btn" type="button" @click="preview()" :disabled="previewState.isLoading">
|
||||
<span x-show="!previewState.isLoading">Preview label</span>
|
||||
<span x-show="previewState.isLoading">Rendering preview...</span>
|
||||
</button>
|
||||
<button class="btn btn-primary" type="submit" :disabled="createState.isLoading">
|
||||
<span x-show="!createState.isLoading">Save stock entry</span>
|
||||
<span x-show="createState.isLoading">Saving...</span>
|
||||
</button>
|
||||
<div class="input-group input-group-label-submit">
|
||||
<span class="input-group-text">
|
||||
<input class="form-check-input mt-0 me-2" type="checkbox" x-model="printLabelOnSave" aria-label="Print label on save" />
|
||||
Print
|
||||
</span>
|
||||
<button class="btn btn-primary label-action-btn" type="submit" :disabled="createState.isLoading">
|
||||
<span x-show="!createState.isLoading">Save stock entry</span>
|
||||
<span x-show="createState.isLoading">Saving...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-outline-secondary" type="button" @click="reset()">Clear form</button>
|
||||
<button class="btn btn-outline-secondary label-action-btn" type="button" @click="reset()">Clear form</button>
|
||||
</div>
|
||||
<div class="small text-body-secondary">
|
||||
<span class="text-danger">*</span> Required field
|
||||
@@ -561,6 +575,8 @@ export function labelCreatePageData(store) {
|
||||
submitError: '',
|
||||
fieldErrors: {},
|
||||
upsertPreview: null,
|
||||
printLabelOnSave: true,
|
||||
printIssue: '',
|
||||
form: {
|
||||
...loadLabelDraft(),
|
||||
},
|
||||
@@ -997,6 +1013,10 @@ export function labelCreatePageData(store) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (this.upsertPreview.mode !== 'preview') {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (this.upsertPreview.operation === 'update') {
|
||||
const name = this.upsertPreview.matchedItem?.name || this.form.name;
|
||||
const matchType = this.upsertPreview.matchType ? ` (matched by ${this.upsertPreview.matchType})` : '';
|
||||
@@ -1009,6 +1029,7 @@ export function labelCreatePageData(store) {
|
||||
this.submitError = '';
|
||||
this.fieldErrors = {};
|
||||
this.upsertPreview = null;
|
||||
this.printIssue = '';
|
||||
|
||||
if (!this.validateBeforeSubmit()) {
|
||||
this.previewState.error = 'Please fill out the required fields before previewing the label.';
|
||||
@@ -1035,6 +1056,7 @@ export function labelCreatePageData(store) {
|
||||
async create() {
|
||||
this.submitError = '';
|
||||
this.fieldErrors = {};
|
||||
this.printIssue = '';
|
||||
|
||||
if (!this.validateBeforeSubmit()) {
|
||||
this.submitError = 'Please fill out the required fields before saving the stock entry.';
|
||||
@@ -1044,12 +1066,23 @@ export function labelCreatePageData(store) {
|
||||
await runAsyncState(this.createState, async () => {
|
||||
try {
|
||||
const entry = await applyItemUpsert(store, this.buildUpsertPayload());
|
||||
if (this.previewUrl && this.previewUrl.startsWith('blob:')) {
|
||||
URL.revokeObjectURL(this.previewUrl);
|
||||
}
|
||||
this.previewUrl = '';
|
||||
const entryName = entry.item?.name || this.form.name;
|
||||
const operationVerb = entry.operation === 'update' ? 'updated' : 'created';
|
||||
const createdUuidB64 = entry.item?.uuid_b64 || null;
|
||||
|
||||
if (this.printLabelOnSave && createdUuidB64) {
|
||||
try {
|
||||
await printItemLabel(store, createdUuidB64);
|
||||
} catch (printError) {
|
||||
const parsedPrintMessage = formatPrintErrorMessage(printError);
|
||||
this.printIssue = parsedPrintMessage;
|
||||
store.addAlert({
|
||||
type: 'warning',
|
||||
message: `${entryName} was ${operationVerb}, but printing has an issue: ${parsedPrintMessage}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.successMessage = `${entryName} was ${operationVerb} successfully.`;
|
||||
store.addAlert({
|
||||
type: 'success',
|
||||
@@ -1074,6 +1107,7 @@ export function labelCreatePageData(store) {
|
||||
this.submitError = '';
|
||||
this.fieldErrors = {};
|
||||
this.upsertPreview = null;
|
||||
this.printIssue = '';
|
||||
saveStoredValue(STORAGE_KEYS.labelDraft, this.form);
|
||||
if (revokePreview && this.previewUrl.startsWith('blob:')) {
|
||||
URL.revokeObjectURL(this.previewUrl);
|
||||
|
||||
Reference in New Issue
Block a user