1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-25 00:07:47 +01:00

fix: make rendering of new project form independent of rendering the project list (#7405)

This change takes the rendering of the new project form component and
puts in a child component of the project list, thereby
significantly speeding up the time it takes to render the form if you
have lots of projects (about to 10x for 50 projects on my machine).

The reason it was so slow before was that the open state of the form
component was stored in the project list component. This meant that
whenever you wanted to open or close the form, you'd have to rerender
the entire project list.

This change abstracts that process into the new ProjectCreationButton
component. This component takes care of checking the feature flag for
whether to render the dialog or to send the user to the old form, and
takes care of state management for the dialog.

Because this is a child component of the project list, it does not
cause rerenders of the entire project list.
This commit is contained in:
Thomas Heartman 2024-06-18 09:36:36 +02:00 committed by GitHub
parent 3f5cf3baac
commit 1f4126e495
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -87,12 +87,56 @@ function resolveCreateButtonData(
}
}
export const ProjectListNew = () => {
const ProjectCreationButton = () => {
const [searchParams] = useSearchParams();
const showCreateDialog = Boolean(searchParams.get('create'));
const [openCreateDialog, setOpenCreateDialog] = useState(showCreateDialog);
const { hasAccess } = useContext(AccessContext);
const navigate = useNavigate();
const { projects, loading, error, refetch } = useProjects();
const { isOss } = useUiConfig();
const createButtonData = resolveCreateButtonData(
isOss(),
hasAccess(CREATE_PROJECT),
);
const useNewProjectForm = useUiFlag('newCreateProjectUI');
const CreateButton: React.FC<{ onClick: () => void }> = ({ onClick }) => {
return (
<ResponsiveButton
Icon={Add}
endIcon={createButtonData.endIcon}
onClick={onClick}
maxWidth='700px'
permission={CREATE_PROJECT}
disabled={createButtonData.disabled}
tooltipProps={createButtonData.tooltip}
data-testid={NAVIGATE_TO_CREATE_PROJECT}
>
New project
</ResponsiveButton>
);
};
if (useNewProjectForm) {
return (
<>
<CreateButton onClick={() => setOpenCreateDialog(true)} />
<CreateProjectDialog
open={openCreateDialog}
onClose={() => setOpenCreateDialog(false)}
/>
</>
);
} else {
return <CreateButton onClick={() => navigate('/projects/create')} />;
}
};
export const ProjectListNew = () => {
const { projects, loading, error, refetch } = useProjects();
const isSmallScreen = useMediaQuery(theme.breakpoints.down('md'));
const [searchParams, setSearchParams] = useSearchParams();
const [searchValue, setSearchValue] = useState(
@ -101,10 +145,6 @@ export const ProjectListNew = () => {
const myProjects = new Set(useProfile().profile?.projects || []);
const showCreateDialog = Boolean(searchParams.get('create'));
const [openCreateDialog, setOpenCreateDialog] = useState(showCreateDialog);
const useNewProjectForm = useUiFlag('newCreateProjectUI');
useEffect(() => {
const tableState: PageQueryType = {};
if (searchValue) {
@ -137,11 +177,6 @@ export const ProjectListNew = () => {
return groupProjects(myProjects, filteredProjects);
}, [filteredProjects, myProjects]);
const createButtonData = resolveCreateButtonData(
isOss(),
hasAccess(CREATE_PROJECT),
);
const projectCount =
filteredProjects.length < projects.length
? `${filteredProjects.length} of ${projects.length}`
@ -160,13 +195,6 @@ export const ProjectListNew = () => {
);
};
function handleClick() {
if (useNewProjectForm) {
return setOpenCreateDialog(true);
}
navigate('/projects/create');
}
return (
<PageContent
isLoading={loading}
@ -187,18 +215,7 @@ export const ProjectListNew = () => {
</>
}
/>
<ResponsiveButton
Icon={Add}
endIcon={createButtonData.endIcon}
onClick={handleClick}
maxWidth='700px'
permission={CREATE_PROJECT}
disabled={createButtonData.disabled}
tooltipProps={createButtonData.tooltip}
data-testid={NAVIGATE_TO_CREATE_PROJECT}
>
New project
</ResponsiveButton>
<ProjectCreationButton />
</>
}
>
@ -234,15 +251,6 @@ export const ProjectListNew = () => {
projects={groupedProjects.otherProjects}
/>
</StyledContainer>
<ConditionallyRender
condition={useNewProjectForm}
show={
<CreateProjectDialog
open={openCreateDialog}
onClose={() => setOpenCreateDialog(false)}
/>
}
/>
</PageContent>
);
};