fix(usage): memoize resource breakdown filters (review comment)

The GPU Instances / Storage tabs built the filter object inline (in
baseRequest and again in the extra tab's props), duplicating the
conditional-spread logic and handing the enterprise Organization tab a fresh
object every render — which refired its fetch effect on any state change.
Hoist it into one memoized ``breakdownFilters`` shared by the chart request
and the extra tab, mirroring the Tokens tab's stable-filters shape.
This commit is contained in:
michelia
2026-07-14 14:35:23 +08:00
committed by jialin
parent 77a2abad32
commit 046d466e16
2 changed files with 49 additions and 62 deletions
+24 -29
View File
@@ -164,28 +164,36 @@ const GpuInstancesTab: React.FC = () => {
fetchData: fetchChartData fetchData: fetchChartData
} = useQueryGpuInstancesBreakdown({ key: 'gpuInstancesBreakdownChart' }); } = useQueryGpuInstancesBreakdown({ key: 'gpuInstancesBreakdownChart' });
const baseRequest = (): Omit<ResourceBreakdownRequest, 'group_by'> => ({ // Single source of truth for the active filter set — memoized so its
start_date: dateRange[0].format('YYYY-MM-DD'), // reference only changes when a selection changes (an inline object would
end_date: dateRange[1].format('YYYY-MM-DD'), // refire the extra tab's fetch effect on every render), and shared by both
scope, // the chart request and the enterprise extra tab (no duplicated spread).
granularity, const breakdownFilters = useMemo(
filters: () => ({
selectedUsers.length ||
selectedInstances.length ||
selectedOrganizations.length ||
selectedUserGroups.length
? {
...(selectedUsers.length ? { creator_ids: selectedUsers } : {}), ...(selectedUsers.length ? { creator_ids: selectedUsers } : {}),
...(selectedInstances.length ...(selectedInstances.length ? { instance_ids: selectedInstances } : {}),
? { instance_ids: selectedInstances }
: {}),
...(selectedOrganizations.length ...(selectedOrganizations.length
? { organization_ids: selectedOrganizations } ? { organization_ids: selectedOrganizations }
: {}), : {}),
...(selectedUserGroups.length ...(selectedUserGroups.length
? { user_group_ids: selectedUserGroups } ? { user_group_ids: selectedUserGroups }
: {}) : {})
} }),
[
selectedUsers,
selectedInstances,
selectedOrganizations,
selectedUserGroups
]
);
const baseRequest = (): Omit<ResourceBreakdownRequest, 'group_by'> => ({
start_date: dateRange[0].format('YYYY-MM-DD'),
end_date: dateRange[1].format('YYYY-MM-DD'),
scope,
granularity,
filters: Object.keys(breakdownFilters).length
? breakdownFilters
: undefined, : undefined,
page: 1, page: 1,
perPage: 50 perPage: 50
@@ -536,20 +544,7 @@ const GpuInstancesTab: React.FC = () => {
tab="gpu-instances" tab="gpu-instances"
dateRange={dateRange} dateRange={dateRange}
scope={scope} scope={scope}
filters={{ filters={breakdownFilters}
...(selectedUsers.length
? { creator_ids: selectedUsers }
: {}),
...(selectedInstances.length
? { instance_ids: selectedInstances }
: {}),
...(selectedOrganizations.length
? { organization_ids: selectedOrganizations }
: {}),
...(selectedUserGroups.length
? { user_group_ids: selectedUserGroups }
: {})
}}
pageResetKey={pageResetKey} pageResetKey={pageResetKey}
refreshKey={refreshKey} refreshKey={refreshKey}
/> />
+18 -26
View File
@@ -158,17 +158,12 @@ const StorageTab: React.FC = () => {
fetchData: fetchChartData fetchData: fetchChartData
} = useQueryStorageBreakdown({ key: 'storageBreakdownChart' }); } = useQueryStorageBreakdown({ key: 'storageBreakdownChart' });
const baseRequest = (): Omit<ResourceBreakdownRequest, 'group_by'> => ({ // Single source of truth for the active filter set — memoized so its
start_date: dateRange[0].format('YYYY-MM-DD'), // reference only changes when a selection changes (an inline object would
end_date: dateRange[1].format('YYYY-MM-DD'), // refire the extra tab's fetch effect on every render), and shared by both
scope, // the chart request and the enterprise extra tab (no duplicated spread).
granularity, const breakdownFilters = useMemo(
filters: () => ({
selectedUsers.length ||
selectedVolumes.length ||
selectedOrganizations.length ||
selectedUserGroups.length
? {
...(selectedUsers.length ? { creator_ids: selectedUsers } : {}), ...(selectedUsers.length ? { creator_ids: selectedUsers } : {}),
...(selectedVolumes.length ? { volume_ids: selectedVolumes } : {}), ...(selectedVolumes.length ? { volume_ids: selectedVolumes } : {}),
...(selectedOrganizations.length ...(selectedOrganizations.length
@@ -177,7 +172,17 @@ const StorageTab: React.FC = () => {
...(selectedUserGroups.length ...(selectedUserGroups.length
? { user_group_ids: selectedUserGroups } ? { user_group_ids: selectedUserGroups }
: {}) : {})
} }),
[selectedUsers, selectedVolumes, selectedOrganizations, selectedUserGroups]
);
const baseRequest = (): Omit<ResourceBreakdownRequest, 'group_by'> => ({
start_date: dateRange[0].format('YYYY-MM-DD'),
end_date: dateRange[1].format('YYYY-MM-DD'),
scope,
granularity,
filters: Object.keys(breakdownFilters).length
? breakdownFilters
: undefined, : undefined,
page: 1, page: 1,
perPage: 50 perPage: 50
@@ -516,20 +521,7 @@ const StorageTab: React.FC = () => {
tab="storage" tab="storage"
dateRange={dateRange} dateRange={dateRange}
scope={scope} scope={scope}
filters={{ filters={breakdownFilters}
...(selectedUsers.length
? { creator_ids: selectedUsers }
: {}),
...(selectedVolumes.length
? { volume_ids: selectedVolumes }
: {}),
...(selectedOrganizations.length
? { organization_ids: selectedOrganizations }
: {}),
...(selectedUserGroups.length
? { user_group_ids: selectedUserGroups }
: {})
}}
pageResetKey={pageResetKey} pageResetKey={pageResetKey}
refreshKey={refreshKey} refreshKey={refreshKey}
/> />