1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-03-27 00:19:39 +01:00

feat: personal dashboard connect sdk (#8190)

This commit is contained in:
Mateusz Kwasniewski 2024-09-19 17:01:33 +02:00 committed by GitHub
parent f66854a0f0
commit 10ec2e7de5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 183 additions and 81 deletions

View File

@ -0,0 +1,70 @@
import { Button, styled, Typography } from '@mui/material';
import type { FC } from 'react';
const TitleContainer = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'row',
gap: theme.spacing(2),
alignItems: 'center',
fontSize: theme.spacing(1.75),
fontWeight: 'bold',
}));
const NeutralCircleContainer = styled('span')(({ theme }) => ({
width: '28px',
height: '28px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: theme.palette.neutral.border,
borderRadius: '50%',
}));
const ActionBox = styled('div')(({ theme }) => ({
flexBasis: '50%',
padding: theme.spacing(4, 2),
display: 'flex',
gap: theme.spacing(3),
flexDirection: 'column',
}));
export const CreateFlag: FC<{ project: string }> = ({ project }) => {
return (
<ActionBox>
<TitleContainer>
<NeutralCircleContainer>1</NeutralCircleContainer>
Create a feature flag
</TitleContainer>
<Typography>
<div>The project currently holds no feature toggles.</div>
<div>Create a feature flag to get started.</div>
</Typography>
<div>
<Button href={`projects/${project}`} variant='contained'>
Go to project
</Button>
</div>
</ActionBox>
);
};
export const ConnectSDK: FC<{ project: string }> = ({ project }) => {
return (
<ActionBox>
{' '}
<TitleContainer>
<NeutralCircleContainer>2</NeutralCircleContainer>
Connect an SDK
</TitleContainer>
<Typography>
Your project is not yet connected to any SDK. In order to start
using your feature flag connect an SDK to the project.
</Typography>
<div>
<Button href={`projects/${project}`} variant='contained'>
Go to project
</Button>
</div>
</ActionBox>
);
};

View File

@ -1,21 +1,22 @@
import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser'; import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser';
import { import {
Grid,
Paper,
styled,
Typography,
Box, Box,
IconButton,
Link,
List, List,
ListItem, ListItem,
ListItemButton, ListItemButton,
Link, styled,
IconButton, Typography,
Grid,
} from '@mui/material'; } from '@mui/material';
import type { Theme } from '@mui/material/styles/createTheme'; import type { Theme } from '@mui/material/styles/createTheme';
import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon'; import { ProjectIcon } from 'component/common/ProjectIcon/ProjectIcon';
import { type FC, useState } from 'react'; import { type FC, useEffect, useState } from 'react';
import { useProfile } from 'hooks/api/getters/useProfile/useProfile'; import { useProfile } from 'hooks/api/getters/useProfile/useProfile';
import LinkIcon from '@mui/icons-material/Link'; import LinkIcon from '@mui/icons-material/Link';
import { Badge } from '../common/Badge/Badge';
import { ConnectSDK, CreateFlag } from './ConnectSDK';
const ScreenExplanation = styled(Typography)(({ theme }) => ({ const ScreenExplanation = styled(Typography)(({ theme }) => ({
marginTop: theme.spacing(1), marginTop: theme.spacing(1),
@ -29,10 +30,9 @@ const StyledHeaderTitle = styled(Typography)(({ theme }) => ({
marginBottom: theme.spacing(2), marginBottom: theme.spacing(2),
})); }));
const Projects = styled(Paper)(({ theme }) => ({ const ProjectsGrid = styled(Grid)(({ theme }) => ({
backgroundColor: theme.palette.background.paper,
borderRadius: `${theme.shape.borderRadiusLarge}px`, borderRadius: `${theme.shape.borderRadiusLarge}px`,
boxShadow: 'none',
padding: theme.spacing(4),
})); }));
const ProjectBox = styled(Box)(({ theme }) => ({ const ProjectBox = styled(Box)(({ theme }) => ({
@ -104,13 +104,15 @@ const ActiveProjectDetails: FC<{
); );
}; };
export const PersonalDashboard = () => { const SpacedGrid = styled(Grid)(({ theme }) => ({
const { user } = useAuthUser(); padding: theme.spacing(4),
border: `0.5px solid ${theme.palette.divider}`,
const name = user?.name; }));
const useProjects = () => {
const myProjects = useProfile().profile?.projects || []; const myProjects = useProfile().profile?.projects || [];
// TODO: add real data for flags/members/health
const projects = myProjects.map((project) => ({ const projects = myProjects.map((project) => ({
name: project, name: project,
flags: 0, flags: 0,
@ -118,9 +120,23 @@ export const PersonalDashboard = () => {
health: 100, health: 100,
})); }));
const [activeProject, setActiveProject] = useState<string | null>( const [activeProject, setActiveProject] = useState(projects[0]?.name);
projects[0]?.name,
); useEffect(() => {
if (!activeProject && projects.length > 0) {
setActiveProject(projects[0].name);
}
}, [JSON.stringify(projects)]);
return { projects, activeProject, setActiveProject };
};
export const PersonalDashboard = () => {
const { user } = useAuthUser();
const name = user?.name;
const { projects, activeProject, setActiveProject } = useProjects();
return ( return (
<div> <div>
@ -132,72 +148,88 @@ export const PersonalDashboard = () => {
most of Unleash most of Unleash
</ScreenExplanation> </ScreenExplanation>
<StyledHeaderTitle>Your resources</StyledHeaderTitle> <StyledHeaderTitle>Your resources</StyledHeaderTitle>
<Projects> <ProjectsGrid container columns={{ lg: 12, md: 1 }}>
<Grid container spacing={2} columns={{ lg: 12 }}> <SpacedGrid item lg={4} md={1}>
<Grid item lg={3}> <Typography variant='h3'>My projects</Typography>
<Typography variant='h3'>My projects</Typography> </SpacedGrid>
</Grid> <SpacedGrid
<Grid item lg={4} /> item
<Grid item lg={5} /> lg={8}
<Grid item lg={3}> md={1}
<List sx={{ display: 'flex', justifyContent: 'flex-end' }}
disablePadding={true} >
sx={{ maxHeight: '400px', overflow: 'auto' }} <Badge color='warning'>Setup incomplete</Badge>
> </SpacedGrid>
{projects.map((project) => { <SpacedGrid item lg={4} md={1}>
return ( <List
<ListItem disablePadding={true}
disablePadding={true} sx={{ maxHeight: '400px', overflow: 'auto' }}
sx={{ mb: 1 }} >
{projects.map((project) => {
return (
<ListItem
key={project.name}
disablePadding={true}
sx={{ mb: 1 }}
>
<ListItemButton
sx={projectStyle}
selected={
project.name === activeProject
}
onClick={() =>
setActiveProject(project.name)
}
> >
<ListItemButton <ProjectBox>
sx={projectStyle} <ProjectIcon color='primary' />
selected={ <StyledCardTitle>
project.name === activeProject {project.name}
} </StyledCardTitle>
onClick={() => <IconButton
setActiveProject(project.name) component={Link}
} href={`projects/${project.name}`}
> size='small'
<ProjectBox> sx={{ ml: 'auto' }}
<ProjectIcon color='primary' /> >
<StyledCardTitle> <LinkIcon
{project.name} titleAccess={`projects/${project.name}`}
</StyledCardTitle>
<IconButton
component={Link}
href={`projects/${project.name}`}
size='small'
sx={{ ml: 'auto' }}
>
<LinkIcon
titleAccess={`projects/${project.name}`}
/>
</IconButton>
</ProjectBox>
{project.name === activeProject ? (
<ActiveProjectDetails
project={project}
/> />
) : null} </IconButton>
</ListItemButton> </ProjectBox>
</ListItem> {project.name === activeProject ? (
); <ActiveProjectDetails
})} project={project}
</List> />
</Grid> ) : null}
<Grid item lg={4}> </ListItemButton>
Connect an SDK </ListItem>
</Grid> );
<Grid item lg={5}> })}
Create a feature toggle </List>
</Grid> </SpacedGrid>
<Grid item lg={3} /> <SpacedGrid item lg={4} md={1}>
<Grid item lg={9}> {activeProject ? (
Your role in this project <CreateFlag project={activeProject} />
</Grid> ) : null}
</Grid> </SpacedGrid>
</Projects> <SpacedGrid item lg={4} md={1}>
{activeProject ? (
<ConnectSDK project={activeProject} />
) : null}
</SpacedGrid>
<SpacedGrid item lg={4} md={1} />
<SpacedGrid
item
lg={8}
md={1}
sx={{ display: 'flex', gap: 1, alignItems: 'center' }}
>
<span>Your roles in this project:</span>{' '}
<Badge color='secondary'>Member</Badge>{' '}
<Badge color='secondary'>Another</Badge>
</SpacedGrid>
</ProjectsGrid>
</div> </div>
); );
}; };