From c9a564a55613850c516282d3afb1e38a38a8ae66 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Fri, 1 Nov 2024 13:04:22 +0100 Subject: [PATCH] chore: add placeholder project status sidebar (#8629) This PR adds an empty placeholder sidebar for the project status content. It also adds a button to open the sidebar. Additionally, because the button to open the sidebar takes the place of the existing "import" button, the import button has also been moved down to the filter row. Of course, these changes are all behind the flag, so if nothing should change if the flag is not enabled. ![image](https://github.com/user-attachments/assets/ca2d6136-5705-4ec0-9c26-21981827ca07) ![image](https://github.com/user-attachments/assets/383d2a09-ab56-4ff6-b801-df9da5a19765) --- frontend/src/assets/icons/projectStatus.svg | 3 ++ .../project/Project/Import/ImportModal.tsx | 2 +- .../ProjectFeatureToggles.tsx | 53 ++++++++++++++++--- .../src/component/project/Project/Project.tsx | 36 ++++++++++--- .../project/Project/ProjectStatusModal.tsx | 21 ++++++++ 5 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 frontend/src/assets/icons/projectStatus.svg create mode 100644 frontend/src/component/project/Project/ProjectStatusModal.tsx diff --git a/frontend/src/assets/icons/projectStatus.svg b/frontend/src/assets/icons/projectStatus.svg new file mode 100644 index 0000000000..713e29eb62 --- /dev/null +++ b/frontend/src/assets/icons/projectStatus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/frontend/src/component/project/Project/Import/ImportModal.tsx b/frontend/src/component/project/Project/Import/ImportModal.tsx index 9147065a72..7418be897a 100644 --- a/frontend/src/component/project/Project/Import/ImportModal.tsx +++ b/frontend/src/component/project/Project/Import/ImportModal.tsx @@ -73,7 +73,7 @@ export const ImportModal = ({ open, setOpen, project }: IImportModalProps) => { }; return ( - + Process diff --git a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx index 73524c4f5b..50bee4226d 100644 --- a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -1,3 +1,4 @@ +import { ReactComponent as ImportSvg } from 'assets/icons/import.svg'; import { useCallback, useMemo, useState } from 'react'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { PageContent } from 'component/common/PageContent/PageContent'; @@ -49,6 +50,10 @@ import { ProjectOnboarded } from 'component/onboarding/flow/ProjectOnboarded'; import { usePlausibleTracker } from 'hooks/usePlausibleTracker'; import { ArchivedFeatureActionCell } from '../../../archive/ArchiveTable/ArchivedFeatureActionCell/ArchivedFeatureActionCell'; import { ArchiveBatchActions } from '../../../archive/ArchiveTable/ArchiveBatchActions'; +import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; +import { UPDATE_FEATURE } from '@server/types/permissions'; +import { ImportModal } from '../Import/ImportModal'; +import { IMPORT_BUTTON } from 'utils/testIds'; interface IPaginatedProjectFeatureTogglesProps { environments: string[]; @@ -66,6 +71,19 @@ const Container = styled('div')(({ theme }) => ({ gap: theme.spacing(2), })); +const FilterRow = styled('div')(({ theme }) => ({ + display: 'flex', + flexFlow: 'row wrap', + gap: theme.spacing(2), + justifyContent: 'space-between', +})); + +const ButtonGroup = styled('div')(({ theme }) => ({ + display: 'flex', + gap: theme.spacing(1), + paddingInline: theme.spacing(1.5), +})); + export const ProjectFeatureToggles = ({ environments, }: IPaginatedProjectFeatureTogglesProps) => { @@ -74,6 +92,8 @@ export const ProjectFeatureToggles = ({ const projectId = useRequiredPathParam('projectId'); const { project } = useProjectOverview(projectId); const [connectSdkOpen, setConnectSdkOpen] = useState(false); + const simplifyProjectOverview = useUiFlag('simplifyProjectOverview'); + const [modalOpen, setModalOpen] = useState(false); const { features, @@ -561,11 +581,27 @@ export const ProjectFeatureToggles = ({ aria-busy={isPlaceholder} aria-live='polite' > - + + + {simplifyProjectOverview && ( + + setModalOpen(true)} + tooltipProps={{ title: 'Import' }} + data-testid={IMPORT_BUTTON} + data-loading-project + > + + + + )} + @@ -583,7 +619,6 @@ export const ProjectFeatureToggles = ({ } /> {rowActionsDialogs} - {featureToggleModals} @@ -627,6 +662,12 @@ export const ProjectFeatureToggles = ({ /> )} + + ); }; diff --git a/frontend/src/component/project/Project/Project.tsx b/frontend/src/component/project/Project/Project.tsx index 029624a29d..0a3f6f0e45 100644 --- a/frontend/src/component/project/Project/Project.tsx +++ b/frontend/src/component/project/Project/Project.tsx @@ -2,6 +2,7 @@ import { useNavigate } from 'react-router'; import useLoading from 'hooks/useLoading'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ReactComponent as ImportSvg } from 'assets/icons/import.svg'; +import { ReactComponent as ProjectStatusSvg } from 'assets/icons/projectStatus.svg'; import { StyledDiv, StyledFavoriteIconButton, @@ -21,15 +22,11 @@ import { Tabs, Typography, styled, + Button, } from '@mui/material'; import useToast from 'hooks/useToast'; import useQueryParams from 'hooks/useQueryParams'; -import { - type PropsWithChildren, - useEffect, - useState, - type ReactNode, -} from 'react'; +import { useEffect, useState, type ReactNode } from 'react'; import ProjectEnvironment from '../ProjectEnvironment/ProjectEnvironment'; import { ProjectFeaturesArchive } from './ProjectFeaturesArchive/ProjectFeaturesArchive'; import ProjectFlags from './ProjectFlags'; @@ -59,6 +56,7 @@ import { ProjectArchived } from './ArchiveProject/ProjectArchived'; import { usePlausibleTracker } from '../../../hooks/usePlausibleTracker'; import { useUiFlag } from 'hooks/useUiFlag'; import { useActionableChangeRequests } from 'hooks/api/getters/useActionableChangeRequests/useActionableChangeRequests'; +import { ProjectStatusModal } from './ProjectStatusModal'; const StyledBadge = styled(Badge)(({ theme }) => ({ position: 'absolute', @@ -105,6 +103,15 @@ const ChangeRequestsLabel = () => { ); }; +const ProjectStatusButton = styled(Button)(({ theme }) => ({ + color: theme.palette.text.primary, + fontSize: theme.typography.body1.fontSize, + fontWeight: 'bold', + 'svg *': { + fill: theme.palette.primary.main, + }, +})); + export const Project = () => { const projectId = useRequiredPathParam('projectId'); const { trackEvent } = usePlausibleTracker(); @@ -120,6 +127,7 @@ export const Project = () => { const projectName = project?.name || projectId; const { favorite, unfavorite } = useFavoriteProjectsApi(); const simplifyProjectOverview = useUiFlag('simplifyProjectOverview'); + const [projectStatusOpen, setProjectStatusOpen] = useState(false); const [showDelDialog, setShowDelDialog] = useState(false); @@ -266,7 +274,8 @@ export const Project = () => { { } /> + {simplifyProjectOverview && ( + setProjectStatusOpen(true)} + startIcon={} + data-loading-project + > + Project status + + )} @@ -393,6 +411,10 @@ export const Project = () => { setOpen={setModalOpen} project={projectId} /> + setProjectStatusOpen(false)} + /> ); }; diff --git a/frontend/src/component/project/Project/ProjectStatusModal.tsx b/frontend/src/component/project/Project/ProjectStatusModal.tsx new file mode 100644 index 0000000000..fbea8e31b3 --- /dev/null +++ b/frontend/src/component/project/Project/ProjectStatusModal.tsx @@ -0,0 +1,21 @@ +import { styled } from '@mui/material'; +import { SidebarModal } from 'component/common/SidebarModal/SidebarModal'; + +const ModalContentContainer = styled('div')(({ theme }) => ({ + minHeight: '100vh', + display: 'flex', + backgroundColor: theme.palette.background.default, +})); + +type Props = { + open: boolean; + close: () => void; +}; + +export const ProjectStatusModal = ({ open, close }: Props) => { + return ( + + + + ); +};