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:
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user