mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	This PR updates the use of references on the project details page to handle the loading state for a single project. Now, if a project is loading, it'll show skeleton loaders for the relevant boxes:  I've also updated the state type we use for this to be more accurate. Shamelessly stolen from Elm. ```ts type RemoteData<T> = | { state: 'error', error: Error } | { state: 'loading' } | { state: 'success', data: T } ``` After refactoring: 
		
			
				
	
	
		
			121 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { Typography, styled } from '@mui/material';
 | |
| import { Badge } from 'component/common/Badge/Badge';
 | |
| import { AvatarGroupFromOwners } from 'component/common/AvatarGroupFromOwners/AvatarGroupFromOwners';
 | |
| import type { ProjectSchemaOwners } from 'openapi';
 | |
| import { HtmlTooltip } from 'component/common/HtmlTooltip/HtmlTooltip';
 | |
| 
 | |
| type Props = {
 | |
|     roles: string[];
 | |
|     owners: ProjectSchemaOwners;
 | |
| };
 | |
| 
 | |
| const Wrapper = styled('div')(({ theme }) => ({
 | |
|     width: '100%',
 | |
|     display: 'flex',
 | |
|     flexFlow: 'row wrap',
 | |
|     gap: theme.spacing(1),
 | |
|     justifyContent: 'space-between',
 | |
| }));
 | |
| 
 | |
| const InfoSection = styled('div')(({ theme }) => ({
 | |
|     display: 'flex',
 | |
|     gap: theme.spacing(1),
 | |
|     alignItems: 'center',
 | |
| }));
 | |
| 
 | |
| const Roles = styled('ul')(({ theme }) => ({
 | |
|     display: 'flex',
 | |
|     gap: theme.spacing(1),
 | |
|     flexFlow: 'row wrap',
 | |
|     listStyle: 'none',
 | |
|     padding: 0,
 | |
| }));
 | |
| 
 | |
| const TooltipRoles = styled('ul')(({ theme }) => ({
 | |
|     gap: theme.spacing(1),
 | |
|     flexFlow: 'column',
 | |
|     display: 'flex',
 | |
|     listStyle: 'none',
 | |
|     padding: 0,
 | |
| }));
 | |
| 
 | |
| const RoleBadge = styled(Badge)({
 | |
|     whitespace: 'nowrap',
 | |
| });
 | |
| 
 | |
| const StyledAvatarGroup = styled(AvatarGroupFromOwners)({
 | |
|     width: 'max-content',
 | |
| });
 | |
| 
 | |
| export const RoleAndOwnerInfo = ({ roles, owners }: Props) => {
 | |
|     const firstRoles = roles.slice(0, 3);
 | |
|     const extraRoles = roles.slice(3);
 | |
|     return (
 | |
|         <Wrapper data-loading>
 | |
|             <InfoSection>
 | |
|                 {roles.length > 0 ? (
 | |
|                     <>
 | |
|                         <Typography
 | |
|                             sx={{
 | |
|                                 whiteSpace: 'nowrap',
 | |
|                             }}
 | |
|                             variant='body1'
 | |
|                             component='h4'
 | |
|                         >
 | |
|                             Your roles in this project:
 | |
|                         </Typography>
 | |
|                         <Roles>
 | |
|                             {firstRoles.map((role) => (
 | |
|                                 <li key={role}>
 | |
|                                     <RoleBadge color='secondary'>
 | |
|                                         {role}
 | |
|                                     </RoleBadge>
 | |
|                                 </li>
 | |
|                             ))}
 | |
|                             {extraRoles.length ? (
 | |
|                                 <li>
 | |
|                                     <HtmlTooltip
 | |
|                                         arrow
 | |
|                                         title={
 | |
|                                             <TooltipRoles>
 | |
|                                                 {extraRoles.map((role) => (
 | |
|                                                     <li key={role}>
 | |
|                                                         <RoleBadge>
 | |
|                                                             {role}
 | |
|                                                         </RoleBadge>
 | |
|                                                     </li>
 | |
|                                                 ))}
 | |
|                                             </TooltipRoles>
 | |
|                                         }
 | |
|                                     >
 | |
|                                         <RoleBadge
 | |
|                                             key={'extra-roles'}
 | |
|                                             color='secondary'
 | |
|                                         >
 | |
|                                             {`+ ${extraRoles.length} more`}
 | |
|                                         </RoleBadge>
 | |
|                                     </HtmlTooltip>
 | |
|                                 </li>
 | |
|                             ) : null}
 | |
|                         </Roles>
 | |
|                     </>
 | |
|                 ) : (
 | |
|                     <span>You have no project roles in this project.</span>
 | |
|                 )}
 | |
|             </InfoSection>
 | |
|             <InfoSection>
 | |
|                 <Typography
 | |
|                     variant='body1'
 | |
|                     component='h4'
 | |
|                     sx={{
 | |
|                         whiteSpace: 'nowrap',
 | |
|                     }}
 | |
|                 >
 | |
|                     Project owner{owners.length > 1 ? 's' : ''}
 | |
|                 </Typography>
 | |
|                 <StyledAvatarGroup users={owners} avatarLimit={3} />
 | |
|             </InfoSection>
 | |
|         </Wrapper>
 | |
|     );
 | |
| };
 |