1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-04 00:18:01 +01:00

feat: show docs with icons in sidebar (#7109)

Adds icons to sidebar documentation and removes the link when you can't
interact with it.

I'm a little concerned that this won't be very accessible at the moment,
because we don't announce that anything has changed (i.e. there's no way
to find out that the text has changed if you can't see it), and the text
isn't labeled as describing anything. (this is being addressed in #7110
)


![image](https://github.com/Unleash/unleash/assets/17786332/2f482aa1-b74d-4b0f-97aa-2dbc1d1f82f9)

There's a few caveats to this:
1. we don't set a min height at the moment. I've avoided this because we
use the sidebar a number of other places and I wanted to touch as little
as possible. This means we can still get height adjustments
2. The new project icon doesn't have the same proportions as the mui
icons. This adds some additional jank. We should probably look at this,
though.
This commit is contained in:
Thomas Heartman 2024-05-22 13:45:47 +02:00 committed by GitHub
parent 688bac9f87
commit 78fcdbf132
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 86 additions and 34 deletions

View File

@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="37" height="35" viewBox="0 0 37 35" fill="none">
<rect x="8.9864" y="9.93245" width="3.78378" height="13.2432" rx="1.41892" fill="#6C65E5" stroke="#6C65E5" stroke-width="0.945947" />
<rect x="16.5542" y="13.7161" width="3.78378" height="9.45946" rx="1.41892" fill="#6C65E5" stroke="#6C65E5" stroke-width="0.945947" />
<rect x="24.1217" y="18.4456" width="3.78378" height="4.72973" rx="1.41892" fill="#6C65E5" stroke="#6C65E5" stroke-width="0.945947" />
<svg xmlns="http://www.w3.org/2000/svg" focusable='false' aria-hidden='true' width="37" height="35" viewBox="0 0 37 35" fill="none">
<rect x="8.9864" y="9.93245" width="3.78378" height="13.2432" rx="1.41892" stroke-width="0.945947" />
<rect x="16.5542" y="13.7161" width="3.78378" height="9.45946" rx="1.41892" stroke-width="0.945947" />
<rect x="24.1217" y="18.4456" width="3.78378" height="4.72973" rx="1.41892" stroke-width="0.945947" />
</svg>

Before

Width:  |  Height:  |  Size: 519 B

After

Width:  |  Height:  |  Size: 460 B

View File

@ -23,8 +23,9 @@ import { relative } from 'themes/themeStyles';
interface ICreateProps {
title?: ReactNode;
description: string;
documentationLink: string;
documentationLinkLabel: string;
documentationLink?: string;
documentationIcon?: ReactNode;
documentationLinkLabel?: string;
loading?: boolean;
modal?: boolean;
disablePadding?: boolean;
@ -165,16 +166,26 @@ const StyledSidebar = styled('aside')(({ theme }) => ({
},
}));
const StyledDescription = styled('p')(({ theme }) => ({
color: theme.palette.common.white,
const StyledDescriptionCard = styled('article')(({ theme }) => ({
display: 'flex',
flexFlow: 'column nowrap',
gap: theme.spacing(2),
alignItems: 'center',
zIndex: 1,
color: theme.palette.common.white,
position: 'relative',
marginBlockEnd: theme.spacing(3),
}));
const StyledDescription = styled('p')(({ theme }) => ({
width: '100%',
}));
const StyledLinkContainer = styled('div')(({ theme }) => ({
margin: theme.spacing(3, 0),
display: 'flex',
alignItems: 'center',
width: '100%',
}));
const StyledLinkIcon = styled(MenuBookIcon)(({ theme }) => ({
@ -195,6 +206,7 @@ const FormTemplate: React.FC<ICreateProps> = ({
description,
children,
documentationLink,
documentationIcon,
documentationLinkLabel,
loading,
modal,
@ -261,6 +273,7 @@ const FormTemplate: React.FC<ICreateProps> = ({
<StyledRelativeDiv>
<MobileGuidance
description={description}
documentationIcon={documentationIcon}
documentationLink={documentationLink}
documentationLinkLabel={documentationLinkLabel}
/>
@ -300,6 +313,7 @@ const FormTemplate: React.FC<ICreateProps> = ({
condition={showGuidance && !smallScreen}
show={
<Guidance
documentationIcon={documentationIcon}
description={description}
documentationLink={documentationLink}
documentationLinkLabel={documentationLinkLabel}
@ -319,7 +333,8 @@ const FormTemplate: React.FC<ICreateProps> = ({
interface IMobileGuidance {
description: string;
documentationLink: string;
documentationLink?: string;
documentationIcon?: ReactNode;
documentationLinkLabel?: string;
}
@ -327,6 +342,7 @@ const MobileGuidance = ({
description,
documentationLink,
documentationLinkLabel,
documentationIcon,
}: IMobileGuidance) => {
const [open, setOpen] = useState(false);
@ -345,6 +361,7 @@ const MobileGuidance = ({
</Tooltip>
<Collapse in={open} timeout={500}>
<Guidance
documentationIcon={documentationIcon}
description={description}
documentationLink={documentationLink}
documentationLinkLabel={documentationLinkLabel}
@ -356,7 +373,8 @@ const MobileGuidance = ({
interface IGuidanceProps {
description: string;
documentationLink: string;
documentationIcon?: ReactNode;
documentationLink?: string;
documentationLinkLabel?: string;
showDescription?: boolean;
showLink?: boolean;
@ -366,6 +384,7 @@ const Guidance: React.FC<IGuidanceProps> = ({
description,
children,
documentationLink,
documentationIcon,
documentationLinkLabel = 'Learn more',
showDescription = true,
showLink = true,
@ -374,11 +393,19 @@ const Guidance: React.FC<IGuidanceProps> = ({
<StyledSidebar>
<ConditionallyRender
condition={showDescription}
show={<StyledDescription>{description}</StyledDescription>}
show={
<StyledDescriptionCard>
<ConditionallyRender
condition={!!documentationIcon}
show={documentationIcon}
/>
<StyledDescription>{description}</StyledDescription>
</StyledDescriptionCard>
}
/>
<ConditionallyRender
condition={showLink}
condition={showLink && !!documentationLink}
show={
<StyledLinkContainer>
<StyledLinkIcon />
@ -392,7 +419,6 @@ const Guidance: React.FC<IGuidanceProps> = ({
</StyledLinkContainer>
}
/>
{children}
</StyledSidebar>
);

View File

@ -76,7 +76,8 @@ export const StyledParagraphInfo = styled('p')(({ theme }) => ({
}));
export const StyledProjectIcon = styled(ProjectIcon)(({ theme }) => ({
color: theme.palette.primary.main,
fill: theme.palette.primary.main,
stroke: theme.palette.primary.main,
}));
export const StyledIconBox = styled(Box)(({ theme }) => ({

View File

@ -9,11 +9,12 @@ import useProjectForm, {
DEFAULT_PROJECT_STICKINESS,
} from '../../hooks/useProjectForm';
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
import { useState } from 'react';
import { type ReactNode, useState } from 'react';
import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { useNavigate } from 'react-router-dom';
import { Button, Dialog, styled } from '@mui/material';
import { ReactComponent as ProjectIcon } from 'assets/icons/projectIconSmall.svg';
interface ICreateProjectDialogueProps {
open: boolean;
@ -24,6 +25,7 @@ const StyledDialog = styled(Dialog)(({ theme, maxWidth }) => ({
'& .MuiDialog-paper': {
borderRadius: theme.shape.borderRadiusLarge,
maxWidth: theme.spacing(170),
width: '100%',
backgroundColor: 'transparent',
},
padding: 0,
@ -35,6 +37,11 @@ const StyledButton = styled(Button)(({ theme }) => ({
marginLeft: theme.spacing(3),
}));
const StyledProjectIcon = styled(ProjectIcon)(({ theme }) => ({
fill: theme.palette.common.white,
stroke: theme.palette.common.white,
}));
export const CreateProjectDialogue = ({
open,
onClose,
@ -67,8 +74,18 @@ export const CreateProjectDialogue = ({
errors,
} = useProjectForm();
const generalDocumentation =
'Projects allows you to group feature flags together in the management UI.';
const generalDocumentation: {
icon: ReactNode;
text: string;
link?: { url: string; label: string };
} = {
icon: <StyledProjectIcon />,
text: 'Projects allows you to group feature flags together in the management UI.',
link: {
url: 'https://docs.getunleash.io/reference/projects',
label: 'Projects documentation',
},
};
const [documentation, setDocumentation] = useState(generalDocumentation);
@ -115,14 +132,16 @@ export const CreateProjectDialogue = ({
}
}
};
return (
<StyledDialog open={open} onClose={onClose}>
<FormTemplate
compact
disablePadding
description={documentation}
documentationLink='https://docs.getunleash.io/reference/projects'
documentationLinkLabel='Projects documentation'
description={documentation.text}
documentationIcon={documentation.icon}
documentationLink={documentation.link?.url}
documentationLinkLabel={documentation.link?.label}
formatApiCode={formatApiCode}
>
<NewProjectForm

View File

@ -15,6 +15,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
import EnvironmentsIcon from '@mui/icons-material/CloudCircle';
import { useStickinessOptions } from 'hooks/useStickinessOptions';
import { ReactComponent as ChangeRequestIcon } from 'assets/icons/merge.svg';
import type { ReactNode } from 'react';
import theme from 'themes/theme';
const StyledForm = styled('form')(({ theme }) => ({
@ -38,7 +39,8 @@ const TopGrid = styled(StyledFormSection)(({ theme }) => ({
}));
const StyledIcon = styled(ProjectIcon)(({ theme }) => ({
color: theme.palette.primary.main,
fill: theme.palette.primary.main,
stroke: theme.palette.primary.main,
}));
const StyledHeader = styled(Typography)(({ theme }) => ({
@ -101,7 +103,7 @@ type FormProps = {
mode: 'Create' | 'Edit';
clearErrors: () => void;
validateProjectId: () => void;
overrideDocumentation: (description: string) => void;
overrideDocumentation: (args: { text: string; icon: ReactNode }) => void;
clearDocumentationOverride: () => void;
};
@ -223,9 +225,10 @@ export const NewProjectForm: React.FC<FormProps> = ({
placeholder: 'Select project environments',
}}
onOpen={() =>
overrideDocumentation(
`Each feature flag can have a separate configuration per environment. This setting configures which environments your project should start with.`,
)
overrideDocumentation({
icon: <EnvironmentsIcon />,
text: `Each feature flag can have a separate configuration per environment. This setting configures which environments your project should start with.`,
})
}
onClose={clearDocumentationOverride}
/>
@ -247,9 +250,10 @@ export const NewProjectForm: React.FC<FormProps> = ({
placeholder: 'Select default stickiness',
}}
onOpen={() =>
overrideDocumentation(
'Stickiness is used to guarantee that your users see the same result when using a gradual rollout. Default stickiness allows you to choose which field is used by default in this project.',
)
overrideDocumentation({
icon: <StickinessIcon />,
text: 'Stickiness is used to guarantee that your users see the same result when using a gradual rollout. Default stickiness allows you to choose which field is used by default in this project.',
})
}
onClose={clearDocumentationOverride}
/>
@ -271,9 +275,10 @@ export const NewProjectForm: React.FC<FormProps> = ({
placeholder: 'Select project mode',
}}
onOpen={() =>
overrideDocumentation(
'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.',
)
overrideDocumentation({
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.',
})
}
onClose={clearDocumentationOverride}
/>
@ -316,9 +321,10 @@ export const NewProjectForm: React.FC<FormProps> = ({
projectChangeRequestConfiguration
}
onOpen={() =>
overrideDocumentation(
'Change requests can be configured per environment and require changes to go through an approval process before being applied.',
)
overrideDocumentation({
icon: <ChangeRequestIcon />,
text: 'Change requests can be configured per environment and require changes to go through an approval process before being applied.',
})
}
onClose={clearDocumentationOverride}
/>