mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: open/close animation on personal dashboard is choppy (#9253)
Extracts each panel into its own component for the personal dashboard.
This lets us use separate states for each panel, which in turn lets each
panel change its open / close state without causing the other panels to
re-render.
When you have a lot of flags and/or projects, the list to render becomes
very long, which causes performance problems, especially when you need
to rerender both flags and projects and the timeline whenever one of
them changes.
The problems were especially noticeable in Firefox for me. Even with
this, the event timeline is a little choppy. I suspect that's because of
it might take a long time to paint? But we can look into that later.
Also updates the dashboard state hook to let you only pass in the
flags/projects you want. We could extract this into three different
hooks that all use the same localhost key, but I'm not sure whether
that's better or worse 🤷🏼
			
			
This commit is contained in:
		
							parent
							
								
									ccd8de6e74
								
							
						
					
					
						commit
						2b668bc5c8
					
				@ -111,6 +111,158 @@ const AccordionSummarySubtitle = styled(Typography)(({ theme }) => ({
 | 
				
			|||||||
    fontWeight: theme.typography.body2.fontWeight,
 | 
					    fontWeight: theme.typography.body2.fontWeight,
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const EventTimelinePanel = () => {
 | 
				
			||||||
 | 
					    const { toggleSectionState, expandTimeline } = useDashboardState();
 | 
				
			||||||
 | 
					    const { trackEvent } = usePlausibleTracker();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const signalsLink = '/integrations/signals';
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <SectionAccordion
 | 
				
			||||||
 | 
					            disableGutters
 | 
				
			||||||
 | 
					            expanded={expandTimeline ?? false}
 | 
				
			||||||
 | 
					            onChange={() => toggleSectionState('timeline')}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <StyledAccordionSummary
 | 
				
			||||||
 | 
					                expandIcon={
 | 
				
			||||||
 | 
					                    <ExpandMore titleAccess='Toggle timeline section' />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                id='timeline-panel-header'
 | 
				
			||||||
 | 
					                aria-controls='timeline-panel-content'
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                <AccordionSummaryText>
 | 
				
			||||||
 | 
					                    <AccordionSummaryHeader>
 | 
				
			||||||
 | 
					                        Event timeline
 | 
				
			||||||
 | 
					                    </AccordionSummaryHeader>
 | 
				
			||||||
 | 
					                    <AccordionSummarySubtitle>
 | 
				
			||||||
 | 
					                        Overview of recent activities across all projects in
 | 
				
			||||||
 | 
					                        Unleash. Make debugging easier and{' '}
 | 
				
			||||||
 | 
					                        <Link
 | 
				
			||||||
 | 
					                            to={signalsLink}
 | 
				
			||||||
 | 
					                            onClick={() => {
 | 
				
			||||||
 | 
					                                trackEvent('event-timeline', {
 | 
				
			||||||
 | 
					                                    props: {
 | 
				
			||||||
 | 
					                                        eventType: 'signals clicked',
 | 
				
			||||||
 | 
					                                    },
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                            }}
 | 
				
			||||||
 | 
					                        >
 | 
				
			||||||
 | 
					                            include external signals
 | 
				
			||||||
 | 
					                        </Link>{' '}
 | 
				
			||||||
 | 
					                        to get a fuller overview.
 | 
				
			||||||
 | 
					                    </AccordionSummarySubtitle>
 | 
				
			||||||
 | 
					                </AccordionSummaryText>
 | 
				
			||||||
 | 
					            </StyledAccordionSummary>
 | 
				
			||||||
 | 
					            <StyledAccordionDetails>
 | 
				
			||||||
 | 
					                <AccordionContent>
 | 
				
			||||||
 | 
					                    <EventTimeline />
 | 
				
			||||||
 | 
					                </AccordionContent>
 | 
				
			||||||
 | 
					            </StyledAccordionDetails>
 | 
				
			||||||
 | 
					        </SectionAccordion>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const FlagPanel = () => {
 | 
				
			||||||
 | 
					    const { personalDashboard, refetch: refetchDashboard } =
 | 
				
			||||||
 | 
					        usePersonalDashboard();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const projects = personalDashboard?.projects || [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const { activeFlag, setActiveFlag, toggleSectionState, expandFlags } =
 | 
				
			||||||
 | 
					        useDashboardState({ flags: personalDashboard?.flags ?? [] });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <SectionAccordion
 | 
				
			||||||
 | 
					            expanded={expandFlags ?? true}
 | 
				
			||||||
 | 
					            onChange={() => toggleSectionState('flags')}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <StyledAccordionSummaryWithBorder
 | 
				
			||||||
 | 
					                expandIcon={<ExpandMore titleAccess='Toggle flags section' />}
 | 
				
			||||||
 | 
					                id='flags-panel-header'
 | 
				
			||||||
 | 
					                aria-controls='flags-panel-content'
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                <AccordionSummaryText>
 | 
				
			||||||
 | 
					                    <AccordionSummaryHeader>
 | 
				
			||||||
 | 
					                        My feature flags
 | 
				
			||||||
 | 
					                    </AccordionSummaryHeader>
 | 
				
			||||||
 | 
					                    <AccordionSummarySubtitle>
 | 
				
			||||||
 | 
					                        Feature flags you have created or favorited
 | 
				
			||||||
 | 
					                    </AccordionSummarySubtitle>
 | 
				
			||||||
 | 
					                </AccordionSummaryText>
 | 
				
			||||||
 | 
					            </StyledAccordionSummaryWithBorder>
 | 
				
			||||||
 | 
					            <StyledAccordionDetails>
 | 
				
			||||||
 | 
					                <MyFlags
 | 
				
			||||||
 | 
					                    hasProjects={projects?.length > 0}
 | 
				
			||||||
 | 
					                    flagData={
 | 
				
			||||||
 | 
					                        personalDashboard?.flags.length
 | 
				
			||||||
 | 
					                            ? {
 | 
				
			||||||
 | 
					                                  state: 'flags' as const,
 | 
				
			||||||
 | 
					                                  activeFlag,
 | 
				
			||||||
 | 
					                                  flags: personalDashboard.flags,
 | 
				
			||||||
 | 
					                              }
 | 
				
			||||||
 | 
					                            : { state: 'no flags' as const }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    setActiveFlag={setActiveFlag}
 | 
				
			||||||
 | 
					                    refetchDashboard={refetchDashboard}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					            </StyledAccordionDetails>
 | 
				
			||||||
 | 
					        </SectionAccordion>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ProjectPanel = () => {
 | 
				
			||||||
 | 
					    const { personalDashboard } = usePersonalDashboard();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const projects = personalDashboard?.projects || [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const {
 | 
				
			||||||
 | 
					        activeProject,
 | 
				
			||||||
 | 
					        setActiveProject,
 | 
				
			||||||
 | 
					        toggleSectionState,
 | 
				
			||||||
 | 
					        expandProjects,
 | 
				
			||||||
 | 
					    } = useDashboardState({ projects });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const personalDashboardProjectDetails =
 | 
				
			||||||
 | 
					        fromPersonalDashboardProjectDetailsOutput(
 | 
				
			||||||
 | 
					            usePersonalDashboardProjectDetails(activeProject),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <SectionAccordion
 | 
				
			||||||
 | 
					            disableGutters
 | 
				
			||||||
 | 
					            expanded={expandProjects ?? true}
 | 
				
			||||||
 | 
					            onChange={() => toggleSectionState('projects')}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <StyledAccordionSummaryWithBorder
 | 
				
			||||||
 | 
					                expandIcon={
 | 
				
			||||||
 | 
					                    <ExpandMore titleAccess='Toggle projects section' />
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                id='projects-panel-header'
 | 
				
			||||||
 | 
					                aria-controls='projects-panel-content'
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                <AccordionSummaryText>
 | 
				
			||||||
 | 
					                    <AccordionSummaryHeader>My projects</AccordionSummaryHeader>
 | 
				
			||||||
 | 
					                    <AccordionSummarySubtitle>
 | 
				
			||||||
 | 
					                        Favorite projects, projects you own, and projects you
 | 
				
			||||||
 | 
					                        are a member of
 | 
				
			||||||
 | 
					                    </AccordionSummarySubtitle>
 | 
				
			||||||
 | 
					                </AccordionSummaryText>
 | 
				
			||||||
 | 
					            </StyledAccordionSummaryWithBorder>
 | 
				
			||||||
 | 
					            <StyledAccordionDetails>
 | 
				
			||||||
 | 
					                <MyProjects
 | 
				
			||||||
 | 
					                    owners={personalDashboard?.projectOwners ?? []}
 | 
				
			||||||
 | 
					                    admins={personalDashboard?.admins ?? []}
 | 
				
			||||||
 | 
					                    projects={projects}
 | 
				
			||||||
 | 
					                    activeProject={activeProject || ''}
 | 
				
			||||||
 | 
					                    setActiveProject={setActiveProject}
 | 
				
			||||||
 | 
					                    personalDashboardProjectDetails={
 | 
				
			||||||
 | 
					                        personalDashboardProjectDetails
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					            </StyledAccordionDetails>
 | 
				
			||||||
 | 
					        </SectionAccordion>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const PersonalDashboard = () => {
 | 
					export const PersonalDashboard = () => {
 | 
				
			||||||
    const { user } = useAuthUser();
 | 
					    const { user } = useAuthUser();
 | 
				
			||||||
    const { trackEvent } = usePlausibleTracker();
 | 
					    const { trackEvent } = usePlausibleTracker();
 | 
				
			||||||
@ -122,24 +274,6 @@ export const PersonalDashboard = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    usePageTitle(name ? `Dashboard: ${name}` : 'Dashboard');
 | 
					    usePageTitle(name ? `Dashboard: ${name}` : 'Dashboard');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { personalDashboard, refetch: refetchDashboard } =
 | 
					 | 
				
			||||||
        usePersonalDashboard();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const projects = personalDashboard?.projects || [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const {
 | 
					 | 
				
			||||||
        activeProject,
 | 
					 | 
				
			||||||
        setActiveProject,
 | 
					 | 
				
			||||||
        activeFlag,
 | 
					 | 
				
			||||||
        setActiveFlag,
 | 
					 | 
				
			||||||
        toggleSectionState,
 | 
					 | 
				
			||||||
        expandFlags,
 | 
					 | 
				
			||||||
        expandProjects,
 | 
					 | 
				
			||||||
        expandTimeline,
 | 
					 | 
				
			||||||
    } = useDashboardState(projects, personalDashboard?.flags ?? []);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const signalsLink = '/integrations/signals';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const [welcomeDialog, setWelcomeDialog] = useLocalStorageState<
 | 
					    const [welcomeDialog, setWelcomeDialog] = useLocalStorageState<
 | 
				
			||||||
        'open' | 'closed'
 | 
					        'open' | 'closed'
 | 
				
			||||||
    >(
 | 
					    >(
 | 
				
			||||||
@ -147,11 +281,6 @@ export const PersonalDashboard = () => {
 | 
				
			|||||||
        splash?.personalDashboardKeyConcepts ? 'closed' : 'open',
 | 
					        splash?.personalDashboardKeyConcepts ? 'closed' : 'open',
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const personalDashboardProjectDetails =
 | 
					 | 
				
			||||||
        fromPersonalDashboardProjectDetailsOutput(
 | 
					 | 
				
			||||||
            usePersonalDashboardProjectDetails(activeProject),
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
        trackEvent('personal-dashboard', {
 | 
					        trackEvent('personal-dashboard', {
 | 
				
			||||||
            props: {
 | 
					            props: {
 | 
				
			||||||
@ -188,122 +317,12 @@ export const PersonalDashboard = () => {
 | 
				
			|||||||
                </ViewKeyConceptsButton>
 | 
					                </ViewKeyConceptsButton>
 | 
				
			||||||
            </WelcomeSection>
 | 
					            </WelcomeSection>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            {showTimelinePanel && (
 | 
					            {showTimelinePanel && <EventTimelinePanel />}
 | 
				
			||||||
                <SectionAccordion
 | 
					
 | 
				
			||||||
                    disableGutters
 | 
					            <ProjectPanel />
 | 
				
			||||||
                    expanded={expandTimeline ?? false}
 | 
					
 | 
				
			||||||
                    onChange={() => toggleSectionState('timeline')}
 | 
					            <FlagPanel />
 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                    <StyledAccordionSummary
 | 
					 | 
				
			||||||
                        expandIcon={
 | 
					 | 
				
			||||||
                            <ExpandMore titleAccess='Toggle timeline section' />
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        id='timeline-panel-header'
 | 
					 | 
				
			||||||
                        aria-controls='timeline-panel-content'
 | 
					 | 
				
			||||||
                    >
 | 
					 | 
				
			||||||
                        <AccordionSummaryText>
 | 
					 | 
				
			||||||
                            <AccordionSummaryHeader>
 | 
					 | 
				
			||||||
                                Event timeline
 | 
					 | 
				
			||||||
                            </AccordionSummaryHeader>
 | 
					 | 
				
			||||||
                            <AccordionSummarySubtitle>
 | 
					 | 
				
			||||||
                                Overview of recent activities across all
 | 
					 | 
				
			||||||
                                projects in Unleash. Make debugging easier and{' '}
 | 
					 | 
				
			||||||
                                <Link
 | 
					 | 
				
			||||||
                                    to={signalsLink}
 | 
					 | 
				
			||||||
                                    onClick={() => {
 | 
					 | 
				
			||||||
                                        trackEvent('event-timeline', {
 | 
					 | 
				
			||||||
                                            props: {
 | 
					 | 
				
			||||||
                                                eventType: 'signals clicked',
 | 
					 | 
				
			||||||
                                            },
 | 
					 | 
				
			||||||
                                        });
 | 
					 | 
				
			||||||
                                    }}
 | 
					 | 
				
			||||||
                                >
 | 
					 | 
				
			||||||
                                    include external signals
 | 
					 | 
				
			||||||
                                </Link>{' '}
 | 
					 | 
				
			||||||
                                to get a fuller overview.
 | 
					 | 
				
			||||||
                            </AccordionSummarySubtitle>
 | 
					 | 
				
			||||||
                        </AccordionSummaryText>
 | 
					 | 
				
			||||||
                    </StyledAccordionSummary>
 | 
					 | 
				
			||||||
                    <StyledAccordionDetails>
 | 
					 | 
				
			||||||
                        <AccordionContent>
 | 
					 | 
				
			||||||
                            <EventTimeline />
 | 
					 | 
				
			||||||
                        </AccordionContent>
 | 
					 | 
				
			||||||
                    </StyledAccordionDetails>
 | 
					 | 
				
			||||||
                </SectionAccordion>
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
            <SectionAccordion
 | 
					 | 
				
			||||||
                disableGutters
 | 
					 | 
				
			||||||
                expanded={expandProjects ?? true}
 | 
					 | 
				
			||||||
                onChange={() => toggleSectionState('projects')}
 | 
					 | 
				
			||||||
            >
 | 
					 | 
				
			||||||
                <StyledAccordionSummaryWithBorder
 | 
					 | 
				
			||||||
                    expandIcon={
 | 
					 | 
				
			||||||
                        <ExpandMore titleAccess='Toggle projects section' />
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    id='projects-panel-header'
 | 
					 | 
				
			||||||
                    aria-controls='projects-panel-content'
 | 
					 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                    <AccordionSummaryText>
 | 
					 | 
				
			||||||
                        <AccordionSummaryHeader>
 | 
					 | 
				
			||||||
                            My projects
 | 
					 | 
				
			||||||
                        </AccordionSummaryHeader>
 | 
					 | 
				
			||||||
                        <AccordionSummarySubtitle>
 | 
					 | 
				
			||||||
                            Favorite projects, projects you own, and projects
 | 
					 | 
				
			||||||
                            you are a member of
 | 
					 | 
				
			||||||
                        </AccordionSummarySubtitle>
 | 
					 | 
				
			||||||
                    </AccordionSummaryText>
 | 
					 | 
				
			||||||
                </StyledAccordionSummaryWithBorder>
 | 
					 | 
				
			||||||
                <StyledAccordionDetails>
 | 
					 | 
				
			||||||
                    <MyProjects
 | 
					 | 
				
			||||||
                        owners={personalDashboard?.projectOwners ?? []}
 | 
					 | 
				
			||||||
                        admins={personalDashboard?.admins ?? []}
 | 
					 | 
				
			||||||
                        projects={projects}
 | 
					 | 
				
			||||||
                        activeProject={activeProject || ''}
 | 
					 | 
				
			||||||
                        setActiveProject={setActiveProject}
 | 
					 | 
				
			||||||
                        personalDashboardProjectDetails={
 | 
					 | 
				
			||||||
                            personalDashboardProjectDetails
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    />
 | 
					 | 
				
			||||||
                </StyledAccordionDetails>
 | 
					 | 
				
			||||||
            </SectionAccordion>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <SectionAccordion
 | 
					 | 
				
			||||||
                expanded={expandFlags ?? true}
 | 
					 | 
				
			||||||
                onChange={() => toggleSectionState('flags')}
 | 
					 | 
				
			||||||
            >
 | 
					 | 
				
			||||||
                <StyledAccordionSummaryWithBorder
 | 
					 | 
				
			||||||
                    expandIcon={
 | 
					 | 
				
			||||||
                        <ExpandMore titleAccess='Toggle flags section' />
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    id='flags-panel-header'
 | 
					 | 
				
			||||||
                    aria-controls='flags-panel-content'
 | 
					 | 
				
			||||||
                >
 | 
					 | 
				
			||||||
                    <AccordionSummaryText>
 | 
					 | 
				
			||||||
                        <AccordionSummaryHeader>
 | 
					 | 
				
			||||||
                            My feature flags
 | 
					 | 
				
			||||||
                        </AccordionSummaryHeader>
 | 
					 | 
				
			||||||
                        <AccordionSummarySubtitle>
 | 
					 | 
				
			||||||
                            Feature flags you have created or favorited
 | 
					 | 
				
			||||||
                        </AccordionSummarySubtitle>
 | 
					 | 
				
			||||||
                    </AccordionSummaryText>
 | 
					 | 
				
			||||||
                </StyledAccordionSummaryWithBorder>
 | 
					 | 
				
			||||||
                <StyledAccordionDetails>
 | 
					 | 
				
			||||||
                    <MyFlags
 | 
					 | 
				
			||||||
                        hasProjects={projects?.length > 0}
 | 
					 | 
				
			||||||
                        flagData={
 | 
					 | 
				
			||||||
                            personalDashboard?.flags.length
 | 
					 | 
				
			||||||
                                ? {
 | 
					 | 
				
			||||||
                                      state: 'flags' as const,
 | 
					 | 
				
			||||||
                                      activeFlag,
 | 
					 | 
				
			||||||
                                      flags: personalDashboard.flags,
 | 
					 | 
				
			||||||
                                  }
 | 
					 | 
				
			||||||
                                : { state: 'no flags' as const }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        setActiveFlag={setActiveFlag}
 | 
					 | 
				
			||||||
                        refetchDashboard={refetchDashboard}
 | 
					 | 
				
			||||||
                    />
 | 
					 | 
				
			||||||
                </StyledAccordionDetails>
 | 
					 | 
				
			||||||
            </SectionAccordion>
 | 
					 | 
				
			||||||
            <WelcomeDialog
 | 
					            <WelcomeDialog
 | 
				
			||||||
                open={welcomeDialog === 'open'}
 | 
					                open={welcomeDialog === 'open'}
 | 
				
			||||||
                onClose={() => {
 | 
					                onClose={() => {
 | 
				
			||||||
 | 
				
			|||||||
@ -5,10 +5,11 @@ import type {
 | 
				
			|||||||
} from 'openapi';
 | 
					} from 'openapi';
 | 
				
			||||||
import { useEffect } from 'react';
 | 
					import { useEffect } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const useDashboardState = (
 | 
					type StateProps = {
 | 
				
			||||||
    projects: PersonalDashboardSchemaProjectsItem[],
 | 
					    projects?: PersonalDashboardSchemaProjectsItem[];
 | 
				
			||||||
    flags: PersonalDashboardSchemaFlagsItem[],
 | 
					    flags?: PersonalDashboardSchemaFlagsItem[];
 | 
				
			||||||
) => {
 | 
					};
 | 
				
			||||||
 | 
					export const useDashboardState = (props?: StateProps) => {
 | 
				
			||||||
    type State = {
 | 
					    type State = {
 | 
				
			||||||
        activeProject: string | undefined;
 | 
					        activeProject: string | undefined;
 | 
				
			||||||
        activeFlag: PersonalDashboardSchemaFlagsItem | undefined;
 | 
					        activeFlag: PersonalDashboardSchemaFlagsItem | undefined;
 | 
				
			||||||
@ -35,34 +36,31 @@ export const useDashboardState = (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
        const updates: Partial<State> = {};
 | 
					        const updates: Partial<State> = {};
 | 
				
			||||||
        const setDefaultFlag =
 | 
					 | 
				
			||||||
            flags.length &&
 | 
					 | 
				
			||||||
            (!state.activeFlag ||
 | 
					 | 
				
			||||||
                !flags.some((flag) => flag.name === state.activeFlag?.name));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (setDefaultFlag) {
 | 
					        if (
 | 
				
			||||||
            updates.activeFlag = flags[0];
 | 
					            props?.flags?.length &&
 | 
				
			||||||
 | 
					            (!state.activeFlag ||
 | 
				
			||||||
 | 
					                !props.flags.some(
 | 
				
			||||||
 | 
					                    (flag) => flag.name === state.activeFlag?.name,
 | 
				
			||||||
 | 
					                ))
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            updates.activeFlag = props.flags[0];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const setDefaultProject =
 | 
					        if (
 | 
				
			||||||
            projects.length &&
 | 
					            props?.projects?.length &&
 | 
				
			||||||
            (!state.activeProject ||
 | 
					            (!state.activeProject ||
 | 
				
			||||||
                !projects.some(
 | 
					                !props.projects.some(
 | 
				
			||||||
                    (project) => project.id === state.activeProject,
 | 
					                    (project) => project.id === state.activeProject,
 | 
				
			||||||
                ));
 | 
					                ))
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
        if (setDefaultProject) {
 | 
					            updates.activeProject = props.projects[0].id;
 | 
				
			||||||
            updates.activeProject = projects[0].id;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Object.keys(updates).length) {
 | 
					        if (Object.keys(updates).length) {
 | 
				
			||||||
            updateState(updates);
 | 
					            updateState(updates);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }, [
 | 
					    }, [JSON.stringify(props), JSON.stringify(state)]);
 | 
				
			||||||
        JSON.stringify(projects),
 | 
					 | 
				
			||||||
        JSON.stringify(flags),
 | 
					 | 
				
			||||||
        JSON.stringify(state),
 | 
					 | 
				
			||||||
    ]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { activeFlag, activeProject } = state;
 | 
					    const { activeFlag, activeProject } = state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user