From 475201d42f246caa5092e89aee32c930cf07aef0 Mon Sep 17 00:00:00 2001 From: Jessica Lawshe Date: Fri, 16 Sep 2022 09:02:08 -0500 Subject: [PATCH] Merge pull request #9603 from overleaf/jel-project-tools [web] Begin project tools for React dash GitOrigin-RevId: a735864153f836ca01135001c661aa31ec52cfa8 --- .../components/project-list-root.tsx | 17 +- .../action-buttons/archive-project-button.tsx | 14 -- .../action-buttons/delete-project-button.tsx | 8 - .../action-buttons/leave-project-buttton.tsx | 10 +- .../action-buttons/trash-project-button.tsx | 14 -- .../table/project-list-table-row.tsx | 28 ++- .../components/table/project-list-table.tsx | 31 ++- .../buttons/archive-projects-button.tsx | 65 ++++++ .../buttons/download-projects-button.tsx | 46 +++++ .../buttons/trash-projects-button.tsx | 66 ++++++ .../table/project-tools/project-tools.tsx | 20 ++ .../table/projects-action-modal.tsx | 60 +++++- .../context/project-list-context.tsx | 9 + .../components/project-list-root.test.tsx | 188 ++++++++++++++++++ .../table/project-list-table.test.tsx | 104 ++++++---- .../buttons/archive-projects.button.test.tsx | 26 +++ .../buttons/download-projects-button.test.tsx | 19 ++ .../buttons/trash-projects.button.test.tsx | 26 +++ .../project-tools/project-tools.test.tsx | 21 ++ .../table/projects-action-modal.test.tsx | 15 -- .../project-list/fixtures/projects-data.ts | 4 + .../helpers/render-with-context.js | 6 +- 22 files changed, 680 insertions(+), 117 deletions(-) create mode 100644 services/web/frontend/js/features/project-list/components/table/project-tools/buttons/archive-projects-button.tsx create mode 100644 services/web/frontend/js/features/project-list/components/table/project-tools/buttons/download-projects-button.tsx create mode 100644 services/web/frontend/js/features/project-list/components/table/project-tools/buttons/trash-projects-button.tsx create mode 100644 services/web/frontend/js/features/project-list/components/table/project-tools/project-tools.tsx create mode 100644 services/web/test/frontend/features/project-list/components/project-list-root.test.tsx create mode 100644 services/web/test/frontend/features/project-list/components/table/project-tools/buttons/archive-projects.button.test.tsx create mode 100644 services/web/test/frontend/features/project-list/components/table/project-tools/buttons/download-projects-button.test.tsx create mode 100644 services/web/test/frontend/features/project-list/components/table/project-tools/buttons/trash-projects.button.test.tsx create mode 100644 services/web/test/frontend/features/project-list/components/table/project-tools/project-tools.test.tsx diff --git a/services/web/frontend/js/features/project-list/components/project-list-root.tsx b/services/web/frontend/js/features/project-list/components/project-list-root.tsx index 4a7af12a34..e907e07269 100644 --- a/services/web/frontend/js/features/project-list/components/project-list-root.tsx +++ b/services/web/frontend/js/features/project-list/components/project-list-root.tsx @@ -14,6 +14,7 @@ import WelcomeMessage from './welcome-message' import LoadingBranded from '../../../shared/components/loading-branded' import UserNotifications from './notifications/user-notifications' import SearchForm from './search-form' +import ProjectTools from './table/project-tools/project-tools' function ProjectListRoot() { const { isReady } = useWaitForI18n() @@ -26,8 +27,14 @@ function ProjectListRoot() { } function ProjectListPageContent() { - const { totalProjectsCount, error, isLoading, loadProgress, setSearchText } = - useProjectListContext() + const { + totalProjectsCount, + error, + isLoading, + loadProgress, + setSearchText, + selectedProjects, + } = useProjectListContext() return isLoading ? (
@@ -58,9 +65,11 @@ function ProjectListPageContent() {
-
+ {selectedProjects.length === 0 ? ( -
+ ) : ( + + )}
diff --git a/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/archive-project-button.tsx b/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/archive-project-button.tsx index 24dcd312c0..9ac2f1bd20 100644 --- a/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/archive-project-button.tsx +++ b/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/archive-project-button.tsx @@ -57,22 +57,8 @@ function ArchiveProjectButton({ project }: ArchiveProjectButtonProps) { {t('about_to_archive_projects')}

} - bodyBottom={ -

- {t('archiving_projects_wont_affect_collaborators')}{' '} - - {t('find_out_more_nt')} - -

- } showModal={showModal} handleCloseModal={handleCloseModal} projects={[project]} diff --git a/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/delete-project-button.tsx b/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/delete-project-button.tsx index 5293815d75..b04e07c343 100644 --- a/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/delete-project-button.tsx +++ b/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/delete-project-button.tsx @@ -60,16 +60,8 @@ function DeleteProjectButton({ project }: DeleteProjectButtonProps) { {t('about_to_delete_projects')}

} - bodyBottom={ -
- {' '} - {t('this_action_cannot_be_undone')} -
- } showModal={showModal} handleCloseModal={handleCloseModal} projects={[project]} diff --git a/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/leave-project-buttton.tsx b/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/leave-project-buttton.tsx index 19bc6943a9..e456339676 100644 --- a/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/leave-project-buttton.tsx +++ b/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/leave-project-buttton.tsx @@ -59,16 +59,8 @@ function LeaveProjectButton({ project }: LeaveProjectButtonProps) { {t('about_to_leave_projects')}

} - bodyBottom={ -
- {' '} - {t('this_action_cannot_be_undone')} -
- } showModal={showModal} handleCloseModal={handleCloseModal} projects={[project]} diff --git a/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/trash-project-button.tsx b/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/trash-project-button.tsx index 1f7eb17067..d4893837da 100644 --- a/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/trash-project-button.tsx +++ b/services/web/frontend/js/features/project-list/components/table/cells/action-buttons/trash-project-button.tsx @@ -58,22 +58,8 @@ function TrashProjectButton({ project }: TrashProjectButtonProps) { {t('about_to_trash_projects')}

} - bodyBottom={ -

- {t('trashing_projects_wont_affect_collaborators')}{' '} - - {t('find_out_more_nt')} - -

- } showModal={showModal} handleCloseModal={handleCloseModal} projects={[project]} diff --git a/services/web/frontend/js/features/project-list/components/table/project-list-table-row.tsx b/services/web/frontend/js/features/project-list/components/table/project-list-table-row.tsx index 003ed80493..aeb15d396a 100644 --- a/services/web/frontend/js/features/project-list/components/table/project-list-table-row.tsx +++ b/services/web/frontend/js/features/project-list/components/table/project-list-table-row.tsx @@ -4,6 +4,8 @@ import InlineTags from './cells/inline-tags' import OwnerCell from './cells/owner-cell' import LastUpdatedCell from './cells/last-updated-cell' import ActionsCell from './cells/actions-cell' +import { useProjectListContext } from '../../context/project-list-context' +import { useCallback } from 'react' type ProjectListTableRowProps = { project: Project @@ -12,11 +14,35 @@ export default function ProjectListTableRow({ project, }: ProjectListTableRowProps) { const { t } = useTranslation() + const { selectedProjects, setSelectedProjects } = useProjectListContext() + + const handleCheckboxChange = useCallback( + (event: React.ChangeEvent) => { + const checked = event.target.checked + setSelectedProjects(selectedProjects => { + let projects = [...selectedProjects] + if (checked) { + projects.push(project) + } else { + const projectId = event.target.getAttribute('data-project-id') + projects = projects.filter(p => p.id !== projectId) + } + return projects + }) + }, + [project, setSelectedProjects] + ) return ( - +