mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: after onboarding show success box with resources (#8278)
![image](https://github.com/user-attachments/assets/7e60ad54-c750-4e8a-8556-a1735a99a43e)
This commit is contained in:
parent
547e41e566
commit
86e7bbc85d
@ -19,6 +19,7 @@ import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectO
|
||||
interface IConnectSDKDialogProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onFinish: () => void;
|
||||
project: string;
|
||||
environments: string[];
|
||||
feature?: string;
|
||||
@ -66,6 +67,7 @@ type OnboardingStage = 'select-sdk' | 'generate-api-key' | 'test-connection';
|
||||
export const ConnectSdkDialog = ({
|
||||
open,
|
||||
onClose,
|
||||
onFinish,
|
||||
environments,
|
||||
project: projectId,
|
||||
feature,
|
||||
@ -76,6 +78,7 @@ export const ConnectSdkDialog = ({
|
||||
const [environment, setEnvironment] = useState<string | null>(null);
|
||||
const [apiKey, setApiKey] = useState<string | null>(null);
|
||||
const [stage, setStage] = useState<OnboardingStage>('select-sdk');
|
||||
|
||||
const { project } = useProjectOverview(projectId, {
|
||||
refreshInterval: 1000,
|
||||
});
|
||||
@ -166,12 +169,7 @@ export const ConnectSdkDialog = ({
|
||||
</Button>
|
||||
) : null}
|
||||
|
||||
<Button
|
||||
variant='contained'
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
<Button variant='contained' onClick={onFinish}>
|
||||
Next
|
||||
</Button>
|
||||
</NextStepSectionSpacedContainer>
|
||||
|
@ -9,7 +9,7 @@ interface IConnectionInformationProps {
|
||||
sdk: string;
|
||||
environment: string;
|
||||
}
|
||||
export const Container = styled('div')(({ theme }) => ({
|
||||
const Container = styled('div')(({ theme }) => ({
|
||||
backgroundColor: theme.palette.background.sidebar,
|
||||
padding: theme.spacing(6, 9, 6, 9),
|
||||
minWidth: '400px',
|
||||
@ -18,14 +18,14 @@ export const Container = styled('div')(({ theme }) => ({
|
||||
color: theme.palette.primary.contrastText,
|
||||
}));
|
||||
|
||||
export const Title = styled(Typography)(({ theme }) => ({
|
||||
const Title = styled(Typography)(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
fontWeight: theme.typography.fontWeightBold,
|
||||
}));
|
||||
|
||||
export const SdkInfo = styled('div')(({ theme }) => ({
|
||||
const SdkInfo = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
padding: theme.spacing(4, 0, 12, 0),
|
||||
@ -33,13 +33,13 @@ export const SdkInfo = styled('div')(({ theme }) => ({
|
||||
fontSize: theme.spacing(1),
|
||||
}));
|
||||
|
||||
export const Info = styled('div')(({ theme }) => ({
|
||||
const Info = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
gap: theme.spacing(1),
|
||||
flexDirection: 'column',
|
||||
}));
|
||||
|
||||
export const ConnectionStatus = styled('div')(({ theme }) => ({
|
||||
const ConnectionStatus = styled('div')(({ theme }) => ({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
display: 'flex',
|
||||
@ -48,7 +48,7 @@ export const ConnectionStatus = styled('div')(({ theme }) => ({
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
}));
|
||||
|
||||
export const StyledCheck = styled(Check)(({ theme }) => ({
|
||||
const StyledCheck = styled(Check)(({ theme }) => ({
|
||||
color: theme.palette.primary.main,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
borderRadius: '50%',
|
||||
|
@ -36,6 +36,7 @@ test('Onboarding for SDK', async () => {
|
||||
open={true}
|
||||
environments={['development', 'production']}
|
||||
feature='featureA'
|
||||
onFinish={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
|
153
frontend/src/component/onboarding/flow/ProjectOnboarded.tsx
Normal file
153
frontend/src/component/onboarding/flow/ProjectOnboarded.tsx
Normal file
@ -0,0 +1,153 @@
|
||||
import { IconButton, styled, Tooltip, Typography } from '@mui/material';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import Check from '@mui/icons-material/Check';
|
||||
import People from '@mui/icons-material/People';
|
||||
import MenuBook from '@mui/icons-material/MenuBook';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
interface IProjectOnboardedProps {
|
||||
projectId: string;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const Container = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
flexBasis: '70%',
|
||||
borderRadius: theme.shape.borderRadiusLarge,
|
||||
}));
|
||||
|
||||
const TitleRow = styled('div')(({ theme }) => ({
|
||||
padding: theme.spacing(2, 4, 2, 7),
|
||||
borderBottom: '1px solid',
|
||||
borderColor: theme.palette.divider,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
gap: theme.spacing(3),
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
const Actions = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexGrow: 1,
|
||||
}));
|
||||
|
||||
const ActionBox = styled('div')(({ theme }) => ({
|
||||
flexBasis: '50%',
|
||||
padding: theme.spacing(3, 2, 6, 8),
|
||||
display: 'flex',
|
||||
gap: theme.spacing(3),
|
||||
flexDirection: 'column',
|
||||
}));
|
||||
|
||||
const TitleContainer = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
gap: theme.spacing(2),
|
||||
alignItems: 'center',
|
||||
fontSize: theme.spacing(1.75),
|
||||
fontWeight: 'bold',
|
||||
}));
|
||||
|
||||
const Title = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
}));
|
||||
|
||||
const StyledCheck = styled(Check)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: theme.palette.background.paper,
|
||||
borderRadius: '50%',
|
||||
padding: theme.spacing(0.5),
|
||||
width: '28px',
|
||||
height: '28px',
|
||||
}));
|
||||
|
||||
const ColoredPeople = styled(People)(({ theme }) => ({
|
||||
color: theme.palette.primary.main,
|
||||
}));
|
||||
|
||||
const ColoredMenuBook = styled(MenuBook)(({ theme }) => ({
|
||||
color: theme.palette.primary.main,
|
||||
}));
|
||||
|
||||
export const ProjectOnboarded = ({
|
||||
projectId,
|
||||
onClose,
|
||||
}: IProjectOnboardedProps) => {
|
||||
return (
|
||||
<Container>
|
||||
<TitleRow>
|
||||
<StyledCheck />
|
||||
<Title>
|
||||
<Typography fontWeight='bold'>Setup completed</Typography>
|
||||
<Typography variant='body2'>Next steps</Typography>
|
||||
</Title>
|
||||
|
||||
<Tooltip title='Close' arrow sx={{ ml: 'auto' }}>
|
||||
<IconButton onClick={onClose} size='small'>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</TitleRow>
|
||||
<Actions>
|
||||
<ActionBox>
|
||||
<TitleContainer>
|
||||
Expose your feature flag to users
|
||||
</TitleContainer>
|
||||
<Typography>
|
||||
You can have fine grained control over who is exposed to
|
||||
your feature flag by leveraging{' '}
|
||||
<Link
|
||||
className='unleash-action-button'
|
||||
to={`https://docs.getunleash.io/reference/activation-strategies`}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
>
|
||||
strategies
|
||||
</Link>
|
||||
. Visit the feature flag page to start adding strategies
|
||||
to control exposure.
|
||||
</Typography>
|
||||
</ActionBox>
|
||||
<ActionBox>
|
||||
<TitleContainer>
|
||||
<ColoredPeople />
|
||||
Add members to your project
|
||||
</TitleContainer>
|
||||
<Typography>
|
||||
Unleash is best when collaborating with your co-workers.{' '}
|
||||
<Link
|
||||
className='unleash-action-button'
|
||||
to={`/projects/${projectId}/settings/access`}
|
||||
>
|
||||
Add your co-workers to the project
|
||||
</Link>
|
||||
.
|
||||
</Typography>
|
||||
</ActionBox>
|
||||
<ActionBox>
|
||||
<TitleContainer>
|
||||
<ColoredMenuBook />
|
||||
Learn about unleash
|
||||
</TitleContainer>
|
||||
<Typography>
|
||||
Take a deep dive through our documentation,{' '}
|
||||
<Link
|
||||
className='unleash-action-button'
|
||||
to={`https://docs.getunleash.io/unleash-academy/foundational`}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
>
|
||||
starting with the foundations of Unleash
|
||||
</Link>
|
||||
.
|
||||
</Typography>
|
||||
</ActionBox>
|
||||
</Actions>
|
||||
</Container>
|
||||
);
|
||||
};
|
@ -45,6 +45,7 @@ import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectO
|
||||
import { ConnectSdkDialog } from '../../../onboarding/dialog/ConnectSdkDialog';
|
||||
import { ProjectOnboarding } from '../../../onboarding/flow/ProjectOnboarding';
|
||||
import { useLocalStorageState } from 'hooks/useLocalStorageState';
|
||||
import { ProjectOnboarded } from 'component/onboarding/flow/ProjectOnboarded';
|
||||
|
||||
interface IPaginatedProjectFeatureTogglesProps {
|
||||
environments: string[];
|
||||
@ -118,6 +119,9 @@ export const ProjectFeatureToggles = ({
|
||||
const [onboardingFlow, setOnboardingFlow] = useLocalStorageState<
|
||||
'visible' | 'closed'
|
||||
>(`onboarding-flow:v1-${projectId}`, 'visible');
|
||||
const [setupCompletedState, setSetupCompletedState] = useLocalStorageState<
|
||||
'hide-setup' | 'show-setup'
|
||||
>(`onboarding-state:v1-${projectId}`, 'hide-setup');
|
||||
|
||||
const notOnboarding =
|
||||
!onboardingUIEnabled ||
|
||||
@ -425,6 +429,17 @@ export const ProjectFeatureToggles = ({
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={setupCompletedState === 'show-setup'}
|
||||
show={
|
||||
<ProjectOnboarded
|
||||
projectId={projectId}
|
||||
onClose={() => {
|
||||
setSetupCompletedState('hide-setup');
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<ConditionallyRender
|
||||
condition={showFeaturesTable}
|
||||
show={
|
||||
@ -539,6 +554,10 @@ export const ProjectFeatureToggles = ({
|
||||
onClose={() => {
|
||||
setConnectSdkOpen(false);
|
||||
}}
|
||||
onFinish={() => {
|
||||
setConnectSdkOpen(false);
|
||||
setSetupCompletedState('show-setup');
|
||||
}}
|
||||
project={projectId}
|
||||
environments={environments}
|
||||
feature={
|
||||
|
Loading…
Reference in New Issue
Block a user