mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-18 00:19:49 +01:00
feat: dependant flag on feature search (#6684)
This commit is contained in:
parent
d4f52cdb54
commit
283a8f4d8b
@ -137,6 +137,11 @@ class FeatureSearchStore implements IFeatureSearchStore {
|
|||||||
this.db.raw(
|
this.db.raw(
|
||||||
'EXISTS (SELECT 1 FROM feature_strategies WHERE feature_strategies.feature_name = features.name AND feature_strategies.environment = feature_environments.environment AND (feature_strategies.disabled IS NULL OR feature_strategies.disabled = false)) as has_enabled_strategies',
|
'EXISTS (SELECT 1 FROM feature_strategies WHERE feature_strategies.feature_name = features.name AND feature_strategies.environment = feature_environments.environment AND (feature_strategies.disabled IS NULL OR feature_strategies.disabled = false)) as has_enabled_strategies',
|
||||||
),
|
),
|
||||||
|
this.db.raw(`CASE
|
||||||
|
WHEN dependent_features.parent = features.name THEN 'parent'
|
||||||
|
WHEN dependent_features.child = features.name THEN 'child'
|
||||||
|
ELSE null
|
||||||
|
END AS dependency`),
|
||||||
];
|
];
|
||||||
|
|
||||||
applyQueryParams(query, queryParams);
|
applyQueryParams(query, queryParams);
|
||||||
@ -197,6 +202,17 @@ class FeatureSearchStore implements IFeatureSearchStore {
|
|||||||
'feature_strategy_segment.segment_id',
|
'feature_strategy_segment.segment_id',
|
||||||
'segments.id',
|
'segments.id',
|
||||||
)
|
)
|
||||||
|
.leftJoin('dependent_features', (qb) => {
|
||||||
|
qb.on(
|
||||||
|
'dependent_features.parent',
|
||||||
|
'=',
|
||||||
|
'features.name',
|
||||||
|
).orOn(
|
||||||
|
'dependent_features.child',
|
||||||
|
'=',
|
||||||
|
'features.name',
|
||||||
|
);
|
||||||
|
})
|
||||||
.leftJoin('client_metrics_env', (qb) => {
|
.leftJoin('client_metrics_env', (qb) => {
|
||||||
qb.on(
|
qb.on(
|
||||||
'client_metrics_env.environment',
|
'client_metrics_env.environment',
|
||||||
@ -335,6 +351,7 @@ class FeatureSearchStore implements IFeatureSearchStore {
|
|||||||
stale: row.stale,
|
stale: row.stale,
|
||||||
impressionData: row.impression_data,
|
impressionData: row.impression_data,
|
||||||
lastSeenAt: row.last_seen_at,
|
lastSeenAt: row.last_seen_at,
|
||||||
|
dependencyType: row.dependency,
|
||||||
environments: [],
|
environments: [],
|
||||||
segments: row.segment_name ? [row.segment_name] : [],
|
segments: row.segment_name ? [row.segment_name] : [],
|
||||||
};
|
};
|
||||||
|
@ -977,3 +977,57 @@ test('should return environment usage metrics', async () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should return dependencyType', 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',
|
||||||
|
});
|
||||||
|
await app.createFeature({
|
||||||
|
name: 'my_feature_c',
|
||||||
|
createdAt: '2023-01-29T15:21:39.975Z',
|
||||||
|
});
|
||||||
|
await app.createFeature({
|
||||||
|
name: 'my_feature_d',
|
||||||
|
createdAt: '2023-01-29T15:21:39.975Z',
|
||||||
|
});
|
||||||
|
|
||||||
|
await stores.dependentFeaturesStore.upsert({
|
||||||
|
child: 'my_feature_b',
|
||||||
|
parent: 'my_feature_a',
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
await stores.dependentFeaturesStore.upsert({
|
||||||
|
child: 'my_feature_c',
|
||||||
|
parent: 'my_feature_a',
|
||||||
|
enabled: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { body } = await searchFeatures({
|
||||||
|
query: 'my_feature',
|
||||||
|
});
|
||||||
|
expect(body).toMatchObject({
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
name: 'my_feature_a',
|
||||||
|
dependencyType: 'parent',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'my_feature_b',
|
||||||
|
dependencyType: 'child',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'my_feature_c',
|
||||||
|
dependencyType: 'child',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'my_feature_d',
|
||||||
|
dependencyType: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -12,7 +12,18 @@ export const featureSearchResponseSchema = {
|
|||||||
$id: '#/components/schemas/featureSearchResponseSchema',
|
$id: '#/components/schemas/featureSearchResponseSchema',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ['name'],
|
required: [
|
||||||
|
'name',
|
||||||
|
'dependencyType',
|
||||||
|
'type',
|
||||||
|
'project',
|
||||||
|
'stale',
|
||||||
|
'favorite',
|
||||||
|
'impressionData',
|
||||||
|
'createdAt',
|
||||||
|
'environments',
|
||||||
|
'segments',
|
||||||
|
],
|
||||||
description: 'A feature toggle definition',
|
description: 'A feature toggle definition',
|
||||||
properties: {
|
properties: {
|
||||||
name: {
|
name: {
|
||||||
@ -33,6 +44,14 @@ export const featureSearchResponseSchema = {
|
|||||||
'Controls disabling of the comments section in case of an incident',
|
'Controls disabling of the comments section in case of an incident',
|
||||||
description: 'Detailed description of the feature',
|
description: 'Detailed description of the feature',
|
||||||
},
|
},
|
||||||
|
dependencyType: {
|
||||||
|
type: 'string',
|
||||||
|
enum: ['parent', 'child', null],
|
||||||
|
nullable: true,
|
||||||
|
example: 'parent',
|
||||||
|
description:
|
||||||
|
"The type of dependency. 'parent' means that the feature is a parent feature, 'child' means that the feature is a child feature.",
|
||||||
|
},
|
||||||
archived: {
|
archived: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
example: true,
|
example: true,
|
||||||
@ -43,11 +62,6 @@ export const featureSearchResponseSchema = {
|
|||||||
example: 'dx-squad',
|
example: 'dx-squad',
|
||||||
description: 'Name of the project the feature belongs to',
|
description: 'Name of the project the feature belongs to',
|
||||||
},
|
},
|
||||||
enabled: {
|
|
||||||
type: 'boolean',
|
|
||||||
example: true,
|
|
||||||
description: '`true` if the feature is enabled, otherwise `false`.',
|
|
||||||
},
|
|
||||||
stale: {
|
stale: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
example: false,
|
example: false,
|
||||||
@ -129,47 +143,6 @@ export const featureSearchResponseSchema = {
|
|||||||
nullable: true,
|
nullable: true,
|
||||||
description: 'The list of feature tags',
|
description: 'The list of feature tags',
|
||||||
},
|
},
|
||||||
children: {
|
|
||||||
type: 'array',
|
|
||||||
description:
|
|
||||||
'The list of child feature names. This is an experimental field and may change.',
|
|
||||||
items: {
|
|
||||||
type: 'string',
|
|
||||||
example: 'some-feature',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dependencies: {
|
|
||||||
type: 'array',
|
|
||||||
items: {
|
|
||||||
type: 'object',
|
|
||||||
additionalProperties: false,
|
|
||||||
required: ['feature'],
|
|
||||||
properties: {
|
|
||||||
feature: {
|
|
||||||
description: 'The name of the parent feature',
|
|
||||||
type: 'string',
|
|
||||||
example: 'some-feature',
|
|
||||||
},
|
|
||||||
enabled: {
|
|
||||||
description:
|
|
||||||
'Whether the parent feature is enabled or not',
|
|
||||||
type: 'boolean',
|
|
||||||
example: true,
|
|
||||||
},
|
|
||||||
variants: {
|
|
||||||
description:
|
|
||||||
'The list of variants the parent feature should resolve to. Only valid when feature is enabled.',
|
|
||||||
type: 'array',
|
|
||||||
items: {
|
|
||||||
example: 'some-feature-blue-variant',
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description:
|
|
||||||
'The list of parent dependencies. This is an experimental field and may change.',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
schemas: {
|
schemas: {
|
||||||
|
@ -223,6 +223,7 @@ export type IFeatureSearchOverview = Exclude<
|
|||||||
IFeatureOverview,
|
IFeatureOverview,
|
||||||
'environments'
|
'environments'
|
||||||
> & {
|
> & {
|
||||||
|
dependencyType: 'parent' | 'child' | null;
|
||||||
environments: FeatureSearchEnvironmentSchema[];
|
environments: FeatureSearchEnvironmentSchema[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user