Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -15,17 +15,30 @@
|
||||
v-model="filters[def.key]"
|
||||
:options="filteredOptionLists[def.key] || []"
|
||||
:label="def.label"
|
||||
:multiple="isMultiFilter(def.key)"
|
||||
:use-chips="isMultiFilter(def.key)"
|
||||
filled
|
||||
dense
|
||||
clearable
|
||||
use-input
|
||||
use-selected
|
||||
input-debounce="250"
|
||||
:disable="isFilterDisabled(def.key)"
|
||||
:loading="loadingFilterOptions"
|
||||
@update:model-value="onFilterValueChange(def.key)"
|
||||
@filter="(val, update) => filterOptions(def.key, val, update)"
|
||||
@keyup.enter="fetchStockByAttributes"
|
||||
/>
|
||||
>
|
||||
<template v-if="isMultiFilter(def.key)" #before-options>
|
||||
<q-item clickable dense v-ripple @click.stop="selectAllFilterOptions(def.key)">
|
||||
<q-item-section>Tumunu Sec</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable dense v-ripple @click.stop="clearAllFilterOptions(def.key)">
|
||||
<q-item-section>Tumunu Temizle</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
@@ -389,21 +402,16 @@ const filterDefs = [
|
||||
{ key: 'drop', label: 'Drop' },
|
||||
{ key: 'beden', label: 'Beden' }
|
||||
]
|
||||
const singleSelectFilterKeys = new Set(['kategori', 'urun_ana_grubu'])
|
||||
const multiSelectFilterKeys = new Set(
|
||||
filterDefs.map((def) => def.key).filter((key) => !singleSelectFilterKeys.has(key))
|
||||
)
|
||||
const filterValueSeparator = '\u001f'
|
||||
|
||||
const loadingFilterOptions = ref(false)
|
||||
const loadingStock = ref(false)
|
||||
const errorMessage = ref('')
|
||||
const filters = ref({
|
||||
kategori: '',
|
||||
urun_ana_grubu: '',
|
||||
urun_alt_grubu: '',
|
||||
renk: '',
|
||||
renk2: '',
|
||||
urun_icerigi: '',
|
||||
fit: '',
|
||||
drop: '',
|
||||
beden: ''
|
||||
})
|
||||
const filters = ref(createEmptyFilters())
|
||||
const optionLists = ref({})
|
||||
const filteredOptionLists = ref({})
|
||||
const filterOptionsCache = ref({})
|
||||
@@ -442,8 +450,8 @@ const activeSchema = ref(storeSchemaByKey.tak)
|
||||
const activeGrpKey = ref('tak')
|
||||
const openState = ref({})
|
||||
const canQuery = computed(() =>
|
||||
String(filters.value?.kategori || '').trim() !== '' &&
|
||||
String(filters.value?.urun_ana_grubu || '').trim() !== ''
|
||||
normalizeFilterScalar(filters.value?.kategori) !== '' &&
|
||||
normalizeFilterScalar(filters.value?.urun_ana_grubu) !== ''
|
||||
)
|
||||
|
||||
const sizeLabels = computed(() => activeSchema.value?.values || [])
|
||||
@@ -654,6 +662,8 @@ function resolveProductImageUrl(item) {
|
||||
|
||||
function extractImageOrder(fileName, fallbackIndex) {
|
||||
const name = String(fileName || '').trim()
|
||||
const mg = name.match(/gallery[-_\s]?(\d+)/i)
|
||||
if (mg) return Number(mg[1] || 999999)
|
||||
const m = name.match(/\((\d+)\)(?=\.[a-z0-9]+$)/i)
|
||||
if (m) return Number(m[1] || 999999)
|
||||
const m2 = name.match(/[-_ ](\d+)(?=\.[a-z0-9]+$)/i)
|
||||
@@ -759,8 +769,9 @@ async function ensureProductImage(code, color, secondColor = '', dim1Id = '', di
|
||||
}
|
||||
}
|
||||
const rawList = Array.isArray(productImageListByCode.value[listKey]) ? productImageListByCode.value[listKey] : []
|
||||
const primaryItem = rawList[0] || null
|
||||
const secondaryItem = rawList.length > 1 ? rawList[rawList.length - 1] : null
|
||||
const sortedList = sortImagesForDisplay(rawList)
|
||||
const primaryItem = sortedList[0] || null
|
||||
const secondaryItem = sortedList.length > 1 ? sortedList[sortedList.length - 1] : null
|
||||
|
||||
const primaryResolved = resolveProductImageUrl(primaryItem)
|
||||
let preferredCardUrl = primaryItem ? await resolveProductImageUrlForCarousel(primaryItem) : ''
|
||||
@@ -992,14 +1003,51 @@ const level1Groups = computed(() => {
|
||||
.sort(sortByTotalQtyDesc)
|
||||
})
|
||||
|
||||
function normalizeText(v) {
|
||||
return String(v || '').trim()
|
||||
function createEmptyFilters() {
|
||||
return {
|
||||
kategori: '',
|
||||
urun_ana_grubu: '',
|
||||
urun_alt_grubu: [],
|
||||
renk: [],
|
||||
renk2: [],
|
||||
urun_icerigi: [],
|
||||
fit: [],
|
||||
drop: [],
|
||||
beden: []
|
||||
}
|
||||
}
|
||||
|
||||
function buildFilterParams() {
|
||||
function isMultiFilter(key) {
|
||||
return multiSelectFilterKeys.has(key)
|
||||
}
|
||||
|
||||
function normalizeFilterScalar(v) {
|
||||
return String(v ?? '').trim()
|
||||
}
|
||||
|
||||
function normalizeFilterList(v) {
|
||||
const src = Array.isArray(v) ? v : (normalizeFilterScalar(v) ? [v] : [])
|
||||
const out = []
|
||||
const seen = new Set()
|
||||
for (const item of src) {
|
||||
const val = normalizeFilterScalar(item)
|
||||
if (!val || seen.has(val)) continue
|
||||
seen.add(val)
|
||||
out.push(val)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
function buildFilterParams(excludeKey = '') {
|
||||
const out = {}
|
||||
for (const def of filterDefs) {
|
||||
const val = normalizeText(filters.value?.[def.key])
|
||||
if (excludeKey && def.key === excludeKey) continue
|
||||
if (isMultiFilter(def.key)) {
|
||||
const vals = normalizeFilterList(filters.value?.[def.key])
|
||||
if (vals.length) out[def.key] = vals.join(filterValueSeparator)
|
||||
continue
|
||||
}
|
||||
const val = normalizeFilterScalar(filters.value?.[def.key])
|
||||
if (val) out[def.key] = val
|
||||
}
|
||||
return out
|
||||
@@ -1013,7 +1061,7 @@ function buildFilterCacheKey(params) {
|
||||
function isFilterDisabled(key) {
|
||||
if (key === 'kategori') return false
|
||||
if (key === 'urun_ana_grubu') {
|
||||
return normalizeText(filters.value.kategori) === ''
|
||||
return normalizeFilterScalar(filters.value.kategori) === ''
|
||||
}
|
||||
return !canQuery.value
|
||||
}
|
||||
@@ -1021,33 +1069,34 @@ function isFilterDisabled(key) {
|
||||
function onFilterValueChange(changedKey) {
|
||||
if (changedKey === 'kategori') {
|
||||
filters.value.urun_ana_grubu = ''
|
||||
filters.value.urun_alt_grubu = ''
|
||||
filters.value.renk = ''
|
||||
filters.value.renk2 = ''
|
||||
filters.value.urun_icerigi = ''
|
||||
filters.value.fit = ''
|
||||
filters.value.drop = ''
|
||||
filters.value.beden = ''
|
||||
filters.value.urun_alt_grubu = []
|
||||
filters.value.renk = []
|
||||
filters.value.renk2 = []
|
||||
filters.value.urun_icerigi = []
|
||||
filters.value.fit = []
|
||||
filters.value.drop = []
|
||||
filters.value.beden = []
|
||||
} else if (changedKey === 'urun_ana_grubu') {
|
||||
filters.value.urun_alt_grubu = ''
|
||||
filters.value.renk = ''
|
||||
filters.value.renk2 = ''
|
||||
filters.value.urun_icerigi = ''
|
||||
filters.value.fit = ''
|
||||
filters.value.drop = ''
|
||||
filters.value.beden = ''
|
||||
filters.value.urun_alt_grubu = []
|
||||
filters.value.renk = []
|
||||
filters.value.renk2 = []
|
||||
filters.value.urun_icerigi = []
|
||||
filters.value.fit = []
|
||||
filters.value.drop = []
|
||||
filters.value.beden = []
|
||||
} else if (changedKey === 'renk') {
|
||||
filters.value.renk2 = ''
|
||||
filters.value.beden = ''
|
||||
filters.value.renk2 = []
|
||||
filters.value.beden = []
|
||||
} else if (changedKey === 'renk2') {
|
||||
filters.value.beden = ''
|
||||
filters.value.beden = []
|
||||
}
|
||||
|
||||
if (filterOptionsDebounceTimer) {
|
||||
clearTimeout(filterOptionsDebounceTimer)
|
||||
}
|
||||
const excludeKey = isMultiFilter(changedKey) ? changedKey : ''
|
||||
filterOptionsDebounceTimer = setTimeout(() => {
|
||||
void loadFilterOptions()
|
||||
void loadFilterOptions(false, excludeKey)
|
||||
}, FILTER_OPTIONS_DEBOUNCE_MS)
|
||||
}
|
||||
|
||||
@@ -1069,8 +1118,21 @@ function filterOptions(field, val, update) {
|
||||
})
|
||||
}
|
||||
|
||||
async function loadFilterOptions(force = false) {
|
||||
const params = buildFilterParams()
|
||||
function selectAllFilterOptions(key) {
|
||||
if (!isMultiFilter(key) || isFilterDisabled(key)) return
|
||||
const list = Array.isArray(optionLists.value?.[key]) ? optionLists.value[key] : []
|
||||
filters.value[key] = [...list]
|
||||
onFilterValueChange(key)
|
||||
}
|
||||
|
||||
function clearAllFilterOptions(key) {
|
||||
if (!isMultiFilter(key) || isFilterDisabled(key)) return
|
||||
filters.value[key] = []
|
||||
onFilterValueChange(key)
|
||||
}
|
||||
|
||||
async function loadFilterOptions(force = false, excludeKey = '') {
|
||||
const params = buildFilterParams(excludeKey)
|
||||
const cacheKey = buildFilterCacheKey(params)
|
||||
const now = Date.now()
|
||||
if (!force) {
|
||||
@@ -1102,9 +1164,14 @@ async function loadFilterOptions(force = false) {
|
||||
next[def.key] = list
|
||||
nextFiltered[def.key] = [...list]
|
||||
|
||||
const selected = normalizeText(filters.value?.[def.key])
|
||||
if (selected && !list.includes(selected)) {
|
||||
filters.value[def.key] = ''
|
||||
if (isMultiFilter(def.key)) {
|
||||
const selectedList = normalizeFilterList(filters.value?.[def.key])
|
||||
filters.value[def.key] = selectedList.filter((v) => list.includes(v))
|
||||
} else {
|
||||
const selected = normalizeFilterScalar(filters.value?.[def.key])
|
||||
if (selected && !list.includes(selected)) {
|
||||
filters.value[def.key] = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1359,17 +1426,7 @@ function onFullscreenSlideChange() {
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
filters.value = {
|
||||
kategori: '',
|
||||
urun_ana_grubu: '',
|
||||
urun_alt_grubu: '',
|
||||
renk: '',
|
||||
renk2: '',
|
||||
urun_icerigi: '',
|
||||
fit: '',
|
||||
drop: '',
|
||||
beden: ''
|
||||
}
|
||||
filters.value = createEmptyFilters()
|
||||
rawRows.value = []
|
||||
errorMessage.value = ''
|
||||
openState.value = {}
|
||||
|
||||
Reference in New Issue
Block a user