From df41146f50770d462c2660f6e92f6dc30b3726ce Mon Sep 17 00:00:00 2001 From: Mateusz Kwasniewski Date: Thu, 10 Aug 2023 11:55:33 +0200 Subject: [PATCH] feat: Demo for strategy variants (#4457) --- .../StrategyVariantsUpgradeAlert.tsx | 4 +- frontend/src/component/demo/demo-setup.ts | 50 ++++- frontend/src/component/demo/demo-topics.tsx | 211 +++++++++++------- .../EnvironmentVariantsModal.tsx | 6 +- .../StrategyTypes/StrategyVariants.tsx | 4 +- 5 files changed, 191 insertions(+), 84 deletions(-) diff --git a/frontend/src/component/common/StrategyVariantsUpgradeAlert/StrategyVariantsUpgradeAlert.tsx b/frontend/src/component/common/StrategyVariantsUpgradeAlert/StrategyVariantsUpgradeAlert.tsx index 3389ed80d3..5a229cb884 100644 --- a/frontend/src/component/common/StrategyVariantsUpgradeAlert/StrategyVariantsUpgradeAlert.tsx +++ b/frontend/src/component/common/StrategyVariantsUpgradeAlert/StrategyVariantsUpgradeAlert.tsx @@ -21,7 +21,7 @@ export const StrategyVariantsPreferredAlert = () => { const DocsSdkSupportLink = () => { return ( @@ -33,7 +33,7 @@ const DocsSdkSupportLink = () => { const DocsLink = () => { return ( diff --git a/frontend/src/component/demo/demo-setup.ts b/frontend/src/component/demo/demo-setup.ts index 05609fe93d..9c2a413366 100644 --- a/frontend/src/component/demo/demo-setup.ts +++ b/frontend/src/component/demo/demo-setup.ts @@ -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; segments: Array }) => + strategy.constraints.length === 0 && strategy.segments.length === 0 + ); + const constrainedStrategies = results.filter( + (strategy: { constraints: Array; segments: Array }) => + 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(); +}; diff --git a/frontend/src/component/demo/demo-topics.tsx b/frontend/src/component/demo/demo-topics.tsx index a45f74724c..35928acb43 100644 --- a/frontend/src/component/demo/demo-topics.tsx +++ b/frontend/src/component/demo/demo-topics.tsx @@ -461,24 +461,147 @@ export const TOPICS: ITutorialTopic[] = [ }, { href: `/projects/${PROJECT}/features/demoApp.step4`, - target: 'button[data-testid="TAB-Variants"]', - content: Select the "Variants" tab., - }, - { - target: 'button[data-testid="EDIT_VARIANTS_BUTTON"]', + target: `div[data-testid="FEATURE_ENVIRONMENT_ACCORDION_${ENVIRONMENT}"] button`, content: ( - Edit the existing variants by using this button. + Add a new strategy to this environment by using this + button. ), }, { - target: 'button[data-testid="MODAL_ADD_VARIANT_BUTTON"]', + target: 'button[data-testid="ADD_CONSTRAINT_BUTTON"]', + content: ( + <> + + + Strategy constraints + {' '} + are conditions that must be satisfied for an{' '} + + activation strategy + {' '} + to be evaluated for a feature toggle. + + + Add a constraint by using this button. + + + ), + backCloseModal: true, + }, + { + target: '#context-field-select', + content: ( + <> + + + Unleash context + {' '} + contains information relating to the current feature + toggle request. + + + Select the context field by using this dropdown. + + + ), + backCloseModal: true, + anyClick: true, + }, + { + target: 'li[data-testid="SELECT_ITEM_ID-userId"]', content: ( - Add a new variant to the list by using this button. + Select the userId context + field. ), + placement: 'right', + backCloseModal: true, + }, + { + target: 'div[data-testid="CONSTRAINT_VALUES_INPUT"]', + content: ( + <> + + Enter your userId + + } + > + You can find your userId on the demo page. + + + + When you're done, use the "Next" button in the + dialog. + + + ), + placement: 'right', + nextButton: true, + focus: 'input', + }, + { + target: 'button[data-testid="CONSTRAINT_VALUES_ADD_BUTTON"]', + content: ( + + Add the constraint value by using this button. + + ), + }, + { + target: 'button[data-testid="CONSTRAINT_SAVE_BUTTON"]', + content: ( + + Save the constraint by using this button. + + ), + }, + { + target: 'button[data-testid="ADD_STRATEGY_VARIANT_BUTTON"]', + content: ( + <> + + + Strategy variants + {' '} + allow to attach one or more values to your{' '} + + activation strategy + {' '} + . + + + Add a strategy variant by using this button. + + + ), backCloseModal: true, }, { @@ -486,7 +609,8 @@ export const TOPICS: ITutorialTopic[] = [ content: ( <> - Enter a unique name for your variant. + Enter a name for your variant e.g.{' '} + color When you're done, use the "Next" button in the @@ -494,9 +618,9 @@ export const TOPICS: ITutorialTopic[] = [ ), - 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: ( - <> - - By adding an override, we can specify that your user - will always get this variant. - - - Let's add an override for your user by using this - button. - - - ), - }, - { - target: 'div[data-testid="VARIANT"]:last-of-type #override-context-name', + target: 'button[data-testid="STRATEGY_FORM_SUBMIT_ID"]', content: ( - Select the context field by using this dropdown. + Save and apply your strategy by using this button. ), - anyClick: true, backCloseModal: true, }, - { - target: 'li[data-testid="SELECT_ITEM_ID-userId"]', - content: ( - - Select the userId context - field. - - ), - placement: 'right', - backCloseModal: true, - }, - { - target: 'div[data-testid="VARIANT"]:last-of-type div[data-testid="OVERRIDE_VALUES"]', - content: ( - <> - - Enter your userId - - } - > - You can find your userId on the demo page. - - - - When you're done, use the "Next" button in the - dialog. - - - ), - placement: 'right', - nextButton: true, - backCloseModal: true, - focus: 'input', - }, - { - target: 'button[data-testid="DIALOGUE_CONFIRM_ID"]', - content: ( - - Save your variants by using this button. - - ), - }, { href: `/projects/${PROJECT}?sort=name`, target: `div[data-testid="TOGGLE-demoApp.step4-${ENVIRONMENT}"]`, diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal.tsx b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal.tsx index 8abcb9e4d8..84a39de798 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsModal/EnvironmentVariantsModal.tsx @@ -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 = ({ /> {variantsEdit.map(variant => ( - Learn more @@ -120,7 +120,6 @@ export const StrategyVariants: FC<{ /> - {variantsEdit.map((variant, i) => ( Add variant