mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-31 00:16:47 +01:00
feat: adds information about project modes to the project creation form (#7250)
This change adds information about the project modes to the new project creation form, using the tooltip for project creation modes. In doing so, it updates the config button tooltip to accept extra elements and adds styling for them. What it looks like: ![image](https://github.com/Unleash/unleash/assets/17786332/809fb48e-2404-416b-a867-6fa04978ccc1) ## a11y issues This solution does present one problem: the popover doesn't get focus, so it's impossible for you to scroll with only a keyboard. However, this is something that's present in Unleash already, and not something that I think would be easily solvable, so I don't think this is when we should solve it.
This commit is contained in:
parent
e5c3cc0c8d
commit
c129541df6
@ -10,7 +10,7 @@ import {
|
||||
|
||||
type ChangeRequestTableConfigButtonProps = Pick<
|
||||
ConfigButtonProps,
|
||||
'button' | 'onOpen' | 'onClose' | 'description' | 'tooltipHeader'
|
||||
'button' | 'onOpen' | 'onClose' | 'description' | 'tooltip'
|
||||
> & {
|
||||
search: {
|
||||
label: string;
|
||||
|
@ -30,3 +30,14 @@ export const ButtonLabel = styled('span', {
|
||||
width: 'max-content',
|
||||
},
|
||||
}));
|
||||
|
||||
export const StyledTooltipContent = styled('article')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: theme.spacing(1),
|
||||
paddingBlock: theme.spacing(1),
|
||||
|
||||
'& > *': {
|
||||
margin: 0,
|
||||
},
|
||||
}));
|
||||
|
@ -6,18 +6,27 @@ import {
|
||||
StyledPopover,
|
||||
HiddenDescription,
|
||||
ButtonLabel,
|
||||
StyledTooltipContent,
|
||||
} from './ConfigButton.styles';
|
||||
import { TooltipResolver } from 'component/common/TooltipResolver/TooltipResolver';
|
||||
|
||||
export type ConfigButtonProps = {
|
||||
button: { label: string; icon: ReactNode; labelWidth?: string };
|
||||
button: {
|
||||
label: string;
|
||||
icon: ReactNode;
|
||||
labelWidth?: string;
|
||||
additionalTooltipContent?: ReactNode;
|
||||
};
|
||||
onOpen?: () => void;
|
||||
onClose?: () => void;
|
||||
description: string;
|
||||
preventOpen?: boolean;
|
||||
anchorEl: HTMLDivElement | null | undefined;
|
||||
setAnchorEl: (el: HTMLDivElement | null | undefined) => void;
|
||||
tooltipHeader: string;
|
||||
tooltip: {
|
||||
header: string;
|
||||
additionalContent?: ReactNode;
|
||||
};
|
||||
};
|
||||
|
||||
export const ConfigButton: FC<PropsWithChildren<ConfigButtonProps>> = ({
|
||||
@ -29,7 +38,7 @@ export const ConfigButton: FC<PropsWithChildren<ConfigButtonProps>> = ({
|
||||
preventOpen,
|
||||
anchorEl,
|
||||
setAnchorEl,
|
||||
tooltipHeader,
|
||||
tooltip,
|
||||
}) => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const descriptionId = uuidv4();
|
||||
@ -49,10 +58,11 @@ export const ConfigButton: FC<PropsWithChildren<ConfigButtonProps>> = ({
|
||||
<Box ref={ref}>
|
||||
<TooltipResolver
|
||||
titleComponent={
|
||||
<article>
|
||||
<h3>{tooltipHeader}</h3>
|
||||
<StyledTooltipContent>
|
||||
<h3>{tooltip.header}</h3>
|
||||
<p>{description}</p>
|
||||
</article>
|
||||
{tooltip.additionalContent}
|
||||
</StyledTooltipContent>
|
||||
}
|
||||
variant='custom'
|
||||
>
|
||||
|
@ -4,7 +4,7 @@ import { DropdownList, type DropdownListProps } from './DropdownList';
|
||||
|
||||
type MultiSelectConfigButtonProps = Pick<
|
||||
ConfigButtonProps,
|
||||
'button' | 'onOpen' | 'onClose' | 'description' | 'tooltipHeader'
|
||||
'button' | 'onOpen' | 'onClose' | 'description' | 'tooltip'
|
||||
> &
|
||||
Pick<DropdownListProps, 'search' | 'options'> & {
|
||||
selectedOptions: Set<string>;
|
||||
|
@ -4,7 +4,7 @@ import { DropdownList, type DropdownListProps } from './DropdownList';
|
||||
|
||||
type SingleSelectConfigButtonProps = Pick<
|
||||
ConfigButtonProps,
|
||||
'button' | 'onOpen' | 'onClose' | 'description' | 'tooltipHeader'
|
||||
'button' | 'onOpen' | 'onClose' | 'description' | 'tooltip'
|
||||
> &
|
||||
Pick<DropdownListProps, 'search' | 'onChange' | 'options'>;
|
||||
|
||||
|
@ -77,3 +77,16 @@ export const FormActions = styled(StyledFormSection)(({ theme }) => ({
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export const StyledDefinitionList = styled('dl')(({ theme }) => ({
|
||||
dt: {
|
||||
fontWeight: 'bold',
|
||||
'&:after': {
|
||||
content: '":"',
|
||||
},
|
||||
},
|
||||
|
||||
'dd + dt': {
|
||||
marginBlockStart: theme.spacing(1),
|
||||
},
|
||||
}));
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
OptionButtons,
|
||||
ProjectDescriptionContainer,
|
||||
ProjectNameContainer,
|
||||
StyledDefinitionList,
|
||||
StyledForm,
|
||||
StyledHeader,
|
||||
StyledIcon,
|
||||
@ -70,7 +71,30 @@ const configButtonData = {
|
||||
},
|
||||
mode: {
|
||||
icon: <ProjectModeIcon />,
|
||||
text: 'Mode defines who should be allowed to interact and see your project. Private mode hides the project from anyone except the project owner and members.',
|
||||
text: "A project's collaboration mode defines who should be allowed see your project and create change requests in it.",
|
||||
additionalTooltipContent: (
|
||||
<>
|
||||
<p>The modes and their functions are:</p>
|
||||
<StyledDefinitionList>
|
||||
<dt>Open</dt>
|
||||
<dd>
|
||||
Anyone can see the project and anyone can create change
|
||||
requests.
|
||||
</dd>
|
||||
<dt>Protected</dt>
|
||||
<dd>
|
||||
Anyone can see the project, but only admins and project
|
||||
members can submit change requests.
|
||||
</dd>
|
||||
<dt>Private</dt>
|
||||
<dd>
|
||||
Hides the project from users with the "viewer" root role
|
||||
who are not members of the project. Only project members
|
||||
and admins can submit change requests.
|
||||
</dd>
|
||||
</StyledDefinitionList>
|
||||
</>
|
||||
),
|
||||
},
|
||||
changeRequests: {
|
||||
icon: <ChangeRequestIcon />,
|
||||
@ -180,7 +204,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
|
||||
<OptionButtons>
|
||||
<MultiSelectConfigButton
|
||||
tooltipHeader='Select project environments'
|
||||
tooltip={{ header: 'Select project environments' }}
|
||||
description={configButtonData.environments.text}
|
||||
selectedOptions={projectEnvironments}
|
||||
options={activeEnvironments.map((env) => ({
|
||||
@ -207,7 +231,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
/>
|
||||
|
||||
<SingleSelectConfigButton
|
||||
tooltipHeader='Set default project stickiness'
|
||||
tooltip={{ header: 'Set default project stickiness' }}
|
||||
description={configButtonData.stickiness.text}
|
||||
options={stickinessOptions.map(({ key, ...rest }) => ({
|
||||
value: key,
|
||||
@ -235,7 +259,12 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
condition={isEnterprise()}
|
||||
show={
|
||||
<SingleSelectConfigButton
|
||||
tooltipHeader='Set project mode'
|
||||
tooltip={{
|
||||
header: 'Set project collaboration mode',
|
||||
additionalContent:
|
||||
configButtonData.mode
|
||||
.additionalTooltipContent,
|
||||
}}
|
||||
description={configButtonData.mode.text}
|
||||
options={projectModeOptions}
|
||||
onChange={(value: any) => {
|
||||
@ -261,7 +290,7 @@ export const NewProjectForm: React.FC<FormProps> = ({
|
||||
condition={isEnterprise()}
|
||||
show={
|
||||
<ChangeRequestTableConfigButton
|
||||
tooltipHeader='Configure change requests'
|
||||
tooltip={{ header: 'Configure change requests' }}
|
||||
description={configButtonData.changeRequests.text}
|
||||
activeEnvironments={
|
||||
availableChangeRequestEnvironments
|
||||
|
Loading…
Reference in New Issue
Block a user