From 60b2f76537cb1eed5795b9ea912fb7e1b26e659c Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Sat, 4 Jul 2026 13:26:10 +0300 Subject: [PATCH] Fix product performance grouped JSON build --- .../pages/ProductPerformanceProfitability.vue | 88 ++++++++++--------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/ui/src/pages/ProductPerformanceProfitability.vue b/ui/src/pages/ProductPerformanceProfitability.vue index a36e291..c6f919c 100644 --- a/ui/src/pages/ProductPerformanceProfitability.vue +++ b/ui/src/pages/ProductPerformanceProfitability.vue @@ -41,7 +41,6 @@ :icon="allProductGroupsExpanded ? 'unfold_less' : 'unfold_more'" :label="allProductGroupsExpanded ? 'Detayları Kapat' : 'Tüm Detayları Aç'" :disable="pageBusy" - @click="toggleAllProductGroups" >
- - + +
@@ -1578,6 +1577,7 @@ const backendGroupedRows = ref({}) const backendGroupedLoading = ref(false) const imagePrimeLoading = ref(false) const filterBusy = ref(false) +const bulkExpandLoading = ref(false) const generalRowsLoaded = ref(false) let backendGroupedTimer = null let imagePrimeActiveRequests = 0 @@ -1603,10 +1603,10 @@ const maxBulkExpandKeys = 500 const maxBackendExpandedKeys = 120 const tableVirtualSliceSize = 160 const maxAutoExpandLevelByTab = { - products: 2, - product_detail: 1, - idle: 2, - sales_color_yaka_market_customer: 0 + products: 8, + product_detail: 4, + idle: 7, + sales_color_yaka_market_customer: 5 } const performanceTabs = [ { name: 'products', icon: 'dashboard', label: 'Genel Özet KPI' }, @@ -1618,7 +1618,7 @@ const performanceTabs = [ { name: 'order_product_customers', icon: 'assignment_ind', label: 'Ürün > Piyasa > Müşteri Sipariş' }, { name: 'order_market_details', icon: 'receipt_long', label: 'Piyasa > Müşteri > Ürün Sipariş' } ] -const pageBusy = computed(() => loading.value || filterBusy.value) +const pageBusy = computed(() => loading.value || filterBusy.value || bulkExpandLoading.value) const pagination = ref({ page: 1, @@ -2583,9 +2583,9 @@ function maxAutoExpandThroughLevelForTab (tabKey = activeTab.value) { } function maxBackendExpandedKeysForTab (tabKey = activeTab.value) { - if (tabKey === 'product_detail') return 160 - if (tabKey === 'products' || tabKey === 'idle') return maxBackendExpandedKeys - if (salesBreakdownTabKeys.includes(tabKey)) return 80 + if (tabKey === 'product_detail') return 260 + if (tabKey === 'products' || tabKey === 'idle') return 260 + if (salesBreakdownTabKeys.includes(tabKey)) return 180 return 100 } @@ -3391,22 +3391,22 @@ function toggleGroup (key) { scheduleLoadBackendGroupedRows() } -function toggleAllProductGroups () { - const keys = productAutoExpandKeys.value - if (allProductGroupsExpanded.value) { - collapseAllProductGroups() - return - } - expandSelectedProductGroups() -} - -function collapseAllProductGroups () { - expandedGroups.value = {} +async function collapseAllProductGroups () { + const tabPrefix = `tab:${activeTab.value}|` + expandedGroups.value = Object.fromEntries( + Object.entries(expandedGroups.value).filter(([key]) => !key.startsWith(tabPrefix)) + ) lastManualExpandedGroupKey.value = '' - scheduleLoadBackendGroupedRows() + if (backendGroupedTimer) window.clearTimeout(backendGroupedTimer) + bulkExpandLoading.value = true + try { + await loadBackendGroupedRows({ force: true }) + } finally { + bulkExpandLoading.value = false + } } -function expandSelectedProductGroups () { +async function expandSelectedProductGroups () { const keys = productAutoExpandKeys.value const maxKeys = Math.min(maxBulkExpandKeys, maxBackendExpandedKeysForTab(activeTab.value)) const expandableKeys = keys.slice(0, maxKeys) @@ -3423,7 +3423,13 @@ function expandSelectedProductGroups () { message: `${formatNumber(expandableKeys.length, 0)} grup açıldı. Daha derin detaylar için satırları kademeli açın.` }) } - scheduleLoadBackendGroupedRows() + if (backendGroupedTimer) window.clearTimeout(backendGroupedTimer) + bulkExpandLoading.value = true + try { + await loadBackendGroupedRows({ force: true }) + } finally { + bulkExpandLoading.value = false + } } function groupLabelColumnName (row) { @@ -4252,7 +4258,7 @@ function scheduleLoadBackendGroupedRows () { if (backendGroupedTimer) window.clearTimeout(backendGroupedTimer) backendGroupedTimer = window.setTimeout(() => { void loadBackendGroupedRows() - }, 120) + }, 260) } function switchPerformanceTab (tabName) { @@ -4274,6 +4280,7 @@ async function loadBackendGroupedRows (options = {}) { } pruneActiveExpandedGroups() backendGroupedLoading.value = true + const requestKey = `${tabKey}|${activeExpandedGroupKeys().join('~')}|${selectedDetailMainGroup.value || ''}` const params = { mode: tabKey, groupLevels: activeGroupLevels.value.map(level => level.key), @@ -4286,6 +4293,8 @@ async function loadBackendGroupedRows (options = {}) { try { const startedAt = performance.now() const rows = await performanceStore.fetchGroupedRows(params, { force: options.force === true }) + const currentKey = `${activeTab.value}|${activeExpandedGroupKeys().join('~')}|${selectedDetailMainGroup.value || ''}` + if (requestKey !== currentKey) return const normalizedRows = Array.isArray(rows) ? rows.map(row => normalizeGroupedDisplayRow(tabKey, row)) : [] backendGroupedRows.value = { ...backendGroupedRows.value, @@ -4537,10 +4546,6 @@ watch(activeTab, () => { scheduleLoadBackendGroupedRows() }) -watch(activeSelectedExpandLevelKeys, () => { - scheduleLoadBackendGroupedRows() -}) - watch(detailMainGroupOptions, () => { ensureDetailMainGroupSelection() }, { immediate: true }) @@ -4769,11 +4774,7 @@ onMounted(reload) .performance-table :deep(.q-table__middle) { max-height: calc(100vh - 220px); - transform: rotateX(180deg); -} - -.performance-table :deep(.q-table__middle > .q-table) { - transform: rotateX(180deg); + overflow: auto; } .performance-table :deep(.q-table__bottom) { @@ -4880,11 +4881,16 @@ onMounted(reload) border-left: 1px solid #d5dce5; } -.performance-table :deep(th) { +.performance-table :deep(.q-table thead), +.performance-table :deep(.q-table thead tr), +.performance-table :deep(.q-table th) { position: sticky; top: 0; - z-index: 1; + z-index: 20; background: #f8fbff; +} + +.performance-table :deep(th) { border-top: 1px solid #d5dce5; } @@ -4900,7 +4906,7 @@ onMounted(reload) } .product-breakdown-table :deep(.q-table th:nth-child(-n+10)) { - z-index: 4; + z-index: 30; background: #f8fbff; } @@ -5002,7 +5008,7 @@ onMounted(reload) .product-breakdown-table.product-detail-table :deep(.q-table th:nth-child(n+8)) { left: auto; - z-index: 1; + z-index: 20; box-shadow: none; } @@ -5013,7 +5019,7 @@ onMounted(reload) } .product-breakdown-table.product-detail-table :deep(.q-table th:nth-child(-n+7)) { - z-index: 4; + z-index: 30; background: #f8fbff; } @@ -5214,7 +5220,7 @@ onMounted(reload) .sticky-dim-table.sticky-dim-9 :deep(.q-table th:nth-child(-n+9)), .sticky-dim-table.sticky-dim-10 :deep(.q-table th:nth-child(-n+10)), .sticky-dim-table.sticky-dim-11 :deep(.q-table th:nth-child(-n+11)) { - z-index: 4; + z-index: 30; background: #f8fbff; }