Fix catalog issues: quantity input, checkbox position, glass header
All checks were successful
Build Docker Image / build (push) Successful in 3m21s
All checks were successful
Build Docker Image / build (push) Successful in 3m21s
1. Quantity input in Quote mode: replaced button with inline number input 2. Checkbox position: moved to left side (next to panel) instead of right 3. MapPanel glass header: fixed sticky positioning by moving negative margins to children
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col h-full -m-4">
|
<div class="flex flex-col h-full">
|
||||||
<!-- Header: белое стекло -->
|
<!-- Header: белое стекло (negative margins to expand beyond parent padding) -->
|
||||||
<div class="sticky top-0 z-10 p-4 rounded-t-xl bg-white/90 backdrop-blur-md border-b border-white/20">
|
<div class="sticky top-0 z-10 -mx-4 -mt-4 px-4 pt-4 pb-3 rounded-t-xl bg-white/90 backdrop-blur-md border-b border-white/20">
|
||||||
<slot name="header" />
|
<slot name="header" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Content: тёмный (наследует контейнер) -->
|
<!-- Content: тёмный (negative margins to expand beyond parent padding) -->
|
||||||
<div class="flex-1 px-4 pt-3 pb-4 overflow-y-auto">
|
<div class="flex-1 -mx-4 -mb-4 px-4 pt-3 pb-4 overflow-y-auto">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -55,14 +55,23 @@
|
|||||||
<div class="text-xs text-base-content/60">{{ $t('catalog.filters.hub') }}</div>
|
<div class="text-xs text-base-content/60">{{ $t('catalog.filters.hub') }}</div>
|
||||||
<div class="font-medium truncate text-base-content">{{ hubLabel || $t('catalog.quote.selectHub') }}</div>
|
<div class="font-medium truncate text-base-content">{{ hubLabel || $t('catalog.quote.selectHub') }}</div>
|
||||||
</button>
|
</button>
|
||||||
<!-- Quantity segment -->
|
<!-- Quantity segment (inline input) -->
|
||||||
<button
|
<div class="flex-1 px-4 py-2 min-w-0">
|
||||||
class="flex-1 px-4 py-2 text-left hover:bg-base-200/50 transition-colors min-w-0"
|
|
||||||
@click="$emit('edit-token', 'quantity')"
|
|
||||||
>
|
|
||||||
<div class="text-xs text-base-content/60">{{ $t('catalog.filters.quantity') }}</div>
|
<div class="text-xs text-base-content/60">{{ $t('catalog.filters.quantity') }}</div>
|
||||||
<div class="font-medium text-base-content">{{ quantity ? `${quantity} ${$t('units.t')}` : '—' }}</div>
|
<div class="flex items-center gap-1">
|
||||||
</button>
|
<input
|
||||||
|
v-model="localQuantity"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
step="0.1"
|
||||||
|
placeholder="—"
|
||||||
|
class="w-16 font-medium bg-transparent outline-none text-base-content [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
||||||
|
@blur="$emit('update-quantity', localQuantity)"
|
||||||
|
@keyup.enter="$emit('update-quantity', localQuantity)"
|
||||||
|
/>
|
||||||
|
<span v-if="localQuantity" class="text-base-content/60 text-sm">{{ $t('units.t') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Search button inside -->
|
<!-- Search button inside -->
|
||||||
<button
|
<button
|
||||||
class="btn btn-primary btn-circle m-1"
|
class="btn btn-primary btn-circle m-1"
|
||||||
@@ -328,6 +337,7 @@ defineEmits([
|
|||||||
'edit-token',
|
'edit-token',
|
||||||
'remove-token',
|
'remove-token',
|
||||||
'update:search-query',
|
'update:search-query',
|
||||||
|
'update-quantity',
|
||||||
// Quote mode
|
// Quote mode
|
||||||
'search',
|
'search',
|
||||||
'set-catalog-mode'
|
'set-catalog-mode'
|
||||||
@@ -340,11 +350,16 @@ const { t } = useI18n()
|
|||||||
|
|
||||||
const inputRef = ref<HTMLInputElement>()
|
const inputRef = ref<HTMLInputElement>()
|
||||||
const localSearchQuery = ref(props.searchQuery || '')
|
const localSearchQuery = ref(props.searchQuery || '')
|
||||||
|
const localQuantity = ref(props.quantity || '')
|
||||||
|
|
||||||
watch(() => props.searchQuery, (val) => {
|
watch(() => props.searchQuery, (val) => {
|
||||||
localSearchQuery.value = val || ''
|
localSearchQuery.value = val || ''
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(() => props.quantity, (val) => {
|
||||||
|
localQuantity.value = val || ''
|
||||||
|
})
|
||||||
|
|
||||||
const focusInput = () => {
|
const focusInput = () => {
|
||||||
inputRef.value?.focus()
|
inputRef.value?.focus()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,22 +38,22 @@
|
|||||||
<span class="text-white text-sm">{{ $t('common.loading') }}</span>
|
<span class="text-white text-sm">{{ $t('common.loading') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- View toggle + filter checkbox (top RIGHT overlay, below header) -->
|
<!-- Filter by bounds checkbox (LEFT, next to panel) -->
|
||||||
<div class="absolute top-[116px] right-4 z-20 hidden lg:flex items-center gap-2">
|
<label
|
||||||
<!-- Filter by bounds checkbox (when panel is open) -->
|
v-if="showPanel"
|
||||||
<label
|
class="absolute top-[116px] left-[26rem] z-20 hidden lg:flex items-center gap-2 bg-black/30 backdrop-blur-md rounded-lg px-3 py-1.5 border border-white/10 cursor-pointer text-white text-sm hover:bg-black/40 transition-colors"
|
||||||
v-if="showPanel"
|
>
|
||||||
class="flex items-center gap-2 bg-black/30 backdrop-blur-md rounded-lg px-3 py-1.5 border border-white/10 cursor-pointer text-white text-sm hover:bg-black/40 transition-colors"
|
<input
|
||||||
>
|
type="checkbox"
|
||||||
<input
|
:checked="filterByBounds"
|
||||||
type="checkbox"
|
class="checkbox checkbox-xs checkbox-primary"
|
||||||
:checked="filterByBounds"
|
@change="$emit('update:filter-by-bounds', ($event.target as HTMLInputElement).checked)"
|
||||||
class="checkbox checkbox-xs checkbox-primary"
|
/>
|
||||||
@change="$emit('update:filter-by-bounds', ($event.target as HTMLInputElement).checked)"
|
<span>{{ $t('catalog.search.filterByMap') }}</span>
|
||||||
/>
|
</label>
|
||||||
<span>{{ $t('catalog.search.filterByMap') }}</span>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
|
<!-- View toggle (top RIGHT overlay, below header) -->
|
||||||
|
<div class="absolute top-[116px] right-4 z-20 hidden lg:flex items-center gap-2">
|
||||||
<!-- View mode toggle -->
|
<!-- View mode toggle -->
|
||||||
<div class="flex gap-1 bg-black/30 backdrop-blur-md rounded-lg p-1 border border-white/10">
|
<div class="flex gap-1 bg-black/30 backdrop-blur-md rounded-lg p-1 border border-white/10">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -205,6 +205,11 @@ export function useCatalogSearch() {
|
|||||||
updateQuery({ select: type as SelectMode })
|
updateQuery({ select: type as SelectMode })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setQuantity = (value: string) => {
|
||||||
|
const qty = value ? value : null
|
||||||
|
updateQuery({ qty })
|
||||||
|
}
|
||||||
|
|
||||||
const clearAll = () => {
|
const clearAll = () => {
|
||||||
if (isMainPage.value) {
|
if (isMainPage.value) {
|
||||||
router.push({ path: localePath('/catalog'), query: {} })
|
router.push({ path: localePath('/catalog'), query: {} })
|
||||||
@@ -277,6 +282,7 @@ export function useCatalogSearch() {
|
|||||||
selectItem,
|
selectItem,
|
||||||
removeFilter,
|
removeFilter,
|
||||||
editFilter,
|
editFilter,
|
||||||
|
setQuantity,
|
||||||
clearAll,
|
clearAll,
|
||||||
setLabel,
|
setLabel,
|
||||||
setMapViewMode,
|
setMapViewMode,
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
@edit-token="editFilter"
|
@edit-token="editFilter"
|
||||||
@remove-token="removeFilter"
|
@remove-token="removeFilter"
|
||||||
@update:search-query="searchQuery = $event"
|
@update:search-query="searchQuery = $event"
|
||||||
|
@update-quantity="setQuantity"
|
||||||
@search="onSearch"
|
@search="onSearch"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ const {
|
|||||||
cancelSelect,
|
cancelSelect,
|
||||||
removeFilter,
|
removeFilter,
|
||||||
editFilter,
|
editFilter,
|
||||||
|
setQuantity,
|
||||||
catalogMode,
|
catalogMode,
|
||||||
setCatalogMode,
|
setCatalogMode,
|
||||||
productLabel,
|
productLabel,
|
||||||
|
|||||||
Reference in New Issue
Block a user