From 218647b2cbb4c68ed0bb52ca85799c5c8a53964d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Bregar?= Date: Mon, 6 Apr 2026 17:34:11 +0200 Subject: [PATCH] Improve label quantity input and unit picker --- src/features/labels/label-create-page.js | 126 ++++++++++++++++++++--- src/styles/app.css | 4 + 2 files changed, 113 insertions(+), 17 deletions(-) diff --git a/src/features/labels/label-create-page.js b/src/features/labels/label-create-page.js index df449ad..bdc88a1 100644 --- a/src/features/labels/label-create-page.js +++ b/src/features/labels/label-create-page.js @@ -21,6 +21,8 @@ const STOCK_LEVEL_OPTIONS = [ { value: 'gone', label: 'Gone (~= 0%)' }, ]; +const QUANTITY_UNIT_OPTIONS = ['g', 'ml', 'pc']; + export function renderLabelCreatePage() { return `
@@ -69,7 +71,7 @@ export function renderLabelCreatePage() {
- +
-
+
- +
+
+ * Required field +
@@ -389,6 +442,10 @@ function loadLabelDraft() { return { ...createDefaultForm(), ...draft, + quantity: + draft.quantity === 0 || draft.quantity === '0' || draft.quantity == null + ? '' + : draft.quantity, itemId: '', search: '', }; @@ -408,10 +465,12 @@ export function labelCreatePageData(store) { createState: createAsyncState(), stockTypeOptions: STOCK_TYPE_OPTIONS, stockLevelOptions: STOCK_LEVEL_OPTIONS, + quantityUnitOptions: QUANTITY_UNIT_OPTIONS, suggestions: [], locations: [], locationSearch: '', locationPickerOpen: false, + quantityUnitPickerOpen: false, previewUrl: '', successMessage: '', submitError: '', @@ -463,7 +522,7 @@ export function labelCreatePageData(store) { this.form.description = item.description || this.form.description; this.form.uom = item.uom_symbol || this.form.uom; this.form.quantity = - item.quantity === 0 || item.quantity + item.quantity ? String(item.quantity) : this.form.quantity; this.form.stockType = item.stock_type || this.form.stockType; @@ -501,6 +560,26 @@ export function labelCreatePageData(store) { `${location.name} ${location.pathLabel}`.toLowerCase().includes(query), ); }, + get filteredQuantityUnits() { + const query = this.form.uom.trim().toLowerCase(); + if (!query) { + return this.quantityUnitOptions; + } + + if (this.quantityUnitOptions.some((unit) => unit.toLowerCase() === query)) { + return this.quantityUnitOptions; + } + + const matches = this.quantityUnitOptions.filter((unit) => + unit.toLowerCase().includes(query), + ); + + if (matches.length) { + return matches; + } + + return this.quantityUnitOptions; + }, get selectedLocation() { return this.locations.find( (location) => String(location.id) === String(this.form.locationId), @@ -524,6 +603,9 @@ export function labelCreatePageData(store) { openLocationPicker() { this.locationPickerOpen = true; }, + openQuantityUnitPicker() { + this.quantityUnitPickerOpen = true; + }, onLocationInput() { this.locationPickerOpen = true; if (this.selectedLocation && this.locationSearch !== this.selectedLocation.name) { @@ -538,6 +620,21 @@ export function labelCreatePageData(store) { this.locationPickerOpen = false; }, + onQuantityUnitInput() { + this.quantityUnitPickerOpen = true; + }, + handleQuantityUnitFocusOut(event) { + const nextTarget = event.relatedTarget; + if (nextTarget && this.$refs.quantityUnitPicker?.contains(nextTarget)) { + return; + } + + this.quantityUnitPickerOpen = false; + }, + pickQuantityUnit(unit) { + this.form.uom = unit; + this.quantityUnitPickerOpen = false; + }, syncLocationSelection() { if (!this.form.locationId) { this.locationSearch = ''; @@ -610,9 +707,6 @@ export function labelCreatePageData(store) { return; } - this.form.quantity = ''; - this.form.uom = 'g'; - if (stockType === 'binary' && this.form.level !== 'plenty') { this.form.level = 'plenty'; return; @@ -634,20 +728,18 @@ export function labelCreatePageData(store) { }, buildPayload() { const quantity = - this.form.stockType === 'measured' - ? this.form.quantity === '' - ? null - : Number(this.form.quantity) - : this.form.stockType === 'binary' + this.form.quantity === '' + ? this.form.stockType === 'binary' ? 1 - : null; + : null + : Number(this.form.quantity); return { item_id: this.form.itemId || null, name: this.form.name.trim(), description: this.form.description.trim(), quantity_initial: quantity, - uom_symbol: this.form.stockType === 'measured' ? this.form.uom.trim() : null, + uom_symbol: this.form.uom.trim() || null, calories: this.form.energy === '' ? null : Number(this.form.energy), calories_unit: this.form.energyUnit.trim() || null, stock_type: this.form.stockType, diff --git a/src/styles/app.css b/src/styles/app.css index 1d26263..eb2c361 100644 --- a/src/styles/app.css +++ b/src/styles/app.css @@ -180,6 +180,10 @@ body { z-index: 4; } +.quantity-unit-picker { + z-index: 4; +} + .location-level-badge { display: inline-flex; align-items: center;