diff --git a/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx b/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx index 34433643fb..280e2e8f71 100644 --- a/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx +++ b/frontend/src/component/common/StrategyItemContainer/StrategyItemContainer.tsx @@ -9,6 +9,7 @@ import { import StringTruncator from 'component/common/StringTruncator/StringTruncator'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PlaygroundStrategySchema } from 'openapi'; +import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; interface IStrategyItemContainerProps { strategy: IFeatureStrategy | PlaygroundStrategySchema; @@ -69,6 +70,7 @@ export const StrategyItemContainer: FC = ({ style = {}, }) => { const Icon = getFeatureStrategyIcon(strategy.name); + const { uiConfig } = useUiConfig(); return ( @@ -105,7 +107,11 @@ export const StrategyItemContainer: FC = ({ { const projectId = useRequiredPathParam('projectId'); @@ -52,6 +53,7 @@ export const FeatureStrategyCreate = () => { const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId); const { refetch: refetchChangeRequests } = usePendingChangeRequests(projectId); + const { trackEvent } = usePlausibleTracker(); const { data, staleDataNotification, forceRefreshCache } = useCollaborateData( @@ -115,6 +117,13 @@ export const FeatureStrategyCreate = () => { const onSubmit = async () => { const payload = createStrategyPayload(strategy, segments); + trackEvent('strategyTitle', { + props: { + hasTitle: Boolean(strategy.title), + on: 'create', + }, + }); + try { if (isChangeRequestConfigured(environmentId)) { await onStrategyRequestAdd(payload); diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit.tsx index 872bfd538c..18febe0d87 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyEdit/FeatureStrategyEdit.tsx @@ -27,6 +27,7 @@ import { comparisonModerator } from '../featureStrategy.utils'; import { useChangeRequestsEnabled } from 'hooks/useChangeRequestsEnabled'; import { useChangeRequestApi } from 'hooks/api/actions/useChangeRequestApi/useChangeRequestApi'; import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests'; +import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; export const FeatureStrategyEdit = () => { const projectId = useRequiredPathParam('projectId'); @@ -47,6 +48,7 @@ export const FeatureStrategyEdit = () => { const { isChangeRequestConfigured } = useChangeRequestsEnabled(projectId); const { refetch: refetchChangeRequests } = usePendingChangeRequests(projectId); + const { trackEvent } = usePlausibleTracker(); const { feature, refetchFeature } = useFeature(projectId, featureId); @@ -101,6 +103,13 @@ export const FeatureStrategyEdit = () => { payload ); + trackEvent('strategyTitle', { + props: { + hasTitle: Boolean(strategy.title), + on: 'edit', + }, + }); + await refetchSavedStrategySegments(); setToastData({ title: 'Strategy updated', @@ -189,6 +198,7 @@ export const createStrategyPayload = ( segments: ISegment[] ): IFeatureStrategyPayload => ({ name: strategy.name, + title: strategy.title, constraints: strategy.constraints ?? [], parameters: strategy.parameters ?? {}, segments: segments.map(segment => segment.id), diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx index 6d08442831..41b8ff50ac 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx @@ -29,6 +29,7 @@ import { formatFeaturePath } from '../FeatureStrategyEdit/FeatureStrategyEdit'; import { useChangeRequestInReviewWarning } from 'hooks/useChangeRequestInReviewWarning'; import { usePendingChangeRequests } from 'hooks/api/getters/usePendingChangeRequests/usePendingChangeRequests'; import { useHasProjectEnvironmentAccess } from 'hooks/useHasAccess'; +import { FeatureStrategyTitle } from './FeatureStrategyTitle/FeatureStrategyTitle'; interface IFeatureStrategyFormProps { feature: IFeatureToggle; @@ -217,6 +218,20 @@ export const FeatureStrategyForm = ({ /> } /> + { + setStrategy(prev => ({ + ...prev, + title, + })); + }} + /> + } + /> void; +} + +export const FeatureStrategyTitle: VFC = ({ + title, + setTitle, +}) => { + const { uiConfig } = useUiConfig(); + + if (!uiConfig.flags.strategyTitle) { + return null; + } + + return ( + theme.spacing(2) }}> + theme.spacing(2), + }} + > + What would you like to call this strategy? (optional) + + setTitle(e.target.value)} + sx={{ width: '100%' }} + /> + + ); +}; diff --git a/frontend/src/hooks/usePlausibleTracker.ts b/frontend/src/hooks/usePlausibleTracker.ts index 63a1c92c88..8e876cbeb9 100644 --- a/frontend/src/hooks/usePlausibleTracker.ts +++ b/frontend/src/hooks/usePlausibleTracker.ts @@ -23,7 +23,8 @@ export type CustomEvents = | 'project_api_tokens' | 'project_stickiness_set' | 'notifications' - | 'batch_operations'; + | 'batch_operations' + | 'strategyTitle'; export const usePlausibleTracker = () => { const plausible = useContext(PlausibleContext); diff --git a/frontend/src/interfaces/strategy.ts b/frontend/src/interfaces/strategy.ts index 6d8f3428cc..08b828263f 100644 --- a/frontend/src/interfaces/strategy.ts +++ b/frontend/src/interfaces/strategy.ts @@ -4,6 +4,7 @@ export interface IFeatureStrategy { id: string; strategyName?: string; name: string; + title?: string; constraints: IConstraint[]; parameters: IFeatureStrategyParameters; featureName?: string; @@ -19,6 +20,7 @@ export interface IFeatureStrategyParameters { export interface IFeatureStrategyPayload { id?: string; name?: string; + title?: string; constraints: IConstraint[]; parameters: IFeatureStrategyParameters; segments?: number[]; diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index fd65018443..6a1adf4d2a 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -52,6 +52,7 @@ export interface IFlags { projectScopedStickiness?: boolean; personalAccessTokensKillSwitch?: boolean; demo?: boolean; + strategyTitle?: boolean; } export interface IVersionInfo { diff --git a/frontend/src/openapi/models/_exportParams.ts b/frontend/src/openapi/models/_exportParams.ts index ee909b078d..1027979bdb 100644 --- a/frontend/src/openapi/models/_exportParams.ts +++ b/frontend/src/openapi/models/_exportParams.ts @@ -6,32 +6,11 @@ import type { _ExportFormat } from './_exportFormat'; export type _ExportParams = { - /** - * Desired export format. Must be either `json` or `yaml`. - */ format?: _ExportFormat; - /** - * Whether exported data should be downloaded as a file. - */ - download?: string; - /** - * Whether strategies should be included in the exported data. - */ + download?: boolean | string | number; strategies?: boolean | string | number; - /** - * Whether feature toggles should be included in the exported data. - */ featureToggles?: boolean | string | number; - /** - * Whether projects should be included in the exported data. - */ projects?: boolean | string | number; - /** - * Whether tag types, tags, and feature_tags should be included in the exported data. - */ tags?: boolean | string | number; - /** - * Whether environments should be included in the exported data. - */ environments?: boolean | string | number; }; diff --git a/frontend/src/openapi/models/addonCreateUpdateSchema.ts b/frontend/src/openapi/models/addonCreateUpdateSchema.ts new file mode 100644 index 0000000000..7e4f190d27 --- /dev/null +++ b/frontend/src/openapi/models/addonCreateUpdateSchema.ts @@ -0,0 +1,37 @@ +/** + * Generated by Orval + * Do not edit manually. + * See `gen:api` script in package.json + */ +import type { AddonCreateUpdateSchemaParameters } from './addonCreateUpdateSchemaParameters'; + +/** + * Data required to create or update an [Unleash addon](https://docs.getunleash.io/reference/addons) instance. + */ +export interface AddonCreateUpdateSchema { + /** The addon provider, such as "webhook" or "slack". This string is **case sensitive** and maps to the provider's `name` property. + +The list of all supported providers and their parameters for a specific Unleash instance can be found by making a GET request to the `api/admin/addons` endpoint: the `providers` property of that response will contain all available providers. + +The default set of providers can be found in the [addons reference documentation](https://docs.getunleash.io/reference/addons). The default supported options are: +- `datadog` for [Datadog](https://docs.getunleash.io/reference/addons/datadog) +- `slack` for [Slack](https://docs.getunleash.io/reference/addons/slack) +- `teams` for [Microsoft Teams](https://docs.getunleash.io/reference/addons/teams) +- `webhook` for [webhooks](https://docs.getunleash.io/reference/addons/webhook) + +The provider you choose for your addon dictates what properties the `parameters` object needs. Refer to the documentation for each provider for more information. + */ + provider: string; + /** A description of the addon. */ + description?: string; + /** Whether the addon should be enabled or not. */ + enabled: boolean; + /** Parameters for the addon provider. This object has different required and optional properties depending on the provider you choose. Consult the documentation for details. */ + parameters: AddonCreateUpdateSchemaParameters; + /** The event types that will trigger this specific addon. */ + events: string[]; + /** The projects that this addon will listen to events from. An empty list means it will listen to events from **all** projects. */ + projects?: string[]; + /** The list of environments that this addon will listen to events from. An empty list means it will listen to events from **all** environments. */ + environments?: string[]; +} diff --git a/frontend/src/openapi/models/addonCreateUpdateSchemaParameters.ts b/frontend/src/openapi/models/addonCreateUpdateSchemaParameters.ts new file mode 100644 index 0000000000..0eb5da8946 --- /dev/null +++ b/frontend/src/openapi/models/addonCreateUpdateSchemaParameters.ts @@ -0,0 +1,10 @@ +/** + * Generated by Orval + * Do not edit manually. + * See `gen:api` script in package.json + */ + +/** + * Parameters for the addon provider. This object has different required and optional properties depending on the provider you choose. Consult the documentation for details. + */ +export type AddonCreateUpdateSchemaParameters = { [key: string]: unknown }; diff --git a/frontend/src/openapi/models/addonParameterSchema.ts b/frontend/src/openapi/models/addonParameterSchema.ts index 2520437871..d316fcf483 100644 --- a/frontend/src/openapi/models/addonParameterSchema.ts +++ b/frontend/src/openapi/models/addonParameterSchema.ts @@ -4,12 +4,22 @@ * See `gen:api` script in package.json */ +/** + * An addon parameter definition. + */ export interface AddonParameterSchema { + /** The name of the parameter as it is used in code. References to this parameter should use this value. */ name: string; + /** The name of the parameter as it is shown to the end user in the Admin UI. */ displayName: string; + /** The type of the parameter. Corresponds roughly to [HTML `input` field types](https://developer.mozilla.org/docs/Web/HTML/Element/Input#input_types). Multi-line inut fields are indicated as `textfield` (equivalent to the HTML `textarea` tag). */ type: string; + /** A description of the parameter. This should explain to the end user what the parameter is used for. */ description?: string; + /** The default value for this parameter. This value is used if no other value is provided. */ placeholder?: string; + /** Whether this parameter is required or not. If a parameter is required, you must give it a value when you create the addon. If it is not required it can be left out. It may receive a default value in those cases. */ required: boolean; + /** Indicates whether this parameter is **sensitive** or not. Unleash will not return sensitive parameters to API requests. It will instead use a number of asterisks to indicate that a value is set, e.g. "******". The number of asterisks does not correlate to the parameter's value. */ sensitive: boolean; } diff --git a/frontend/src/openapi/models/addonSchema.ts b/frontend/src/openapi/models/addonSchema.ts index 18223db893..71c2fcec96 100644 --- a/frontend/src/openapi/models/addonSchema.ts +++ b/frontend/src/openapi/models/addonSchema.ts @@ -5,14 +5,24 @@ */ import type { AddonSchemaParameters } from './addonSchemaParameters'; +/** + * An [addon](https://docs.getunleash.io/reference/addons) instance description. Contains data about what kind of provider it uses, whether it's enabled or not, what events it listens for, and more. + */ export interface AddonSchema { - id?: number; - createdAt?: string | null; + /** The addon's unique identifier. */ + id: number; + /** The addon provider, such as "webhook" or "slack". */ provider: string; - description?: string; + /** A description of the addon. `null` if no description exists. */ + description: string | null; + /** Whether the addon is enabled or not. */ enabled: boolean; + /** Parameters for the addon provider. This object has different required and optional properties depending on the provider you choose. */ parameters: AddonSchemaParameters; + /** The event types that trigger this specific addon. */ events: string[]; + /** The projects that this addon listens to events from. An empty list means it listens to events from **all** projects. */ projects?: string[]; + /** The list of environments that this addon listens to events from. An empty list means it listens to events from **all** environments. */ environments?: string[]; } diff --git a/frontend/src/openapi/models/addonSchemaParameters.ts b/frontend/src/openapi/models/addonSchemaParameters.ts index 92fc8ad61b..64c2523892 100644 --- a/frontend/src/openapi/models/addonSchemaParameters.ts +++ b/frontend/src/openapi/models/addonSchemaParameters.ts @@ -4,4 +4,7 @@ * See `gen:api` script in package.json */ -export type AddonSchemaParameters = { [key: string]: any }; +/** + * Parameters for the addon provider. This object has different required and optional properties depending on the provider you choose. + */ +export type AddonSchemaParameters = { [key: string]: unknown }; diff --git a/frontend/src/openapi/models/addonTypeSchema.ts b/frontend/src/openapi/models/addonTypeSchema.ts index f519e6f0be..d238d78a0b 100644 --- a/frontend/src/openapi/models/addonTypeSchema.ts +++ b/frontend/src/openapi/models/addonTypeSchema.ts @@ -6,12 +6,22 @@ import type { TagTypeSchema } from './tagTypeSchema'; import type { AddonParameterSchema } from './addonParameterSchema'; +/** + * An addon provider. Defines a specific addon type and what the end user must configure when creating a new addon of that type. + */ export interface AddonTypeSchema { + /** The name of the addon type. When creating new addons, this goes in the payload's `type` field. */ name: string; + /** The addon type's name as it should be displayed in the admin UI. */ displayName: string; + /** A URL to where you can find more information about using this addon type. */ documentationUrl: string; + /** A description of the addon type. */ description: string; + /** A list of [Unleash tag types](https://docs.getunleash.io/reference/tags#tag-types) that this addon uses. These tags will be added to the Unleash instance when an addon of this type is created. */ tagTypes?: TagTypeSchema[]; + /** The addon provider's parameters. Use these to configure an addon of this provider type. Items with `required: true` must be provided. */ parameters?: AddonParameterSchema[]; + /** All the [event types](https://docs.getunleash.io/reference/api/legacy/unleash/admin/events#feature-toggle-events) that are available for this addon provider. */ events?: string[]; } diff --git a/frontend/src/openapi/models/addonsSchema.ts b/frontend/src/openapi/models/addonsSchema.ts index 5e485cc3ef..fda89d9b87 100644 --- a/frontend/src/openapi/models/addonsSchema.ts +++ b/frontend/src/openapi/models/addonsSchema.ts @@ -6,7 +6,14 @@ import type { AddonSchema } from './addonSchema'; import type { AddonTypeSchema } from './addonTypeSchema'; +/** + * An object containing two things: +1. A list of all [addons](https://docs.getunleash.io/reference/addons) defined on this Unleash instance +2. A list of all addon providers defined on this instance + */ export interface AddonsSchema { + /** All the addons that exist on this instance of Unleash. */ addons: AddonSchema[]; + /** A list of all available addon providers, along with their parameters and descriptions. */ providers: AddonTypeSchema[]; } diff --git a/frontend/src/openapi/models/createFeatureStrategySchema.ts b/frontend/src/openapi/models/createFeatureStrategySchema.ts index f0c584980e..62673c4779 100644 --- a/frontend/src/openapi/models/createFeatureStrategySchema.ts +++ b/frontend/src/openapi/models/createFeatureStrategySchema.ts @@ -7,9 +7,15 @@ import type { ConstraintSchema } from './constraintSchema'; import type { ParametersSchema } from './parametersSchema'; export interface CreateFeatureStrategySchema { + /** The name or type of strategy */ name: string; + /** A descriptive title for the strategy */ + title?: string | null; + /** The order of the strategy in the list */ sortOrder?: number; + /** A list of the constraints attached to the strategy */ constraints?: ConstraintSchema[]; + /** An object containing the parameters for the strategy */ parameters?: ParametersSchema; /** Ids of segments to use for this strategy */ segments?: number[]; diff --git a/frontend/src/openapi/models/featureStrategySchema.ts b/frontend/src/openapi/models/featureStrategySchema.ts index 6d3b848125..e806d49854 100644 --- a/frontend/src/openapi/models/featureStrategySchema.ts +++ b/frontend/src/openapi/models/featureStrategySchema.ts @@ -6,12 +6,23 @@ import type { ConstraintSchema } from './constraintSchema'; import type { ParametersSchema } from './parametersSchema'; +/** + * A singles activation strategy configuration schema for a feature + */ export interface FeatureStrategySchema { + /** A uuid for the feature strategy */ id?: string; + /** The name or type of strategy */ name: string; + /** A descriptive title for the strategy */ + title?: string | null; + /** The name or feature the strategy is attached to */ featureName?: string; + /** The order of the strategy in the list */ sortOrder?: number; + /** A list of segment ids attached to the strategy */ segments?: number[]; + /** A list of the constraints attached to the strategy */ constraints?: ConstraintSchema[]; parameters?: ParametersSchema; } diff --git a/frontend/src/openapi/models/featureTagSchema.ts b/frontend/src/openapi/models/featureTagSchema.ts index cbecd25ffd..1782a61ab4 100644 --- a/frontend/src/openapi/models/featureTagSchema.ts +++ b/frontend/src/openapi/models/featureTagSchema.ts @@ -10,17 +10,17 @@ export interface FeatureTagSchema { /** The name of the feature this tag is applied to */ featureName: string; - /** The type of tag */ + /** The [type](https://docs.getunleash.io/reference/tags#tag-types tag types) of the tag */ tagType?: string; /** The value of the tag */ tagValue: string; /** - * This field is deprecated and currently unused, use tagType instead + * The [type](https://docs.getunleash.io/reference/tags#tag-types tag types) of the tag. This property is deprecated and will be removed in a future version of Unleash. Superseded by the `tagType` property. * @deprecated */ type?: string; /** - * This field is deprecated and currently unused, use tagValue instead + * The value of the tag. This property is deprecated and will be removed in a future version of Unleash. Superseded by the `tagValue` property. * @deprecated */ value?: string; diff --git a/frontend/src/openapi/models/getEventsParams.ts b/frontend/src/openapi/models/getEventsParams.ts index fc7fffc5e1..acfd3765d0 100644 --- a/frontend/src/openapi/models/getEventsParams.ts +++ b/frontend/src/openapi/models/getEventsParams.ts @@ -4,9 +4,4 @@ * See `gen:api` script in package.json */ -export type GetEventsParams = { - /** - * The name of the project whose events you want to retrieve - */ - project?: string; -}; +export type GetEventsParams = { project?: string }; diff --git a/frontend/src/openapi/models/index.ts b/frontend/src/openapi/models/index.ts index 92954c7efb..e46c503777 100644 --- a/frontend/src/openapi/models/index.ts +++ b/frontend/src/openapi/models/index.ts @@ -1,11 +1,7 @@ -/** - * Generated by Orval - * Do not edit manually. - * See `gen:api` script in package.json - */ - export * from './_exportFormat'; export * from './_exportParams'; +export * from './addonCreateUpdateSchema'; +export * from './addonCreateUpdateSchemaParameters'; export * from './addonParameterSchema'; export * from './addonSchema'; export * from './addonSchemaParameters'; diff --git a/frontend/src/openapi/models/playgroundStrategySchema.ts b/frontend/src/openapi/models/playgroundStrategySchema.ts index efded15cbd..1a46fe14db 100644 --- a/frontend/src/openapi/models/playgroundStrategySchema.ts +++ b/frontend/src/openapi/models/playgroundStrategySchema.ts @@ -11,6 +11,8 @@ import type { ParametersSchema } from './parametersSchema'; export interface PlaygroundStrategySchema { /** The strategy's name. */ name: string; + /** Description of the feature's purpose. */ + title?: string; /** The strategy's id. */ id: string; /** The strategy's evaluation result. If the strategy is a custom strategy that Unleash can't evaluate, `evaluationStatus` will be `unknown`. Otherwise, it will be `true` or `false` */ diff --git a/frontend/src/openapi/models/strategySchema.ts b/frontend/src/openapi/models/strategySchema.ts index 43a62d432c..e5e108a18d 100644 --- a/frontend/src/openapi/models/strategySchema.ts +++ b/frontend/src/openapi/models/strategySchema.ts @@ -5,11 +5,21 @@ */ import type { StrategySchemaParametersItem } from './strategySchemaParametersItem'; +/** + * The [activation strategy](https://docs.getunleash.io/reference/activation-strategies) schema + */ export interface StrategySchema { + /** An optional title for the strategy */ + title?: string | null; + /** The name or type of the strategy */ name: string; + /** A human friendly name for the strategy */ displayName: string | null; + /** A short description for the strategy */ description: string; + /** Determines whether the strategy allows for editing */ editable: boolean; deprecated: boolean; + /** A list of relevant parameters for each strategy */ parameters: StrategySchemaParametersItem[]; } diff --git a/frontend/src/openapi/models/tagSchema.ts b/frontend/src/openapi/models/tagSchema.ts index 20c09503de..04aabffe8c 100644 --- a/frontend/src/openapi/models/tagSchema.ts +++ b/frontend/src/openapi/models/tagSchema.ts @@ -5,11 +5,11 @@ */ /** - * Representation of a tag + * Representation of a [tag](https://docs.getunleash.io/reference/tags) */ export interface TagSchema { /** The value of the tag */ value: string; - /** The type of the tag */ + /** The [type](https://docs.getunleash.io/reference/tags#tag-types) of the tag */ type: string; } diff --git a/frontend/src/openapi/models/updateTagsSchema.ts b/frontend/src/openapi/models/updateTagsSchema.ts index d47dbe542d..6364e34d0e 100644 --- a/frontend/src/openapi/models/updateTagsSchema.ts +++ b/frontend/src/openapi/models/updateTagsSchema.ts @@ -6,7 +6,7 @@ import type { TagSchema } from './tagSchema'; /** - * Represents a set of changes to tags of a feature. + * Represents a set of changes to a feature's tags, such as adding or removing tags. */ export interface UpdateTagsSchema { /** Tags to add to the feature. */ diff --git a/src/lib/__snapshots__/create-config.test.ts.snap b/src/lib/__snapshots__/create-config.test.ts.snap index 1cd75cdb24..0b6e3bc1bf 100644 --- a/src/lib/__snapshots__/create-config.test.ts.snap +++ b/src/lib/__snapshots__/create-config.test.ts.snap @@ -89,6 +89,7 @@ exports[`should create default config 1`] = ` "projectScopedSegments": false, "projectScopedStickiness": false, "responseTimeWithAppNameKillSwitch": false, + "strategyTitle": false, "strictSchemaValidation": false, }, }, @@ -116,6 +117,7 @@ exports[`should create default config 1`] = ` "projectScopedSegments": false, "projectScopedStickiness": false, "responseTimeWithAppNameKillSwitch": false, + "strategyTitle": false, "strictSchemaValidation": false, }, "externalResolver": { diff --git a/src/lib/openapi/spec/playground-strategy-schema.ts b/src/lib/openapi/spec/playground-strategy-schema.ts index 09d376f6a8..030ed44249 100644 --- a/src/lib/openapi/spec/playground-strategy-schema.ts +++ b/src/lib/openapi/spec/playground-strategy-schema.ts @@ -66,6 +66,11 @@ export const playgroundStrategySchema = { description: "The strategy's name.", type: 'string', }, + title: { + type: 'string', + example: 'Beta rollout', + description: "Description of the feature's purpose.", + }, id: { description: "The strategy's id.", type: 'string', diff --git a/src/lib/types/experimental.ts b/src/lib/types/experimental.ts index 1a295db68d..35e7ef961f 100644 --- a/src/lib/types/experimental.ts +++ b/src/lib/types/experimental.ts @@ -78,6 +78,10 @@ const flags = { ), migrationLock: parseEnvVarBoolean(process.env.MIGRATION_LOCK, false), demo: parseEnvVarBoolean(process.env.UNLEASH_DEMO, false), + strategyTitle: parseEnvVarBoolean( + process.env.UNLEASH_STRATEGY_TITLE, + false, + ), }; export const defaultExperimentalOptions: IExperimentalOptions = { diff --git a/src/lib/util/feature-evaluator/client.ts b/src/lib/util/feature-evaluator/client.ts index 71210cd81d..49b00f3c51 100644 --- a/src/lib/util/feature-evaluator/client.ts +++ b/src/lib/util/feature-evaluator/client.ts @@ -108,6 +108,7 @@ export default class UnleashClient { return { name: strategySelector.name, id: strategySelector.id, + title: strategySelector.title, parameters: strategySelector.parameters, ...strategy.isEnabledWithConstraints( strategySelector.parameters, diff --git a/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap b/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap index 9dffa12b31..8f404dfa55 100644 --- a/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap +++ b/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap @@ -3297,6 +3297,11 @@ The provider you choose for your addon dictates what properties the \`parameters }, "type": "array", }, + "title": { + "description": "Description of the feature's purpose.", + "example": "Beta rollout", + "type": "string", + }, }, "required": [ "id",