From 03d6ed0c32cf1b947c91cbe1c22788f24e3ccb82 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 13 Sep 2023 08:05:58 +0200 Subject: [PATCH] ui: update design for feature naming pattern info (#4656) This PR updates the design for the feature naming pattern info. In doing so, I've extracted the information into a single component. It also, on @nicolaesocaciu's behest, makes the new toggle form inputs wider when they have room to grow. Light mode: ![image](https://github.com/Unleash/unleash/assets/17786332/0923cf95-18e3-4524-8402-7f42a0ac94ec) Dark mode: ![image](https://github.com/Unleash/unleash/assets/17786332/c2a07f73-8973-42d0-b94a-d7dc4ec38a25) For copying features it looks like this: ![image](https://github.com/Unleash/unleash/assets/17786332/2a39f17b-4d86-408c-8f3b-5f2b24e82c81) --- .../feature/CopyFeature/CopyFeature.tsx | 39 +-- .../feature/FeatureForm/FeatureForm.tsx | 273 ++++++++---------- .../FeatureNamingPatternInfo.tsx | 63 ++++ 3 files changed, 181 insertions(+), 194 deletions(-) create mode 100644 frontend/src/component/feature/FeatureNamingPatternInfo/FeatureNamingPatternInfo.tsx diff --git a/frontend/src/component/feature/CopyFeature/CopyFeature.tsx b/frontend/src/component/feature/CopyFeature/CopyFeature.tsx index 6ba6a27340..8b976f1604 100644 --- a/frontend/src/component/feature/CopyFeature/CopyFeature.tsx +++ b/frontend/src/component/feature/CopyFeature/CopyFeature.tsx @@ -20,6 +20,7 @@ import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { useChangeRequestsEnabled } from '../../../hooks/useChangeRequestsEnabled'; import useProject from 'hooks/api/getters/useProject/useProject'; +import { FeatureNamingPatternInfo } from '../FeatureNamingPatternInfo/FeatureNamingPatternInfo'; const StyledPage = styled(Paper)(({ theme }) => ({ overflow: 'visible', @@ -141,41 +142,9 @@ export const CopyFeatureToggle = () => { -

- This project has feature flag naming patterns - enabled, so the name must also match the - configured pattern. -

-
-
Pattern
-
- {featureNaming?.pattern} -
- -
Example
-
{featureNaming?.example}
- - } - /> - -
Description
-
- {featureNaming?.description} -
- - } - /> -
- + } /> diff --git a/frontend/src/component/feature/FeatureForm/FeatureForm.tsx b/frontend/src/component/feature/FeatureForm/FeatureForm.tsx index 6d04ff836f..b18aaf01f6 100644 --- a/frontend/src/component/feature/FeatureForm/FeatureForm.tsx +++ b/frontend/src/component/feature/FeatureForm/FeatureForm.tsx @@ -22,6 +22,7 @@ import { useNavigate } from 'react-router-dom'; import React from 'react'; import { useAuthPermissions } from 'hooks/api/getters/useAuth/useAuthPermissions'; import { FeatureNamingType } from 'interfaces/project'; +import { FeatureNamingPatternInfo } from '../FeatureNamingPatternInfo/FeatureNamingPatternInfo'; interface IFeatureToggleForm { type: string; @@ -44,15 +45,9 @@ interface IFeatureToggleForm { } const StyledForm = styled('form')({ - display: 'flex', - flexDirection: 'column', height: '100%', }); -const StyledContainer = styled('div')({ - maxWidth: '400px', -}); - const StyledInputDescription = styled('p')(({ theme }) => ({ marginBottom: theme.spacing(1), })); @@ -82,11 +77,6 @@ const StyledTypeDescription = styled('p')(({ theme }) => ({ position: 'relative', })); -const StyledFlagNamingInfo = styled('div')(({ theme }) => ({ - fontSize: theme.fontSizes.smallBody, - color: theme.palette.text.secondary, -})); - const StyledButtonContainer = styled('div')({ marginTop: 'auto', display: 'flex', @@ -147,156 +137,121 @@ const FeatureForm: React.FC = ({ return ( - - - What would you like to call your toggle? - - -

- This project has feature flag naming patterns - enabled. -

-
-
Pattern
-
- {featureNaming?.pattern} -
- -
Example
-
{featureNaming?.example}
- - } - /> - -
Description
-
- {featureNaming?.description} -
- - } - /> -
- - } - /> - clearErrors()} - value={name} - onChange={e => setName(trim(e.target.value))} - data-testid={CF_NAME_ID} - onBlur={validateToggleName} - /> - - What kind of feature toggle do you want? - - - - {renderToggleDescription()} - - - In which project do you want to save the toggle? - - } - /> - { - setProject(projectId); - navigate(`/projects/${projectId}/create-toggle`, { - replace: true, - }); - }} - enabled={editable} - filter={projectFilterGenerator(permissions, CREATE_FEATURE)} - IconComponent={KeyboardArrowDownOutlined} - sx={styledSelectInput} - /> + + What would you like to call your toggle? + + + } + /> + clearErrors()} + value={name} + onChange={e => setName(trim(e.target.value))} + data-testid={CF_NAME_ID} + onBlur={validateToggleName} + /> + + What kind of feature toggle do you want? + + + + {renderToggleDescription()} + + + In which project do you want to save the toggle? + + } + /> + { + setProject(projectId); + navigate(`/projects/${projectId}/create-toggle`, { + replace: true, + }); + }} + enabled={editable} + filter={projectFilterGenerator(permissions, CREATE_FEATURE)} + IconComponent={KeyboardArrowDownOutlined} + sx={styledSelectInput} + /> - - How would you describe your feature toggle? - - setDescription(e.target.value)} - /> - - + How would you describe your feature toggle? + + setDescription(e.target.value)} + /> + + + Impression Data + +

+ When you enable impression data for a feature toggle, your + client SDKs will emit events you can listen for every time + this toggle gets triggered. Learn more in{' '} + - Impression Data - -

- When you enable impression data for a feature toggle, - your client SDKs will emit events you can listen for - every time this toggle gets triggered. Learn more in{' '} - - the impression data documentation - -

- - - setImpressionData(!impressionData) - } - checked={impressionData} - /> - } - label="Enable impression data" - /> - -
-
+ the impression data documentation + +

+ + + setImpressionData(!impressionData) + } + checked={impressionData} + /> + } + label="Enable impression data" + /> + + {children} diff --git a/frontend/src/component/feature/FeatureNamingPatternInfo/FeatureNamingPatternInfo.tsx b/frontend/src/component/feature/FeatureNamingPatternInfo/FeatureNamingPatternInfo.tsx new file mode 100644 index 0000000000..53025f6e6b --- /dev/null +++ b/frontend/src/component/feature/FeatureNamingPatternInfo/FeatureNamingPatternInfo.tsx @@ -0,0 +1,63 @@ +import { styled } from '@mui/material'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import { FeatureNamingType } from 'interfaces/project'; + +const StyledFlagNamingInfo = styled('article')(({ theme }) => ({ + fontSize: theme.fontSizes.smallBody, + padding: theme.spacing(2), + borderRadius: theme.shape.borderRadius, + backgroundColor: `${theme.palette.background.elevation2}`, + dl: { + display: 'grid', + gridTemplateColumns: 'max-content auto', + rowGap: theme.spacing(1), + columnGap: 0, + }, + dt: { + color: theme.palette.text.secondary, + '&::after': { content: '":"' }, + }, + dd: { + marginInlineStart: theme.spacing(2), + }, + + marginBlockEnd: theme.spacing(2), +})); + +type Props = { + featureNaming: FeatureNamingType; +}; + +export const FeatureNamingPatternInfo: React.FC = ({ + featureNaming, +}) => { + return ( + +

This project has feature flag naming patterns enabled.

+
+
Pattern
+
+ {featureNaming.pattern} +
+ +
Example
+
{featureNaming?.example}
+ + } + /> + +
Description
+
{featureNaming?.description}
+ + } + /> +
+
+ ); +};