diff --git a/frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.styles.tsx b/frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.styles.tsx index 80b052ef6c..241e415517 100644 --- a/frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.styles.tsx +++ b/frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.styles.tsx @@ -33,11 +33,14 @@ export const StyledHeader = styled(Typography)({ fontWeight: 'lighter', }); -export const ProjectNameContainer = styled('div')({ +export const NameContainer = styled('div')(({ theme }) => ({ gridArea: 'project-name', -}); + display: 'flex', + flexFlow: 'column nowrap', + gap: theme.spacing(2), +})); -export const ProjectDescriptionContainer = styled('div')({ +export const DescriptionContainer = styled('div')({ gridArea: 'project-description', }); diff --git a/frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.tsx b/frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.tsx index 266612d329..6aec3f5d8d 100644 --- a/frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.tsx +++ b/frontend/src/component/common/DialogFormTemplate/DialogFormTemplate.tsx @@ -2,8 +2,8 @@ import type { FormEventHandler } from 'react'; import theme from 'themes/theme'; import { ConfigButtons, - ProjectDescriptionContainer, - ProjectNameContainer, + DescriptionContainer, + NameContainer, StyledForm, StyledHeader, StyledInput, @@ -15,6 +15,11 @@ import { import { Button } from '@mui/material'; import { CreateButton } from 'component/common/CreateButton/CreateButton'; import type { IPermissionButtonProps } from 'component/common/PermissionButton/PermissionButton'; +import type { FeatureNamingType } from 'interfaces/project'; +import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender'; +import { NamingPatternInfo } from './NamingPatternInfo'; + +type NamingPattern = FeatureNamingType; type FormProps = { createButtonProps: IPermissionButtonProps; @@ -30,12 +35,14 @@ type FormProps = { setDescription: (newDescription: string) => void; setName: (newName: string) => void; validateName?: () => void; + namingPattern?: NamingPattern; }; export const DialogFormTemplate: React.FC = ({ Limit, handleSubmit, name, + namingPattern, setName, description, setDescription, @@ -47,15 +54,22 @@ export const DialogFormTemplate: React.FC = ({ createButtonProps, validateName = () => {}, }) => { + const displayNamingPattern = Boolean(namingPattern?.pattern); + return ( {Icon} Create {resource} - + setName(e.target.value)} error={Boolean(errors.name)} @@ -74,8 +88,13 @@ export const DialogFormTemplate: React.FC = ({ data-testid='FORM_NAME_INPUT' size='medium' /> - - + + } + /> + + = ({ }} data-testid='FORM_DESCRIPTION_INPUT' /> - + {configButtons} diff --git a/frontend/src/component/common/DialogFormTemplate/NamingPatternInfo.tsx b/frontend/src/component/common/DialogFormTemplate/NamingPatternInfo.tsx new file mode 100644 index 0000000000..988c8ca22d --- /dev/null +++ b/frontend/src/component/common/DialogFormTemplate/NamingPatternInfo.tsx @@ -0,0 +1,83 @@ +import { + Accordion, + AccordionDetails, + AccordionSummary, + styled, +} from '@mui/material'; +import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; +import type { FeatureNamingType } from 'interfaces/project'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; + +const StyledFlagNamingInfo = styled('article')(({ theme }) => ({ + fontSize: theme.typography.body2.fontSize, + borderRadius: theme.shape.borderRadius, + marginInlineStart: theme.spacing(1.5), + 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), + }, +})); + +const StyledAccordion = styled(Accordion)(({ theme }) => ({ + backgroundColor: 'inherit', + boxShadow: 'none', + margin: 0, +})); + +type Props = { + naming: FeatureNamingType; +}; + +export const NamingPatternInfo: React.FC = ({ naming }) => { + const controlId = 'naming-pattern-info-summary'; + return ( + + + } + > + Name must match: ^{naming.pattern}$ + + +

The name must match this pattern:

+
+
Pattern
+
+ ^{naming.pattern}$ +
+ +
Example
+
{naming?.example}
+ + } + /> + +
Description
+
{naming?.description}
+ + } + /> +
+
+
+
+ ); +}; diff --git a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureTogglesHeader/CreateFeatureDialog.tsx b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureTogglesHeader/CreateFeatureDialog.tsx index a137c49eda..616434619f 100644 --- a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureTogglesHeader/CreateFeatureDialog.tsx +++ b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureTogglesHeader/CreateFeatureDialog.tsx @@ -227,6 +227,7 @@ const CreateFeatureDialogContent = ({ tooltipProps: { title: limitMessage, arrow: true }, }} description={description} + namingPattern={projectInfo.featureNaming} errors={errors} handleSubmit={handleSubmit} Icon={}