mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-17 01:17:29 +02:00
feat: search by lifecycle stage (#9705)
This commit is contained in:
parent
5ed3041b11
commit
588e35e759
@ -101,6 +101,7 @@ export default class FeatureSearchController extends Controller {
|
||||
createdBy,
|
||||
state,
|
||||
status,
|
||||
lifecycle,
|
||||
favoritesFirst,
|
||||
archived,
|
||||
sortBy,
|
||||
@ -144,6 +145,7 @@ export default class FeatureSearchController extends Controller {
|
||||
createdAt,
|
||||
createdBy,
|
||||
sortBy,
|
||||
lifecycle,
|
||||
status: normalizedStatus,
|
||||
offset: normalizedOffset,
|
||||
limit: normalizedLimit,
|
||||
|
@ -15,7 +15,11 @@ import type {
|
||||
IFeatureSearchParams,
|
||||
IQueryParam,
|
||||
} from '../feature-toggle/types/feature-toggle-strategies-store-type';
|
||||
import { applyGenericQueryParams, applySearchFilters } from './search-utils';
|
||||
import {
|
||||
applyGenericQueryParams,
|
||||
applySearchFilters,
|
||||
parseSearchOperatorValue,
|
||||
} from './search-utils';
|
||||
import type { FeatureSearchEnvironmentSchema } from '../../openapi/spec/feature-search-environment-schema';
|
||||
import { generateImageUrl } from '../../util';
|
||||
import Raw = Knex.Raw;
|
||||
@ -100,6 +104,7 @@ class FeatureSearchStore implements IFeatureSearchStore {
|
||||
status,
|
||||
offset,
|
||||
limit,
|
||||
lifecycle,
|
||||
sortOrder,
|
||||
sortBy,
|
||||
archived,
|
||||
@ -327,7 +332,15 @@ class FeatureSearchStore implements IFeatureSearchStore {
|
||||
'ranked_features.feature_name',
|
||||
'lifecycle.stage_feature',
|
||||
);
|
||||
|
||||
if (this.flagResolver.isEnabled('flagsOverviewSearch')) {
|
||||
const parsedLifecycle = lifecycle
|
||||
? parseSearchOperatorValue('lifecycle.latest_stage', lifecycle)
|
||||
: null;
|
||||
if (parsedLifecycle) {
|
||||
applyGenericQueryParams(finalQuery, [parsedLifecycle]);
|
||||
}
|
||||
|
||||
finalQuery
|
||||
.leftJoin(
|
||||
this.db('change_request_events AS cre')
|
||||
|
@ -103,6 +103,22 @@ const searchFeatures = async (
|
||||
.expect(expectedCode);
|
||||
};
|
||||
|
||||
const searchFeaturesWithLifecycle = async (
|
||||
{
|
||||
query = '',
|
||||
project = 'IS:default',
|
||||
archived = 'IS:false',
|
||||
lifecycle = 'IS:initial',
|
||||
}: FeatureSearchQueryParameters,
|
||||
expectedCode = 200,
|
||||
) => {
|
||||
return app.request
|
||||
.get(
|
||||
`/api/admin/search/features?query=${query}&project=${project}&archived=${archived}&lifecycle=${lifecycle}`,
|
||||
)
|
||||
.expect(expectedCode);
|
||||
};
|
||||
|
||||
const sortFeatures = async (
|
||||
{
|
||||
sortBy = '',
|
||||
@ -1130,10 +1146,10 @@ test('should return environment usage metrics and lifecycle', async () => {
|
||||
{ feature: 'my_feature_b', stage: 'completed', status: 'discarded' },
|
||||
]);
|
||||
|
||||
const { body } = await searchFeatures({
|
||||
const { body: noExplicitLifecycle } = await searchFeatures({
|
||||
query: 'my_feature_b',
|
||||
});
|
||||
expect(body).toMatchObject({
|
||||
expect(noExplicitLifecycle).toMatchObject({
|
||||
features: [
|
||||
{
|
||||
name: 'my_feature_b',
|
||||
@ -1158,6 +1174,22 @@ test('should return environment usage metrics and lifecycle', async () => {
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { body: noFeaturesWithOtherLifecycle } =
|
||||
await searchFeaturesWithLifecycle({
|
||||
query: 'my_feature_b',
|
||||
lifecycle: 'IS:initial',
|
||||
});
|
||||
expect(noFeaturesWithOtherLifecycle).toMatchObject({ features: [] });
|
||||
|
||||
const { body: featureWithMatchingLifecycle } =
|
||||
await searchFeaturesWithLifecycle({
|
||||
query: 'my_feature_b',
|
||||
lifecycle: 'IS:completed',
|
||||
});
|
||||
expect(featureWithMatchingLifecycle).toMatchObject({
|
||||
features: [{ name: 'my_feature_b' }],
|
||||
});
|
||||
});
|
||||
|
||||
test('should return dependencyType', async () => {
|
||||
|
@ -30,6 +30,7 @@ export interface IFeatureSearchParams {
|
||||
state?: string;
|
||||
type?: string;
|
||||
tag?: string;
|
||||
lifecycle?: string;
|
||||
status?: string[][];
|
||||
offset: number;
|
||||
favoritesFirst?: boolean;
|
||||
|
@ -34,6 +34,18 @@ export const featureSearchQueryParameters = [
|
||||
'The state of the feature active/stale. The state can be specified with an operator. The supported operators are IS, IS_NOT, IS_ANY_OF, IS_NONE_OF.',
|
||||
in: 'query',
|
||||
},
|
||||
{
|
||||
name: 'lifecycle',
|
||||
schema: {
|
||||
type: 'string',
|
||||
example: 'IS:initial',
|
||||
pattern:
|
||||
'^(IS|IS_NOT|IS_ANY_OF|IS_NONE_OF):(.*?)(,([a-zA-Z0-9_]+))*$',
|
||||
},
|
||||
description:
|
||||
'The lifecycle stage of the feature. The stagee can be specified with an operator. The supported operators are IS, IS_NOT, IS_ANY_OF, IS_NONE_OF.',
|
||||
in: 'query',
|
||||
},
|
||||
{
|
||||
name: 'type',
|
||||
schema: {
|
||||
|
Loading…
Reference in New Issue
Block a user