Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(workspaces): remove form from workspace #6754

Merged
merged 18 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 32 additions & 24 deletions frontend/src/features/workspace/WorkspaceContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import { RolloutAnnouncementModal } from '~features/rollout-announcement/Rollout
import { useUser } from '~features/user/queries'

import CreateFormModal from './components/CreateFormModal'
import { EmptyWorkspace } from './components/EmptyWorkspace'
import {
EmptyDefaultWorkspace,
EmptyNewWorkspace,
} from './components/EmptyWorkspace'
import { WorkspaceFormRows } from './components/WorkspaceFormRow'
import { WorkspaceHeader } from './components/WorkspaceHeader'
import { useWorkspaceContext } from './WorkspaceContext'

export const CONTAINER_MAXW = '69.5rem'

export const WorkspaceContent = (): JSX.Element => {
const { isLoading, totalFormsCount, isDefaultWorkspace } =
useWorkspaceContext()
Expand All @@ -43,47 +44,54 @@ export const WorkspaceContent = (): JSX.Element => {
isOpen={createFormModalDisclosure.isOpen}
onClose={createFormModalDisclosure.onClose}
/>
{totalFormsCount === 0 ? (
<EmptyWorkspace
{totalFormsCount === 0 && isDefaultWorkspace ? (
<EmptyDefaultWorkspace
handleOpenCreateFormModal={createFormModalDisclosure.onOpen}
isLoading={isLoading}
isFolder={!isDefaultWorkspace}
/>
) : (
<Grid
bg="neutral.100"
templateColumns="1fr"
templateRows="auto 1fr auto"
minH="100vh"
templateAreas="'header' 'main' 'footer'"
templateAreas=" 'header' 'main'"
overflowY="scroll"
>
<Container
gridArea="header"
maxW={CONTAINER_MAXW}
maxW="100%"
borderBottom="1px solid var(--chakra-colors-neutral-300)"
px="2rem"
px="4rem"
py="1rem"
>
<InlineMessage useMarkdown mb="2rem" mx="-2rem">
{dashboardMessage}
</InlineMessage>
{isDefaultWorkspace && (
<InlineMessage
useMarkdown
mb="2rem"
mx="-2rem"
justifyContent="center"
>
{dashboardMessage}
</InlineMessage>
)}
<WorkspaceHeader
handleOpenCreateFormModal={createFormModalDisclosure.onOpen}
/>
</Container>
<Box gridArea="main">
<RolloutAnnouncementModal
onClose={() => setHasSeenAnnouncement(true)}
isOpen={isAnnouncementModalOpen}
/>
<WorkspaceFormRows />
</Box>
<Container
gridArea="footer"
pt={{ base: '1rem', md: '1.5rem' }}
maxW={CONTAINER_MAXW}
/>
{totalFormsCount === 0 && !isDefaultWorkspace ? (
<EmptyNewWorkspace isLoading={isLoading} />
) : (
<Box gridArea="main">
<RolloutAnnouncementModal
onClose={() => setHasSeenAnnouncement(true)}
isOpen={isAnnouncementModalOpen}
/>
<WorkspaceFormRows />
</Box>
)}

<Container pt={{ base: '1rem', md: '1.5rem' }} />
</Grid>
)}
</>
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/features/workspace/WorkspaceService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ export const deleteWorkspace = async ({
return ApiService.delete(`${ADMIN_WORKSPACES_ENDPOINT}/${destWorkspaceId}`)
}

export const removeFormsFromWorkspaces = async ({
formIds,
}: {
formIds: string[]
}): Promise<void> => {
return ApiService.post(`${ADMIN_WORKSPACES_ENDPOINT}/remove`, { formIds })
}

export const createEmailModeForm = async (
body: CreateEmailFormBodyDto,
): Promise<FormDto> => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { EmptyWorkspace, EmptyWorkspacePage } from './EmptyWorkspace'

export const EmptyDefaultWorkspace = ({
isLoading,
handleOpenCreateFormModal,
}: EmptyWorkspacePage) => (
<EmptyWorkspace
isLoading={isLoading}
handleOpenCreateFormModal={handleOpenCreateFormModal}
title={"You don't have any forms yet"}
subText={'Get started by creating a new form'}
/>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { EmptyWorkspace, EmptyWorkspacePage } from './EmptyWorkspace'

export const EmptyNewWorkspace = ({ isLoading }: EmptyWorkspacePage) => (
<EmptyWorkspace
isLoading={isLoading}
title={'You don’t have any forms in this folder yet'}
subText={'Organise your forms by grouping them into folders'}
/>
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BiPlus } from 'react-icons/bi'
import { Box, Flex, Text } from '@chakra-ui/react'
import { Flex, Text } from '@chakra-ui/react'

import { useIsMobile } from '~hooks/useIsMobile'
import { fillHeightCss } from '~utils/fillHeightCss'
Expand All @@ -9,15 +9,20 @@ import { EmptyWorkspaceSvgr } from './EmptyWorkspaceSvgr'

export interface EmptyWorkspacePage {
isLoading: boolean
handleOpenCreateFormModal: () => void
isFolder?: boolean
handleOpenCreateFormModal?: () => void
}

interface EmptyWorkspaceProps extends EmptyWorkspacePage {
title: string
subText: string
}

export const EmptyWorkspace = ({
isLoading,
handleOpenCreateFormModal,
isFolder,
}: EmptyWorkspacePage): JSX.Element => {
title,
subText,
}: EmptyWorkspaceProps): JSX.Element => {
const isMobile = useIsMobile()

return (
Expand All @@ -31,16 +36,12 @@ export const EmptyWorkspace = ({
css={fillHeightCss}
>
<Text as="h2" textStyle="h2" color="primary.500" mb="1rem">
{isFolder
? 'You don’t have any forms in this folder yet'
: "You don't have any forms yet"}
{title}
</Text>
<Text textStyle="body-1" color="secondary.500">
{isFolder
? 'Organise your forms by grouping them into folders'
: 'Get started by creating a new form'}
{subText}
</Text>
{!isFolder && (
{!!handleOpenCreateFormModal && (
<Button
isFullWidth={isMobile}
isDisabled={isLoading}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { EmptyWorkspace } from './EmptyWorkspace'
export { EmptyDefaultWorkspace } from './EmptyDefaultWorkspace'
export { EmptyNewWorkspace } from './EmptyNewWorkspace'
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const RowActions = (props: RowActionsProps): JSX.Element => {
return (
<Box
pos="absolute"
right="2rem"
right="4rem"
top={{ md: '1.5rem' }}
bottom={{ base: '1.5rem', md: 'initial' }}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,20 +179,26 @@ const MoveWorkspaceDrawer = ({
formMeta: AdminDashboardFormMetaDto
buttonProps: Partial<ButtonProps>
}) => {
const { handleMoveForm } = useRowAction(formMeta)
const { handleRemoveFormFromWorkspaces, handleMoveForm } =
useRowAction(formMeta)
const { workspaces, getFormWorkspace } = useWorkspaceContext()

const handleWorkspaceClick = useCallback(
(destWorkspace: Workspace) =>
handleMoveForm(destWorkspace._id.toString(), destWorkspace.title),
[handleMoveForm],
)

const currFormWorkspace = useMemo(
() => getFormWorkspace(formMeta._id),
[formMeta, getFormWorkspace],
)

// if workspace selected is current workspace, delete
// else move to selected workspace
const handleWorkspaceAction = useCallback(
(destWorkspace: Workspace, currFormWorkspace?: Workspace) => {
if (destWorkspace._id === currFormWorkspace?._id)
handleRemoveFormFromWorkspaces()
else handleMoveForm(destWorkspace._id.toString(), destWorkspace.title)
},
[handleMoveForm, handleRemoveFormFromWorkspaces],
)

if (!workspaces) return null

return (
Expand All @@ -210,7 +216,7 @@ const MoveWorkspaceDrawer = ({
<Button
{...buttonProps}
key={workspace._id}
onClick={() => handleWorkspaceClick(workspace)}
onClick={() => handleWorkspaceAction(workspace, currFormWorkspace)}
>
<Flex justifyContent="space-between" w="100%" alignItems="center">
<Text textStyle="body-1" noOfLines={1}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,26 @@ const MoveWorkspaceDropdown = ({
setIsMoveWorkspace: Dispatch<SetStateAction<boolean>>
formMeta: AdminDashboardFormMetaDto
}) => {
const { handleMoveForm } = useRowAction(formMeta)
const { handleMoveForm, handleRemoveFormFromWorkspaces } =
useRowAction(formMeta)
const { workspaces, getFormWorkspace } = useWorkspaceContext()

const handleWorkspaceClick = useCallback(
(destWorkspace: Workspace) =>
handleMoveForm(destWorkspace._id.toString(), destWorkspace.title),
[handleMoveForm],
)

const currFormWorkspace = useMemo(
() => getFormWorkspace(formMeta._id),
[formMeta, getFormWorkspace],
)

// if workspace selected is current workspace, delete
// else move to selected workspace
const handleWorkspaceAction = useCallback(
(destWorkspace: Workspace, currFormWorkspace?: Workspace) => {
if (destWorkspace._id === currFormWorkspace?._id)
handleRemoveFormFromWorkspaces()
else handleMoveForm(destWorkspace._id.toString(), destWorkspace.title)
},
[handleMoveForm, handleRemoveFormFromWorkspaces],
)

if (!workspaces) return null

return (
Expand All @@ -70,7 +76,7 @@ const MoveWorkspaceDropdown = ({
{workspaces.map((workspace) => (
<Menu.Item
key={workspace._id}
onClick={() => handleWorkspaceClick(workspace)}
onClick={() => handleWorkspaceAction(workspace, currFormWorkspace)}
>
<Flex
justifyContent="space-between"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type UseRowActionReturn = {
handleCollaborators: () => void
handleDeleteForm: () => void
handleShareForm: () => void
handleRemoveFormFromWorkspaces: () => void
handleMoveForm: (destWorkspaceId: string, destWorkspaceTitle: string) => void
isFormAdmin: boolean
}
Expand All @@ -24,7 +25,8 @@ export const useRowAction = (
formMeta: AdminDashboardFormMetaDto,
): UseRowActionReturn => {
const { user } = useUser()
const { moveWorkspaceMutation } = useWorkspaceMutations()
const { moveWorkspaceMutation, removeFormFromWorkspacesMutation } =
useWorkspaceMutations()

const {
onOpenDupeFormModal,
Expand Down Expand Up @@ -79,13 +81,20 @@ export const useRowAction = (
[formMeta, moveWorkspaceMutation],
)

const handleRemoveFormFromWorkspaces = useCallback(async () => {
await removeFormFromWorkspacesMutation.mutateAsync({
formId: formMeta._id.toString(),
})
}, [formMeta, removeFormFromWorkspacesMutation])

return {
adminFormLink,
previewFormLink,
handleShareForm,
handleDuplicateForm,
handleCollaborators,
handleDeleteForm,
handleRemoveFormFromWorkspaces,
handleMoveForm,
isFormAdmin,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Box, Divider, Flex, Stack, Text } from '@chakra-ui/react'

import { CONTAINER_MAXW } from '~features/workspace/WorkspaceContent'
import { useWorkspaceContext } from '~features/workspace/WorkspaceContext'

import { WorkspaceFormRow } from './WorkspaceFormRow'
Expand All @@ -10,7 +9,7 @@ import { WorkspaceRowsProvider } from './WorkspaceRowsContext'

const WorkspaceFormRowsSkeleton = () => {
return (
<Stack maxW={CONTAINER_MAXW} m="auto" spacing={0} divider={<Divider />}>
<Stack m="auto" spacing={0} divider={<Divider />}>
<WorkspaceFormRowSkeleton />
<WorkspaceFormRowSkeleton />
<WorkspaceFormRowSkeleton />
Expand Down Expand Up @@ -51,9 +50,9 @@ export const WorkspaceFormRows = (): JSX.Element => {

return (
<WorkspaceRowsProvider>
<Stack maxW={CONTAINER_MAXW} m="auto" spacing={0} divider={<Divider />}>
<Stack m="auto" spacing={0} divider={<Divider />}>
{displayedForms.map((meta) => (
<WorkspaceFormRow px="2rem" key={meta._id} formMeta={meta} />
<WorkspaceFormRow px="4rem" key={meta._id} formMeta={meta} />
))}
</Stack>
</WorkspaceRowsProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,15 @@ export const WorkspaceHeader = ({
{isDesktop ? (
// Combination box used in desktop mode.
<Box gridArea="searchFilter">
<WorkspaceSearchbar
placeholder="Search by title"
value={activeSearch}
onChange={setActiveSearch}
filterValue={activeFilter}
onFilter={setActiveFilter}
/>
{totalFormsCount ? (
<WorkspaceSearchbar
placeholder="Search by title"
value={activeSearch}
onChange={setActiveSearch}
filterValue={activeFilter}
onFilter={setActiveFilter}
/>
) : null}
</Box>
) : (
<MobileWorkspaceSearchbar
Expand Down
Loading