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
+27 -32
View File
@@ -164,29 +164,37 @@ const GpuInstancesTab: React.FC = () => {
fetchData: fetchChartData
} = useQueryGpuInstancesBreakdown({ key: 'gpuInstancesBreakdownChart' });
// Single source of truth for the active filter set — memoized so its
// reference only changes when a selection changes (an inline object would
// refire the extra tab's fetch effect on every render), and shared by both
// the chart request and the enterprise extra tab (no duplicated spread).
const breakdownFilters = useMemo(
() => ({
...(selectedUsers.length ? { creator_ids: selectedUsers } : {}),
...(selectedInstances.length ? { instance_ids: selectedInstances } : {}),
...(selectedOrganizations.length
? { organization_ids: selectedOrganizations }
: {}),
...(selectedUserGroups.length
? { 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:
selectedUsers.length ||
selectedInstances.length ||
selectedOrganizations.length ||
selectedUserGroups.length
? {
...(selectedUsers.length ? { creator_ids: selectedUsers } : {}),
...(selectedInstances.length
? { instance_ids: selectedInstances }
: {}),
...(selectedOrganizations.length
? { organization_ids: selectedOrganizations }
: {}),
...(selectedUserGroups.length
? { user_group_ids: selectedUserGroups }
: {})
}
: undefined,
filters: Object.keys(breakdownFilters).length
? breakdownFilters
: undefined,
page: 1,
perPage: 50
});
@@ -536,20 +544,7 @@ const GpuInstancesTab: React.FC = () => {
tab="gpu-instances"
dateRange={dateRange}
scope={scope}
filters={{
...(selectedUsers.length
? { creator_ids: selectedUsers }
: {}),
...(selectedInstances.length
? { instance_ids: selectedInstances }
: {}),
...(selectedOrganizations.length
? { organization_ids: selectedOrganizations }
: {}),
...(selectedUserGroups.length
? { user_group_ids: selectedUserGroups }
: {})
}}
filters={breakdownFilters}
pageResetKey={pageResetKey}
refreshKey={refreshKey}
/>
+22 -30
View File
@@ -158,27 +158,32 @@ const StorageTab: React.FC = () => {
fetchData: fetchChartData
} = useQueryStorageBreakdown({ key: 'storageBreakdownChart' });
// Single source of truth for the active filter set — memoized so its
// reference only changes when a selection changes (an inline object would
// refire the extra tab's fetch effect on every render), and shared by both
// the chart request and the enterprise extra tab (no duplicated spread).
const breakdownFilters = useMemo(
() => ({
...(selectedUsers.length ? { creator_ids: selectedUsers } : {}),
...(selectedVolumes.length ? { volume_ids: selectedVolumes } : {}),
...(selectedOrganizations.length
? { organization_ids: selectedOrganizations }
: {}),
...(selectedUserGroups.length
? { 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:
selectedUsers.length ||
selectedVolumes.length ||
selectedOrganizations.length ||
selectedUserGroups.length
? {
...(selectedUsers.length ? { creator_ids: selectedUsers } : {}),
...(selectedVolumes.length ? { volume_ids: selectedVolumes } : {}),
...(selectedOrganizations.length
? { organization_ids: selectedOrganizations }
: {}),
...(selectedUserGroups.length
? { user_group_ids: selectedUserGroups }
: {})
}
: undefined,
filters: Object.keys(breakdownFilters).length
? breakdownFilters
: undefined,
page: 1,
perPage: 50
});
@@ -516,20 +521,7 @@ const StorageTab: React.FC = () => {
tab="storage"
dateRange={dateRange}
scope={scope}
filters={{
...(selectedUsers.length
? { creator_ids: selectedUsers }
: {}),
...(selectedVolumes.length
? { volume_ids: selectedVolumes }
: {}),
...(selectedOrganizations.length
? { organization_ids: selectedOrganizations }
: {}),
...(selectedUserGroups.length
? { user_group_ids: selectedUserGroups }
: {})
}}
filters={breakdownFilters}
pageResetKey={pageResetKey}
refreshKey={refreshKey}
/>