1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-23 00:22:19 +01:00

feat: archived features can be searched now (#8568)

Archived features can be searched now.
This is the backend and small parts of frontend preparing to add
filters, buttons etc in next PR.

---------

Co-authored-by: Thomas Heartman <thomas@getunleash.io>
This commit is contained in:
Jaanus Sellin 2024-10-29 13:19:13 +02:00 committed by GitHub
parent 30c14ff995
commit 28e062b5cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 62 additions and 4 deletions

View File

@ -92,6 +92,7 @@ export const ProjectFeatureToggles = ({
type: tableState.type,
state: tableState.state,
createdBy: tableState.createdBy,
archived: tableState.archived,
};
const { favorite, unfavorite } = useFavoriteFeaturesApi();

View File

@ -40,6 +40,7 @@ export const useProjectFeatureSearch = (
createdAt: FilterItemParam,
type: FilterItemParam,
createdBy: FilterItemParam,
archived: FilterItemParam,
};
const [tableState, setTableState] = usePersistentTableState(
`${storageKey}-${projectId}`,

View File

@ -102,6 +102,7 @@ export default class FeatureSearchController extends Controller {
state,
status,
favoritesFirst,
archived,
sortBy,
} = req.query;
const userId = req.user.id;
@ -131,6 +132,7 @@ export default class FeatureSearchController extends Controller {
['enabled', 'disabled'].includes(tag[1]),
);
const normalizedFavoritesFirst = favoritesFirst === 'true';
const normalizedArchived = archived === 'IS:true';
const { features, total } = await this.featureSearchService.search({
searchParams: normalizedQuery,
project,
@ -147,6 +149,7 @@ export default class FeatureSearchController extends Controller {
limit: normalizedLimit,
sortOrder: normalizedSortOrder,
favoritesFirst: normalizedFavoritesFirst,
archived: normalizedArchived,
});
this.openApiService.respondWithValidation(

View File

@ -101,6 +101,7 @@ class FeatureSearchStore implements IFeatureSearchStore {
limit,
sortOrder,
sortBy,
archived,
favoritesFirst,
}: IFeatureSearchParams,
queryParams: IQueryParam[],
@ -188,9 +189,8 @@ class FeatureSearchStore implements IFeatureSearchStore {
}
});
}
query
.modify(FeatureToggleStore.filterByArchived, false)
.modify(FeatureToggleStore.filterByArchived, archived)
.leftJoin(
'feature_environments',
'feature_environments.feature_name',

View File

@ -57,16 +57,23 @@ afterAll(async () => {
});
beforeEach(async () => {
await db.stores.dependentFeaturesStore.deleteAll();
await db.stores.featureToggleStore.deleteAll();
await db.stores.segmentStore.deleteAll();
});
const searchFeatures = async (
{ query = '', project = 'IS:default' }: FeatureSearchQueryParameters,
{
query = '',
project = 'IS:default',
archived = 'IS:false',
}: FeatureSearchQueryParameters,
expectedCode = 200,
) => {
return app.request
.get(`/api/admin/search/features?query=${query}&project=${project}`)
.get(
`/api/admin/search/features?query=${query}&project=${project}&archived=${archived}`,
)
.expect(expectedCode);
};
@ -1128,3 +1135,38 @@ test('should return dependencyType', async () => {
],
});
});
test('should return archived when query param set', async () => {
await app.createFeature({
name: 'my_feature_a',
createdAt: '2023-01-29T15:21:39.975Z',
});
await app.createFeature({
name: 'my_feature_b',
createdAt: '2023-01-29T15:21:39.975Z',
archived: true,
});
const { body } = await searchFeatures({
query: 'my_feature',
});
expect(body).toMatchObject({
features: [
{
name: 'my_feature_a',
},
],
});
const { body: archivedFeatures } = await searchFeatures({
query: 'my_feature',
archived: 'IS:true',
});
expect(archivedFeatures).toMatchObject({
features: [
{
name: 'my_feature_b',
},
],
});
});

View File

@ -33,6 +33,7 @@ export interface IFeatureSearchParams {
status?: string[][];
offset: number;
favoritesFirst?: boolean;
archived?: boolean;
limit: number;
sortBy?: string;
sortOrder: 'asc' | 'desc';

View File

@ -146,6 +146,16 @@ export const featureSearchQueryParameters = [
'The flag to indicate if the favorite features should be returned first. By default it is set to false.',
in: 'query',
},
{
name: 'archived',
schema: {
type: 'string',
example: 'IS:true',
},
description:
'Whether to get results for archived feature flags or active feature flags. If `true`, Unleash will return only archived flags. If `false`, it will return only active flags.',
in: 'query',
},
{
name: 'createdAt',
schema: {