1
0
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:
Mateusz Kwasniewski 2023-08-10 11:55:33 +02:00 committed by GitHub
parent 8ee031e978
commit df41146f50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 191 additions and 84 deletions

View File

@ -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"
>

View File

@ -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();
};

View File

@ -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}"]`,

View File

@ -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}

View File

@ -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>