mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
feat: Demo for strategy variants (#4457)
This commit is contained in:
parent
8ee031e978
commit
df41146f50
@ -21,7 +21,7 @@ export const StrategyVariantsPreferredAlert = () => {
|
||||
const DocsSdkSupportLink = () => {
|
||||
return (
|
||||
<a
|
||||
href="https://docs.getunleash.io/reference/feature-strategy-variants#client-sdk-support"
|
||||
href="https://docs.getunleash.io/reference/strategy-variants#client-sdk-support"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
@ -33,7 +33,7 @@ const DocsSdkSupportLink = () => {
|
||||
const DocsLink = () => {
|
||||
return (
|
||||
<a
|
||||
href="https://docs.getunleash.io/reference/feature-strategy-variants"
|
||||
href="https://docs.getunleash.io/reference/strategy-variants"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
@ -28,6 +28,7 @@ const ensureUserIdContextExists = async () => {
|
||||
};
|
||||
|
||||
export const specificUser = async () => {
|
||||
await deleteOldStrategies('demoApp.step2');
|
||||
await ensureUserIdContextExists();
|
||||
};
|
||||
|
||||
@ -67,11 +68,48 @@ export const gradualRollout = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
export const variants = async () => {
|
||||
const featureId = 'demoApp.step4';
|
||||
const deleteStrategy = (featureId: string, strategyId: string) =>
|
||||
fetch(
|
||||
formatApiPath(
|
||||
`api/admin/projects/${PROJECT}/features/${featureId}/environments/${ENVIRONMENT}/strategies/${strategyId}`
|
||||
),
|
||||
{ method: 'DELETE' }
|
||||
);
|
||||
|
||||
await ensureUserIdContextExists();
|
||||
const deleteOldStrategies = async (featureId: string) => {
|
||||
const results = await fetch(
|
||||
formatApiPath(
|
||||
`api/admin/projects/${PROJECT}/features/${featureId}/environments/${ENVIRONMENT}/strategies`
|
||||
)
|
||||
).then(res => res.json());
|
||||
|
||||
const tooGenericStrategies = results.filter(
|
||||
(strategy: { constraints: Array<unknown>; segments: Array<unknown> }) =>
|
||||
strategy.constraints.length === 0 && strategy.segments.length === 0
|
||||
);
|
||||
const constrainedStrategies = results.filter(
|
||||
(strategy: { constraints: Array<unknown>; segments: Array<unknown> }) =>
|
||||
strategy.constraints.length > 0 || strategy.segments.length > 0
|
||||
);
|
||||
await Promise.all(
|
||||
tooGenericStrategies.map((result: { id: string }) =>
|
||||
deleteStrategy(featureId, result.id)
|
||||
)
|
||||
);
|
||||
|
||||
const strategyLimit = 30;
|
||||
if (constrainedStrategies.length > strategyLimit) {
|
||||
await Promise.all(
|
||||
constrainedStrategies
|
||||
.slice(0, strategyLimit - 1)
|
||||
.map((result: { id: string }) =>
|
||||
deleteStrategy(featureId, result.id)
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const ensureDefaultVariants = async (featureId: string) => {
|
||||
const { variants }: IFeatureToggle = await fetch(
|
||||
formatApiPath(
|
||||
`api/admin/projects/${PROJECT}/features/${featureId}?variantEnvironments=true`
|
||||
@ -139,3 +177,9 @@ export const variants = async () => {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const variants = async () => {
|
||||
await deleteOldStrategies('demoApp.step4');
|
||||
await ensureDefaultVariants('demoApp.step4');
|
||||
await ensureUserIdContextExists();
|
||||
};
|
||||
|
@ -461,24 +461,147 @@ export const TOPICS: ITutorialTopic[] = [
|
||||
},
|
||||
{
|
||||
href: `/projects/${PROJECT}/features/demoApp.step4`,
|
||||
target: 'button[data-testid="TAB-Variants"]',
|
||||
content: <Description>Select the "Variants" tab.</Description>,
|
||||
},
|
||||
{
|
||||
target: 'button[data-testid="EDIT_VARIANTS_BUTTON"]',
|
||||
target: `div[data-testid="FEATURE_ENVIRONMENT_ACCORDION_${ENVIRONMENT}"] button`,
|
||||
content: (
|
||||
<Description>
|
||||
Edit the existing variants by using this button.
|
||||
Add a new strategy to this environment by using this
|
||||
button.
|
||||
</Description>
|
||||
),
|
||||
},
|
||||
{
|
||||
target: 'button[data-testid="MODAL_ADD_VARIANT_BUTTON"]',
|
||||
target: 'button[data-testid="ADD_CONSTRAINT_BUTTON"]',
|
||||
content: (
|
||||
<>
|
||||
<Description>
|
||||
<a
|
||||
href="https://docs.getunleash.io/reference/strategy-constraints"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Strategy constraints
|
||||
</a>{' '}
|
||||
are conditions that must be satisfied for an{' '}
|
||||
<a
|
||||
href="https://docs.getunleash.io/reference/activation-strategies"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
activation strategy
|
||||
</a>{' '}
|
||||
to be evaluated for a feature toggle.
|
||||
</Description>
|
||||
<Description sx={{ mt: 1 }}>
|
||||
Add a constraint by using this button.
|
||||
</Description>
|
||||
</>
|
||||
),
|
||||
backCloseModal: true,
|
||||
},
|
||||
{
|
||||
target: '#context-field-select',
|
||||
content: (
|
||||
<>
|
||||
<Description>
|
||||
<a
|
||||
href="https://docs.getunleash.io/reference/unleash-context"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Unleash context
|
||||
</a>{' '}
|
||||
contains information relating to the current feature
|
||||
toggle request.
|
||||
</Description>
|
||||
<Description sx={{ mt: 1 }}>
|
||||
Select the context field by using this dropdown.
|
||||
</Description>
|
||||
</>
|
||||
),
|
||||
backCloseModal: true,
|
||||
anyClick: true,
|
||||
},
|
||||
{
|
||||
target: 'li[data-testid="SELECT_ITEM_ID-userId"]',
|
||||
content: (
|
||||
<Description>
|
||||
Add a new variant to the list by using this button.
|
||||
Select the <Badge as="span">userId</Badge> context
|
||||
field.
|
||||
</Description>
|
||||
),
|
||||
placement: 'right',
|
||||
backCloseModal: true,
|
||||
},
|
||||
{
|
||||
target: 'div[data-testid="CONSTRAINT_VALUES_INPUT"]',
|
||||
content: (
|
||||
<>
|
||||
<Description>
|
||||
Enter your <Badge as="span">userId</Badge>
|
||||
</Description>
|
||||
<Badge
|
||||
sx={{ mt: 2, mb: 1, width: '100%' }}
|
||||
icon={<InfoOutlinedIcon />}
|
||||
>
|
||||
You can find your userId on the demo page.
|
||||
</Badge>
|
||||
<StyledImg
|
||||
src={formatAssetPath(demoUserId)}
|
||||
alt="You can find your userId on the demo page."
|
||||
/>
|
||||
<Description sx={{ mt: 1 }}>
|
||||
When you're done, use the "Next" button in the
|
||||
dialog.
|
||||
</Description>
|
||||
</>
|
||||
),
|
||||
placement: 'right',
|
||||
nextButton: true,
|
||||
focus: 'input',
|
||||
},
|
||||
{
|
||||
target: 'button[data-testid="CONSTRAINT_VALUES_ADD_BUTTON"]',
|
||||
content: (
|
||||
<Description>
|
||||
Add the constraint value by using this button.
|
||||
</Description>
|
||||
),
|
||||
},
|
||||
{
|
||||
target: 'button[data-testid="CONSTRAINT_SAVE_BUTTON"]',
|
||||
content: (
|
||||
<Description>
|
||||
Save the constraint by using this button.
|
||||
</Description>
|
||||
),
|
||||
},
|
||||
{
|
||||
target: 'button[data-testid="ADD_STRATEGY_VARIANT_BUTTON"]',
|
||||
content: (
|
||||
<>
|
||||
<Description>
|
||||
<a
|
||||
href="https://docs.getunleash.io/reference/strategy-variants"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
Strategy variants
|
||||
</a>{' '}
|
||||
allow to attach one or more values to your{' '}
|
||||
<a
|
||||
href="https://docs.getunleash.io/reference/activation-strategies"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
activation strategy
|
||||
</a>{' '}
|
||||
.
|
||||
</Description>
|
||||
<Description sx={{ mt: 1 }}>
|
||||
Add a strategy variant by using this button.
|
||||
</Description>
|
||||
</>
|
||||
),
|
||||
backCloseModal: true,
|
||||
},
|
||||
{
|
||||
@ -486,7 +609,8 @@ export const TOPICS: ITutorialTopic[] = [
|
||||
content: (
|
||||
<>
|
||||
<Description>
|
||||
Enter a unique name for your variant.
|
||||
Enter a name for your variant e.g.{' '}
|
||||
<Badge as="span">color</Badge>
|
||||
</Description>
|
||||
<Description sx={{ mt: 1 }}>
|
||||
When you're done, use the "Next" button in the
|
||||
@ -494,9 +618,9 @@ export const TOPICS: ITutorialTopic[] = [
|
||||
</Description>
|
||||
</>
|
||||
),
|
||||
backCloseModal: true,
|
||||
nextButton: true,
|
||||
focus: 'input',
|
||||
backCloseModal: true,
|
||||
},
|
||||
{
|
||||
target: 'div[data-testid="VARIANT"]:last-of-type #variant-payload-value',
|
||||
@ -530,77 +654,14 @@ export const TOPICS: ITutorialTopic[] = [
|
||||
focus: true,
|
||||
},
|
||||
{
|
||||
target: 'div[data-testid="VARIANT"]:last-of-type button[data-testid="VARIANT_ADD_OVERRIDE_BUTTON"]',
|
||||
content: (
|
||||
<>
|
||||
<Description>
|
||||
By adding an override, we can specify that your user
|
||||
will always get this variant.
|
||||
</Description>
|
||||
<Description sx={{ mt: 1 }}>
|
||||
Let's add an override for your user by using this
|
||||
button.
|
||||
</Description>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
target: 'div[data-testid="VARIANT"]:last-of-type #override-context-name',
|
||||
target: 'button[data-testid="STRATEGY_FORM_SUBMIT_ID"]',
|
||||
content: (
|
||||
<Description>
|
||||
Select the context field by using this dropdown.
|
||||
Save and apply your strategy by using this button.
|
||||
</Description>
|
||||
),
|
||||
anyClick: true,
|
||||
backCloseModal: true,
|
||||
},
|
||||
{
|
||||
target: 'li[data-testid="SELECT_ITEM_ID-userId"]',
|
||||
content: (
|
||||
<Description>
|
||||
Select the <Badge as="span">userId</Badge> context
|
||||
field.
|
||||
</Description>
|
||||
),
|
||||
placement: 'right',
|
||||
backCloseModal: true,
|
||||
},
|
||||
{
|
||||
target: 'div[data-testid="VARIANT"]:last-of-type div[data-testid="OVERRIDE_VALUES"]',
|
||||
content: (
|
||||
<>
|
||||
<Description>
|
||||
Enter your <Badge as="span">userId</Badge>
|
||||
</Description>
|
||||
<Badge
|
||||
sx={{ mt: 2, mb: 1, width: '100%' }}
|
||||
icon={<InfoOutlinedIcon />}
|
||||
>
|
||||
You can find your userId on the demo page.
|
||||
</Badge>
|
||||
<StyledImg
|
||||
src={formatAssetPath(demoUserId)}
|
||||
alt="You can find your userId on the demo page."
|
||||
/>
|
||||
<Description sx={{ mt: 1 }}>
|
||||
When you're done, use the "Next" button in the
|
||||
dialog.
|
||||
</Description>
|
||||
</>
|
||||
),
|
||||
placement: 'right',
|
||||
nextButton: true,
|
||||
backCloseModal: true,
|
||||
focus: 'input',
|
||||
},
|
||||
{
|
||||
target: 'button[data-testid="DIALOGUE_CONFIRM_ID"]',
|
||||
content: (
|
||||
<Description>
|
||||
Save your variants by using this button.
|
||||
</Description>
|
||||
),
|
||||
},
|
||||
{
|
||||
href: `/projects/${PROJECT}?sort=name`,
|
||||
target: `div[data-testid="TOGGLE-demoApp.step4-${ENVIRONMENT}"]`,
|
||||
|
@ -2,7 +2,7 @@ import { Alert, Button, Divider, Link, styled } from '@mui/material';
|
||||
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
|
||||
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { FormEvent, useEffect, useMemo, useState } from 'react';
|
||||
import { FormEvent, useEffect, useMemo, useState, memo } from 'react';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { IFeatureEnvironment, IFeatureVariant } from 'interfaces/featureToggle';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
@ -133,6 +133,8 @@ interface IEnvironmentVariantModalProps {
|
||||
onConfirm: (updatedVariants: IFeatureVariant[]) => void;
|
||||
}
|
||||
|
||||
const MemoizedVariantForm = memo(VariantForm);
|
||||
|
||||
export const EnvironmentVariantsModal = ({
|
||||
environment,
|
||||
open,
|
||||
@ -373,7 +375,7 @@ export const EnvironmentVariantsModal = ({
|
||||
/>
|
||||
<StyledVariantForms>
|
||||
{variantsEdit.map(variant => (
|
||||
<VariantForm
|
||||
<MemoizedVariantForm
|
||||
key={variant.id}
|
||||
variant={variant}
|
||||
variants={variantsEdit}
|
||||
|
@ -111,7 +111,7 @@ export const StrategyVariants: FC<{
|
||||
</span>
|
||||
<Link
|
||||
target="_blank"
|
||||
href="https://docs.getunleash.io/reference/feature-strategy-variants"
|
||||
href="https://docs.getunleash.io/reference/strategy-variants"
|
||||
>
|
||||
Learn more
|
||||
</Link>
|
||||
@ -120,7 +120,6 @@ export const StrategyVariants: FC<{
|
||||
/>
|
||||
</Typography>
|
||||
<StyledVariantForms>
|
||||
<VariantInfoAlert mode="strategy" />
|
||||
<StrategyVariantsUpgradeAlert />
|
||||
{variantsEdit.map((variant, i) => (
|
||||
<VariantForm
|
||||
@ -155,6 +154,7 @@ export const StrategyVariants: FC<{
|
||||
permission={UPDATE_FEATURE_ENVIRONMENT_VARIANTS}
|
||||
projectId={projectId}
|
||||
environmentId={environment}
|
||||
data-testid="ADD_STRATEGY_VARIANT_BUTTON"
|
||||
>
|
||||
Add variant
|
||||
</PermissionButton>
|
||||
|
Loading…
Reference in New Issue
Block a user