import { useAuthUser } from 'hooks/api/getters/useAuth/useAuthUser'; import { IconButton, Link, List, ListItem, ListItemButton, styled, Typography, } from '@mui/material'; import React, { type FC, useEffect, useRef } from 'react'; import LinkIcon from '@mui/icons-material/ArrowForward'; import { WelcomeDialog } from './WelcomeDialog'; import { useLocalStorageState } from 'hooks/useLocalStorageState'; import { usePersonalDashboard } from 'hooks/api/getters/usePersonalDashboard/usePersonalDashboard'; import { getFeatureTypeIcons } from 'utils/getFeatureTypeIcons'; import type { PersonalDashboardSchemaFlagsItem, PersonalDashboardSchemaProjectsItem, } from '../../openapi'; import { FlagExposure } from 'component/feature/FeatureView/FeatureOverview/FeatureLifecycle/FlagExposure'; import { usePersonalDashboardProjectDetails } from 'hooks/api/getters/usePersonalDashboard/usePersonalDashboardProjectDetails'; import HelpOutline from '@mui/icons-material/HelpOutline'; import useLoading from '../../hooks/useLoading'; import { MyProjects } from './MyProjects'; import { ContentGridContainer, FlagGrid, ListItemBox, listItemStyle, GridItem, SpacedGridItem, } from './Grid'; import { ContentGridNoProjects } from './ContentGridNoProjects'; const ScreenExplanation = styled('div')(({ theme }) => ({ marginBottom: theme.spacing(4), display: 'flex', alignItems: 'center', })); export const StyledCardTitle = styled('div')<{ lines?: number }>( ({ theme, lines = 2 }) => ({ fontWeight: theme.typography.fontWeightRegular, fontSize: theme.typography.body1.fontSize, lineClamp: `${lines}`, WebkitLineClamp: lines, lineHeight: '1.2', display: '-webkit-box', boxOrient: 'vertical', textOverflow: 'ellipsis', overflow: 'hidden', alignItems: 'flex-start', WebkitBoxOrient: 'vertical', wordBreak: 'break-word', }), ); const FlagListItem: FC<{ flag: { name: string; project: string; type: string }; selected: boolean; onClick: () => void; }> = ({ flag, selected, onClick }) => { const activeFlagRef = useRef(null); useEffect(() => { if (activeFlagRef.current) { activeFlagRef.current.scrollIntoView({ block: 'nearest', inline: 'start', }); } }, []); const IconComponent = getFeatureTypeIcons(flag.type); return ( {flag.name} ); }; const useDashboardState = ( projects: PersonalDashboardSchemaProjectsItem[], flags: PersonalDashboardSchemaFlagsItem[], ) => { type State = { activeProject: string | undefined; activeFlag: PersonalDashboardSchemaFlagsItem | undefined; }; const defaultState = { activeProject: undefined, activeFlag: undefined, }; const [state, setState] = useLocalStorageState( 'personal-dashboard:v1', defaultState, ); useEffect(() => { const setDefaultFlag = flags.length && (!state.activeFlag || !flags.some((flag) => flag.name === state.activeFlag?.name)); const setDefaultProject = projects.length && (!state.activeProject || !projects.some( (project) => project.id === state.activeProject, )); if (setDefaultFlag || setDefaultProject) { setState({ activeFlag: setDefaultFlag ? flags[0] : state.activeFlag, activeProject: setDefaultProject ? projects[0].id : state.activeProject, }); } }); const { activeFlag, activeProject } = state; const setActiveFlag = (flag: PersonalDashboardSchemaFlagsItem) => { setState({ ...state, activeFlag: flag, }); }; const setActiveProject = (projectId: string) => { setState({ ...state, activeProject: projectId, }); }; return { activeFlag, setActiveFlag, activeProject, setActiveProject, }; }; export const PersonalDashboard = () => { const { user } = useAuthUser(); const name = user?.name; const { personalDashboard, refetch: refetchDashboard, loading: personalDashboardLoading, } = usePersonalDashboard(); const projects = personalDashboard?.projects || []; const { activeProject, setActiveProject, activeFlag, setActiveFlag } = useDashboardState(projects, personalDashboard?.flags ?? []); const [welcomeDialog, setWelcomeDialog] = useLocalStorageState< 'open' | 'closed' >('welcome-dialog:v1', 'open'); const { personalDashboardProjectDetails, loading: loadingDetails, error: detailsError, } = usePersonalDashboardProjectDetails(activeProject); const activeProjectStage = personalDashboardProjectDetails?.onboardingStatus.status ?? 'loading'; const setupIncomplete = activeProjectStage === 'onboarding-started' || activeProjectStage === 'first-flag-created'; const noProjects = projects.length === 0; const projectStageRef = useLoading( !detailsError && activeProjectStage === 'loading', ); return (
Welcome {name}

{activeProjectStage === 'onboarded' ? 'We have gathered projects and flags you have favorited or owned' : null} {setupIncomplete ? 'Here are some tasks we think would be useful in order to get the most out of Unleash' : null} {activeProjectStage === 'loading' ? 'We have gathered projects and flags you have favorited or owned' : null}

setWelcomeDialog('open')} >
{noProjects && personalDashboard ? ( ) : ( )} My feature flags {activeFlag ? ( ) : null} {personalDashboard && personalDashboard.flags.length > 0 ? ( {personalDashboard.flags.map((flag) => ( setActiveFlag(flag)} /> ))} ) : ( You have not created or favorited any feature flags. Once you do, they will show up here. )} {activeFlag ? ( ) : ( )} setWelcomeDialog('closed')} />
); }; const FlagMetricsChart = React.lazy(() => import('./FlagMetricsChart').then((module) => ({ default: module.FlagMetricsChart, })), ); const PlaceholderFlagMetricsChart = React.lazy(() => import('./FlagMetricsChart').then((module) => ({ default: module.PlaceholderFlagMetricsChart, })), );