From a7ce8b48aa5f07ee4dea834d9cb8f89aa73068b7 Mon Sep 17 00:00:00 2001 From: Tara Epp <102187683+taraepp@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:21:09 -0600 Subject: [PATCH] [MDS-6011] Fix buttons in modal footers, only show allowed type in replace modal (#3220) * add space around buttons in modal footers * fix an actions/consistency issue, clean up document table, clean up & test doc modals, only show the actual allowed type in replace doc modal * move test * fix spelling, remove imports from proptypes, fix duplicate key in datamocks * fix a nesting issue for spatial doc modal test, add in missing test id * test if the only CSS change is breaking the build * see if adding a default geomark URL helps Index.js pass, and if adding an equivalent rule on MS helps the build error * update styles * attempt to target the correct actions button --- .../src/components/common/ActionMenu.tsx | 1 + .../documents/ArchiveDocumentModal.spec.tsx | 19 + .../documents/ArchiveDocumentModal.tsx | 31 +- .../documents/DeleteDocumentModal.spec.tsx | 20 + .../documents/DeleteDocumentModal.tsx | 29 +- .../documents/DocumentTable.spec.tsx | 26 +- .../components/documents/DocumentTable.tsx | 29 +- .../documents}/ReplaceDocumentModal.spec.tsx | 19 +- .../documents/ReplaceDocumentModal.tsx | 72 ++-- .../ArchiveDocumentModal.spec.tsx.snap | 167 ++++++++ .../DeleteDocumentModal.spec.tsx.snap | 167 ++++++++ .../__snapshots__/DocumentTable.spec.tsx.snap | 345 +++++++++++------ .../ReplaceDocumentModal.spec.tsx.snap | 20 +- .../spatial/AddSpatialDocumentsModal.spec.tsx | 26 +- .../AddSpatialDocumentsModal.spec.tsx.snap | 363 +++++++++--------- .../components/forms/RenderSubmitButton.tsx | 5 +- .../ProjectDocumentsTab.spec.tsx.snap | 2 +- .../ProjectDocumentsTabSection.spec.tsx.snap | 2 +- services/common/src/constants/environment.ts | 2 +- services/common/src/constants/forms.ts | 2 + .../document/documentTableProps.interface.ts | 10 +- services/common/src/tests/mocks/dataMocks.tsx | 9 +- .../core-web/cypress/e2e/majorprojects.cy.ts | 2 +- .../src/styles/settings/themeOverride.scss | 4 + 24 files changed, 933 insertions(+), 439 deletions(-) create mode 100644 services/common/src/components/documents/ArchiveDocumentModal.spec.tsx create mode 100644 services/common/src/components/documents/DeleteDocumentModal.spec.tsx rename services/{core-web/src/tests/components/modalContent => common/src/components/documents}/ReplaceDocumentModal.spec.tsx (53%) create mode 100644 services/common/src/components/documents/__snapshots__/ArchiveDocumentModal.spec.tsx.snap create mode 100644 services/common/src/components/documents/__snapshots__/DeleteDocumentModal.spec.tsx.snap rename services/{core-web/src/tests/components/modalContent => common/src/components/documents}/__snapshots__/ReplaceDocumentModal.spec.tsx.snap (79%) diff --git a/services/common/src/components/common/ActionMenu.tsx b/services/common/src/components/common/ActionMenu.tsx index 1511621519..9112214a61 100644 --- a/services/common/src/components/common/ActionMenu.tsx +++ b/services/common/src/components/common/ActionMenu.tsx @@ -25,6 +25,7 @@ export const generateActionMenuItems = (actionItems: ITableAction[], record) => - + + - + ); }; diff --git a/services/common/src/components/documents/DeleteDocumentModal.spec.tsx b/services/common/src/components/documents/DeleteDocumentModal.spec.tsx new file mode 100644 index 0000000000..205bd41a02 --- /dev/null +++ b/services/common/src/components/documents/DeleteDocumentModal.spec.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { render } from "@testing-library/react"; +import { ReduxWrapper } from "@mds/common/tests/utils/ReduxWrapper"; +import { MINEDOCUMENTS } from "@mds/common/tests/mocks/dataMocks"; +import DeleteDocumentModal from "./DeleteDocumentModal"; +import { MineDocument } from "@mds/common/models/documents/document"; + +describe("DeleteDocumentModal", () => { + it("renders correctly and matches the snapshot", () => { + const { container } = render( + + new MineDocument(d))} + handleSubmit={jest.fn().mockReturnValue(Promise.resolve())} + /> + + ); + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/services/common/src/components/documents/DeleteDocumentModal.tsx b/services/common/src/components/documents/DeleteDocumentModal.tsx index bf8a9202c6..8b4a286744 100644 --- a/services/common/src/components/documents/DeleteDocumentModal.tsx +++ b/services/common/src/components/documents/DeleteDocumentModal.tsx @@ -1,21 +1,20 @@ import React, { FC } from "react"; - -import { Alert, Button, Form, Typography } from "antd"; +import { Alert, Typography } from "antd"; import { MineDocument } from "@mds/common/models/documents/document"; import DocumentTable from "./DocumentTable"; +import FormWrapper from "../forms/FormWrapper"; +import RenderCancelButton from "../forms/RenderCancelButton"; +import RenderSubmitButton from "../forms/RenderSubmitButton"; +import { FORM } from "@mds/common/constants"; interface DeleteDocumentModalProps { documents: MineDocument[]; handleSubmit(documents: MineDocument[]): Promise; - closeModal(): void; } -const DeleteDocumentModal: FC = (props: DeleteDocumentModalProps) => { +const DeleteDocumentModal: FC = ({ documents, handleSubmit }) => { return ( -
props.handleSubmit(props.documents).then(props.closeModal)} - > + handleSubmit(documents)} isModal> = (props: DeleteDocument - You're about to delete the following file{props.documents?.length > 1 ? "s" : ""}: + You're about to delete the following file{documents?.length > 1 ? "s" : ""}:
- - + +
- +
); }; diff --git a/services/common/src/components/documents/DocumentTable.spec.tsx b/services/common/src/components/documents/DocumentTable.spec.tsx index 875edaf875..cce580e339 100644 --- a/services/common/src/components/documents/DocumentTable.spec.tsx +++ b/services/common/src/components/documents/DocumentTable.spec.tsx @@ -1,19 +1,37 @@ import React from "react"; -import { render } from "@testing-library/react"; +import { render, fireEvent } from "@testing-library/react"; import * as MOCK from "@mds/common/tests/mocks/dataMocks"; import DocumentTable from "./DocumentTable"; import { MineDocument } from "@mds/common/models/documents/document"; import { ReduxWrapper } from "@mds/common/tests/utils/ReduxWrapper"; +import * as modalActions from "@mds/common/redux/actions/modalActions"; const documents = MOCK.PROJECT_SUMMARY.documents.map((d) => new MineDocument(d)); describe("DocumentTable", () => { - it("renders properly", () => { - const { container } = render( + const removeFunc = jest.fn(); + const onArchiveFunc = jest.fn(); + const onReplaceFunc = jest.fn(); + + const openModalSpy = jest.spyOn(modalActions, "openModal"); + it("renders properly", async () => { + const { container, getAllByText, findByTestId } = render( - + ); expect(container).toMatchSnapshot(); + const actionsButton = getAllByText("Actions")[0]; + fireEvent.mouseEnter(actionsButton); + const archiveAction = await findByTestId("action-button-archive"); + fireEvent.click(archiveAction); + expect(openModalSpy).toHaveBeenCalledTimes(1); }); }); diff --git a/services/common/src/components/documents/DocumentTable.tsx b/services/common/src/components/documents/DocumentTable.tsx index d1e18eb022..6997e8b76d 100644 --- a/services/common/src/components/documents/DocumentTable.tsx +++ b/services/common/src/components/documents/DocumentTable.tsx @@ -63,8 +63,8 @@ export const DocumentTable: FC = ({ }; const [rowSelection, setRowSelection] = useState([]); - const [isCompressionModal, setCompressionModal] = useState(false); - const [isCompressionInProgress, setCompressionInProgress] = useState(false); + const [isCompressionModal, setIsCompressionModal] = useState(false); + const [isCompressionInProgress, setIsCompressionInProgress] = useState(false); const [documentsCanBulkDropDown, setDocumentsCanBulkDropDown] = useState(false); const { isFeatureEnabled } = useFeatureFlag(); @@ -114,7 +114,6 @@ export const DocumentTable: FC = ({ openModal({ props: { title: `Archive ${docs?.length > 1 ? "Multiple Files" : "File"}`, - closeModal: handleCloseModal, handleSubmit: async () => { await dispatch( archiveMineDocuments( @@ -123,8 +122,9 @@ export const DocumentTable: FC = ({ ) ); if (props.onArchivedDocuments) { - props.onArchivedDocuments(docs); + await props.onArchivedDocuments(docs); } + handleCloseModal(); }, documents: docs, }, @@ -139,16 +139,12 @@ export const DocumentTable: FC = ({ openModal({ props: { title: `Delete ${docs?.length > 1 ? "Multiple Files" : "File"}`, - closeModal: handleCloseModal, handleSubmit: async () => { - for (const doc of docs) { - await removeDocument(event, doc.key, documentParent); - } + await Promise.all(docs.map((doc) => removeDocument(event, doc.key, documentParent))); handleCloseModal(); }, documents: docs, }, - content: DeleteDocumentModal, }) ); @@ -160,7 +156,6 @@ export const DocumentTable: FC = ({ openModal({ props: { title: `Replace File`, - closeModal: handleCloseModal, handleSubmit: async (document: MineDocument) => { const newDocuments = documents.map((d) => d.mine_document_guid === document.mine_document_guid ? document : d @@ -281,14 +276,14 @@ export const DocumentTable: FC = ({ const bulkItems: MenuProps["items"] = [ { - key: "0", + key: FileOperations.Download, icon: , label: ( ), }, - ]; + ].filter((a) => allowedTableActions[a.key]); const renderBulkActions = () => { let element = ( @@ -318,7 +313,7 @@ export const DocumentTable: FC = ({ className="ant-btn ant-btn-primary" disabled={rowSelection.length === 0 || isCompressionInProgress} onClick={() => { - setCompressionModal(true); + setIsCompressionModal(true); }} >
Download
@@ -385,9 +380,9 @@ export const DocumentTable: FC = ({
{renderBulkActions()} diff --git a/services/core-web/src/tests/components/modalContent/ReplaceDocumentModal.spec.tsx b/services/common/src/components/documents/ReplaceDocumentModal.spec.tsx similarity index 53% rename from services/core-web/src/tests/components/modalContent/ReplaceDocumentModal.spec.tsx rename to services/common/src/components/documents/ReplaceDocumentModal.spec.tsx index 4f765c3546..bf1c87e99e 100644 --- a/services/core-web/src/tests/components/modalContent/ReplaceDocumentModal.spec.tsx +++ b/services/common/src/components/documents/ReplaceDocumentModal.spec.tsx @@ -4,22 +4,17 @@ import ReplaceDocumentModal from "@mds/common/components/documents/ReplaceDocume import { render } from "@testing-library/react"; import { ReduxWrapper } from "@mds/common/tests/utils/ReduxWrapper"; import { MINEDOCUMENTS } from "@mds/common/tests/mocks/dataMocks"; -import FormWrapper from "@mds/common/components/forms/FormWrapper"; -import { FORM } from "@mds/common/constants/forms"; - -const props = { - document: MINEDOCUMENTS.records[0], - handleSubmit: jest.fn().mockReturnValue(Promise.resolve()), - closeModal: jest.fn(), - postNewDocumentVersion: jest.fn().mockReturnValue(Promise.resolve()), - alertMessage: "This is a test alert message.", -}; +import { MineDocument } from "@mds/common/models/documents/document"; describe("ReplaceDocumentModal", () => { it("renders correctly and matches the snapshot", () => { const { container } = render( - - + + ); expect(container.firstChild).toMatchSnapshot(); diff --git a/services/common/src/components/documents/ReplaceDocumentModal.tsx b/services/common/src/components/documents/ReplaceDocumentModal.tsx index 77e96facb0..959f7c2697 100644 --- a/services/common/src/components/documents/ReplaceDocumentModal.tsx +++ b/services/common/src/components/documents/ReplaceDocumentModal.tsx @@ -1,40 +1,48 @@ import React, { FC, useState } from "react"; import { Field } from "redux-form"; -import { Alert, Button, Col, notification, Row, Typography } from "antd"; +import { useDispatch } from "react-redux"; +import { Alert, Col, notification, Row, Typography } from "antd"; import { MineDocument } from "@mds/common/models/documents/document"; import { formatDate } from "@mds/common/redux/utils/helpers"; import RenderFileUpload from "@mds/common/components/forms/RenderFileUpload"; import { NEW_VERSION_DOCUMENTS } from "@mds/common/constants/API"; -import { bindActionCreators } from "redux"; -import { connect } from "react-redux"; -import { ActionCreator } from "@mds/common/interfaces/actionCreator"; import { IMAGE, DOCUMENT, EXCEL, SPATIAL } from "@mds/common/constants/fileTypes"; import { postNewDocumentVersion } from "@mds/common/redux/actionCreators/documentActionCreator"; import { IMineDocumentVersion } from "@mds/common/interfaces"; import { FilePondFile } from "filepond"; import FormWrapper from "../forms/FormWrapper"; import { FORM } from "@mds/common/constants/forms"; +import { closeModal } from "@mds/common/redux/actions/modalActions"; +import RenderCancelButton from "../forms/RenderCancelButton"; +import RenderSubmitButton from "../forms/RenderSubmitButton"; interface ReplaceDocumentModalProps { document: MineDocument; - postNewDocumentVersion: ActionCreator; alertMessage: string; handleSubmit(document: MineDocument): Promise; - closeModal(): void; } const ReplaceDocumentModal: FC = (props) => { + const dispatch = useDispatch(); const { document, alertMessage } = props; const [versionGuid, setVersionGuid] = useState(); const [disableReplace, setDisableReplace] = useState(true); const [updatedDocument, setUpdatedDocument] = useState(document); - const acceptedFileTypesMap = { - ...DOCUMENT, - ...EXCEL, - ...IMAGE, - ...SPATIAL, + const getAcceptedFileTypes = () => { + const allAcceptedFileTypesMap = { + ...DOCUMENT, + ...EXCEL, + ...IMAGE, + ...SPATIAL, + }; + const { file_type } = document; + if (!file_type || !allAcceptedFileTypesMap[file_type]) { + return allAcceptedFileTypesMap; + } + return { [file_type]: allAcceptedFileTypesMap[file_type] }; }; + const acceptedFileTypesMap = getAcceptedFileTypes(); const onFileLoad = async (fileName: string, document_manager_guid: string) => { setDisableReplace(false); @@ -75,23 +83,25 @@ const ReplaceDocumentModal: FC = (props) => { const handleReplaceSubmit = async () => { if (versionGuid) { - const ConnectedVersion = await props.postNewDocumentVersion({ - mineGuid: document.mine_guid, - mineDocumentGuid: document.mine_document_guid, - documentManagerVersionGuid: versionGuid, - }); + const ConnectedVersion = await dispatch( + postNewDocumentVersion({ + mineGuid: document.mine_guid, + mineDocumentGuid: document.mine_document_guid, + documentManagerVersionGuid: versionGuid, + }) + ); const newDocument = new MineDocument({ ...updatedDocument, versions: [ConnectedVersion.data as IMineDocumentVersion, ...document.versions].reverse(), }); - props.handleSubmit(newDocument).then(props.closeModal); + props.handleSubmit(newDocument).then(() => dispatch(closeModal())); } }; return ( - + Original Document @@ -131,27 +141,15 @@ const ReplaceDocumentModal: FC = (props) => { />
- - + +
); }; -const mapDispatchToProps = (dispatch) => - bindActionCreators( - { - postNewDocumentVersion, - }, - dispatch - ); -export default connect(null, mapDispatchToProps)(ReplaceDocumentModal); +export default ReplaceDocumentModal; diff --git a/services/common/src/components/documents/__snapshots__/ArchiveDocumentModal.spec.tsx.snap b/services/common/src/components/documents/__snapshots__/ArchiveDocumentModal.spec.tsx.snap new file mode 100644 index 0000000000..fe05a4b9d0 --- /dev/null +++ b/services/common/src/components/documents/__snapshots__/ArchiveDocumentModal.spec.tsx.snap @@ -0,0 +1,167 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ArchiveDocumentModal renders correctly and matches the snapshot 1`] = ` +
+
+ +
+
+ + You're about to archive the following file + + : + +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + +
+ File Name + + Uploaded +
+
+
+ 05.4_Parent_Conduct.pdf +
+ +
+
+
+ Feb 06 2024 +
+
+
+
+
+
+
+
+
+ + +`; diff --git a/services/common/src/components/documents/__snapshots__/DeleteDocumentModal.spec.tsx.snap b/services/common/src/components/documents/__snapshots__/DeleteDocumentModal.spec.tsx.snap new file mode 100644 index 0000000000..731c7c0c07 --- /dev/null +++ b/services/common/src/components/documents/__snapshots__/DeleteDocumentModal.spec.tsx.snap @@ -0,0 +1,167 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DeleteDocumentModal renders correctly and matches the snapshot 1`] = ` +
+
+ +
+
+ + You're about to delete the following file + + : + +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + +
+ File Name + + Uploaded +
+
+
+ 05.4_Parent_Conduct.pdf +
+ +
+
+
+ Feb 06 2024 +
+
+
+
+
+
+
+
+
+ + +`; diff --git a/services/common/src/components/documents/__snapshots__/DocumentTable.spec.tsx.snap b/services/common/src/components/documents/__snapshots__/DocumentTable.spec.tsx.snap index 6a59702c87..c30a253d3e 100644 --- a/services/common/src/components/documents/__snapshots__/DocumentTable.spec.tsx.snap +++ b/services/common/src/components/documents/__snapshots__/DocumentTable.spec.tsx.snap @@ -31,7 +31,7 @@ exports[`DocumentTable renders properly 1`] = ` > @@ -41,7 +41,11 @@ exports[`DocumentTable renders properly 1`] = ` - File Name + + File Name + @@ -102,7 +106,7 @@ exports[`DocumentTable renders properly 1`] = ` - Category + File Type - Uploaded + Last Modified
+ +
+ + Created By + + + + + + + + + + + +
+ +
- + + pdf1.kmz + @@ -253,19 +315,29 @@ exports[`DocumentTable renders properly 1`] = ` class="ant-table-cell" >
- N/A + .kmz
- Jun 26 2024 + N/A +
+ + +
+ idir\\username
+
- + + shape.dbf + @@ -337,19 +406,29 @@ exports[`DocumentTable renders properly 1`] = ` class="ant-table-cell" >
- N/A + .dbf
- Jun 26 2024 + N/A +
+ + +
+ idir\\username
+
- + + shape.prj + @@ -421,19 +497,29 @@ exports[`DocumentTable renders properly 1`] = ` class="ant-table-cell" >
- N/A + .prj
+ N/A +
+ + +
- Jun 26 2024 + idir\\username
+
- + + shape.shp + @@ -505,19 +588,29 @@ exports[`DocumentTable renders properly 1`] = ` class="ant-table-cell" >
- N/A + .shp
+ N/A +
+ + +
- Jun 26 2024 + idir\\username
+
- + + shape.shx + @@ -589,19 +679,29 @@ exports[`DocumentTable renders properly 1`] = ` class="ant-table-cell" >
- N/A + .shx
+ N/A +
+ + +
- Jun 26 2024 + idir\\username
+
- + + shape.shx + @@ -673,19 +770,29 @@ exports[`DocumentTable renders properly 1`] = ` class="ant-table-cell" >
- N/A + .shx
+ N/A +
+ + +
- Jun 21 2024 + idir\\username
+ > + .pdf +
+ > + Feb 06 2024 +
+ > + create-user@bceid +
- -
- + + Cancel + + + +
`; diff --git a/services/common/src/components/forms/RenderSubmitButton.tsx b/services/common/src/components/forms/RenderSubmitButton.tsx index 1fde1dc184..d7c80c3534 100644 --- a/services/common/src/components/forms/RenderSubmitButton.tsx +++ b/services/common/src/components/forms/RenderSubmitButton.tsx @@ -8,22 +8,25 @@ import { ButtonProps } from "antd/lib/button/button"; interface RenderSubmitButtonProps { buttonText?: string | ReactNode; buttonProps?: ButtonProps & React.RefAttributes; + disableOnClean?: boolean; } const RenderSubmitButton: FC = ({ buttonText = "Save Changes", buttonProps, + disableOnClean = true, }) => { const { formName, isEditMode } = useContext(FormContext); const submitting = useSelector(isSubmitting(formName)); const isFormDirty = useSelector(isDirty(formName)); + const disabled = submitting || (!isFormDirty && disableOnClean); return ( <> {isEditMode && (