Skip to content

Commit 362a9f8

Browse files
authored
refactor: Prevent duplicate features list GETS (#6927)
1 parent 0d68a05 commit 362a9f8

File tree

5 files changed

+24
-31
lines changed

5 files changed

+24
-31
lines changed

frontend/common/stores/feature-list-store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ const controller = {
854854
store.projectId = projectId
855855
store.environmentId = environmentId
856856
store.page = page
857-
store.filter = filter
857+
store.filter = filter || {}
858858
let filterUrl = ''
859859
const { feature } = Utils.fromParam()
860860
if (Object.keys(store.filter).length) {

frontend/common/utils/featureFilterParams.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,6 @@ export function getFiltersFromParams(
169169
? TagStrategy.UNION
170170
: TagStrategy.INTERSECTION,
171171
tags: parseIntArray(params.tags),
172-
value_search: parseStringParam(params.value_search, '') || null,
172+
value_search: parseStringParam(params.value_search, ''),
173173
}
174174
}

frontend/web/components/PanelSearch.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,15 +307,16 @@ const PanelSearch = <T,>(props: PanelSearchProps<T>): ReactElement => {
307307
<div
308308
id={props.id}
309309
className={classNames('search-list', props.listClassName)}
310-
style={isLoading ? { opacity: 0.5 } : {}}
311310
>
312311
{props.header}
313312
{isLoading && (!filteredItems || !items) ? (
314313
<div className='text-center'>
315314
<Loader />
316315
</div>
317316
) : filteredItems && filteredItems.length ? (
318-
renderContainer(filteredItems)
317+
<div style={isLoading ? { opacity: 0.5 } : undefined}>
318+
{renderContainer(filteredItems)}
319+
</div>
319320
) : renderNoResults && !search ? (
320321
renderNoResults
321322
) : (

frontend/web/components/pages/features/FeaturesPage.tsx

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { FC, useCallback, useEffect, useMemo } from 'react'
2+
import cloneDeep from 'lodash/cloneDeep'
23
import { useHistory } from 'react-router-dom'
34
import CreateFlagModal from 'components/modals/create-feature'
45
import Constants from 'common/constants'
@@ -87,8 +88,9 @@ const FeaturesPage: FC<FeaturesPageProps> = ({
8788
getEnvironment,
8889
project,
8990
} = useProjectEnvironments(projectId)
90-
const { data, error, isFetching, isLoading, refetch } =
91+
const { currentData, data, error, isFetching, isLoading, refetch } =
9192
useFeatureListWithApiKey(effectiveFilters, page, environmentId, projectId)
93+
const isDataStale = !!data && !currentData
9294

9395
// Backward compatibility: Populate ProjectStore for legacy components (CreateFlag)
9496
// TODO: Remove this when CreateFlag is migrated to RTK Query
@@ -98,31 +100,21 @@ const FeaturesPage: FC<FeaturesPageProps> = ({
98100
}
99101
}, [projectId])
100102

101-
// Backward compatibility: Populate FeatureListStore for legacy components (CreateFlag modal)
102-
// Must pass current filters/search/page so FeatureListStore contains the same features
103-
// that RTK Query displays. Otherwise editing features will crash because they're not in the store.
104-
// TODO: Remove this when CreateFlag is migrated to RTK Query
105103
useEffect(() => {
106-
if (projectId && environmentId) {
107-
AppActions.getFeatures(
108-
projectId,
109-
environmentId,
110-
true,
111-
effectiveFilters.search,
112-
effectiveFilters.sort,
113-
page,
114-
{
115-
group_owners: effectiveFilters.group_owners?.join(',') || undefined,
116-
is_archived: effectiveFilters.showArchived,
117-
is_enabled: effectiveFilters.is_enabled,
118-
owners: effectiveFilters.owners?.join(',') || undefined,
119-
tag_strategy: effectiveFilters.tag_strategy,
120-
tags: effectiveFilters.tags?.join(',') || undefined,
121-
value_search: effectiveFilters.value_search,
122-
},
123-
)
104+
if (data && environmentId) {
105+
// TODO: Remove this when CreateFlag is migrated to RTK Query
106+
// This currently avoids duplicate api calls
107+
FeatureListStore.envId = environmentId
108+
FeatureListStore.projectId = projectId
109+
FeatureListStore.environmentId = environmentId
110+
FeatureListStore.model = {
111+
features: cloneDeep(data.results),
112+
keyedEnvironmentFeatures: cloneDeep(data.environmentStates),
113+
}
114+
FeatureListStore.paging = { ...data.pagination }
115+
FeatureListStore.loaded()
124116
}
125-
}, [projectId, environmentId, page, effectiveFilters])
117+
}, [data, environmentId, projectId])
126118

127119
// Force re-fetch when legacy Flux store updates features
128120
// TODO: Remove when all feature mutations use RTK Query
@@ -317,7 +309,7 @@ const FeaturesPage: FC<FeaturesPageProps> = ({
317309
id='features-list'
318310
renderSearchWithNoResults
319311
itemHeight={65}
320-
isLoading={isLoading}
312+
isLoading={isLoading || isDataStale}
321313
paging={paging}
322314
header={renderHeader()}
323315
nextPage={handleNextPage}

frontend/web/components/tables/TableValueFilter.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { FC, useEffect, useMemo, useRef, useState } from 'react'
1+
import React, { FC, useEffect } from 'react'
22
import TableFilter from './TableFilter'
33
import Utils from 'common/utils/utils'
44
import InputGroup from 'components/base/forms/InputGroup'
@@ -38,7 +38,7 @@ const TableTagFilter: FC<TableFilterType> = ({
3838
value?.valueSearch || '',
3939
)
4040
useEffect(() => {
41-
if (search !== value.valueSearch) {
41+
if ((search || '') !== (value.valueSearch || '')) {
4242
onChange({
4343
enabled: value.enabled,
4444
valueSearch: search,

0 commit comments

Comments
 (0)