Skip to content

Commit

Permalink
[MDS-6273] Project file deletion (#3343)
Browse files Browse the repository at this point in the history
* Add delete functionality, tests

* Correct non draft behaviour

* Update error message

* Remove unnecessary async

* Add editMode check

* Change to deleteEnabled flag, change scss

* add a mock for document deletion

* unused import

* Add document amendment deletion tests

* Add supporting document to test, update snap

---------

Co-authored-by: Tara Epp <[email protected]>
  • Loading branch information
sggerard and taraepp authored Dec 17, 2024
1 parent 5d9fa5b commit d81622d
Show file tree
Hide file tree
Showing 15 changed files with 929 additions and 41 deletions.
11 changes: 3 additions & 8 deletions services/common/src/components/documents/DocumentTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,13 @@ export const DocumentTable: FC<DocumentTableProps> = ({
const isMinimalView: boolean = view === "minimal";

const parseDocuments = (docs: any[]): MineDocument[] => {
let parsedDocs: MineDocument[];
if (docs.length && docs[0] instanceof MineDocument) {
parsedDocs = docs;
return docs;
} else {
parsedDocs = docs.map((doc) => new MineDocument(doc));
return docs.map((doc) => new MineDocument(doc));
}
return parsedDocs.map((doc) => {
doc.setAllowedActions(userRoles);
return doc;
});
};

const [documents, setDocuments] = useState<MineDocument[]>(parseDocuments(props.documents ?? []));

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ import { SystemFlagEnum } from "@mds/common/constants/enums";
import { getSystemFlag } from "@mds/common/redux/selectors/authenticationSelectors";
import { FormContext } from "../forms/FormWrapper";
import { ProjectSummaryFormComponentProps } from "./ProjectSummaryForm";
import { areAuthEnvFieldsDisabled, areDocumentFieldsDisabled } from "../projects/projectUtils";
import { areAuthEnvFieldsDisabled, areDocumentFieldsDisabled, isDocumentDeletionEnabled } from "../projects/projectUtils";
import { removeDocumentFromProjectSummary } from "@mds/common/redux/actionCreators/projectActionCreator";

const RenderEMAPermitCommonSections = ({ code, isAmendment, index, isDisabled }) => {
const dispatch = useDispatch();
Expand All @@ -79,11 +80,27 @@ const RenderEMAPermitCommonSections = ({ code, isAmendment, index, isDisabled })

const projectSummaryDocumentTypesHash = useSelector(getProjectSummaryDocumentTypesHash);
const docFieldsDisabled = areDocumentFieldsDisabled(systemFlag, status_code);
const { isEditMode } = useContext(FormContext);
const deletionEnabled = isDocumentDeletionEnabled(systemFlag, status_code);

const onChange = (value) => {
setShowExemptionSection(value);
};

const onDeleteDocument = (event, key: string) => {
const document = tableDocuments.find( (doc) => key === doc.key);
if(document){
dispatch(
removeDocumentFromProjectSummary(
project_guid,
project_summary_guid,
document.mine_document_guid
)).then( () => {
removeAmendmentDocument(tableDocuments.indexOf(document),document.category,document.document_manager_guid)
})
}
}

const removeAmendmentDocument = (
amendmentDocumentsIndex: number,
category: string,
Expand Down Expand Up @@ -231,6 +248,7 @@ const RenderEMAPermitCommonSections = ({ code, isAmendment, index, isDisabled })
documents={tableDocuments}
documentParent="project summary authorization"
documentColumns={documentColumns}
removeDocument={deletionEnabled && isEditMode ? onDeleteDocument : undefined}
/>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe("DocumentUpload", () => {
initialValues={MOCK.PROJECT_SUMMARY}
onSubmit={() => { }}
>
<DocumentUpload docFieldsDisabled={false} />
<DocumentUpload docFieldsDisabled={false} deleteEnabled={false}/>
</FormWrapper>
</ReduxWrapper>
);
Expand Down
49 changes: 34 additions & 15 deletions services/common/src/components/projectSummary/DocumentUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import SpatialDocumentTable from "../documents/spatial/SpatialDocumentTable";
import { FormContext } from "../forms/FormWrapper";
import { useFeatureFlag } from "@mds/common/providers/featureFlags/useFeatureFlag";
import { Feature, IProjectSummaryForm } from "../..";
import { removeDocumentFromProjectSummary } from "@mds/common/redux/actionCreators/projectActionCreator";

const RenderOldDocuments = ({
documents,
Expand Down Expand Up @@ -67,9 +68,10 @@ const RenderOldDocuments = ({

interface DocumentUploadProps {
docFieldsDisabled: boolean;
deleteEnabled: boolean;
}

export const DocumentUpload: FC<DocumentUploadProps> = ({ docFieldsDisabled }) => {
export const DocumentUpload: FC<DocumentUploadProps> = ({ docFieldsDisabled, deleteEnabled }) => {
const dispatch = useDispatch();
const {
spatial_documents = [],
Expand Down Expand Up @@ -145,29 +147,45 @@ export const DocumentUpload: FC<DocumentUploadProps> = ({ docFieldsDisabled }) =
}
};

const removeFile = (document) => {
if (document.project_summary_document_type_code === PROJECT_SUMMARY_DOCUMENT_TYPE_CODE.SPATIAL) {
const newSpatialDocuments = [...spatial_documents].filter(
(file) => document.document_manager_guid !== file.document_manager_guid
);
dispatch(change(FORM.ADD_EDIT_PROJECT_SUMMARY, "spatial_documents", newSpatialDocuments));
} else if (document.project_summary_document_type_code === PROJECT_SUMMARY_DOCUMENT_TYPE_CODE.SUPPORTING) {
const newSupportDocuments = [...support_documents].filter(
(file) => document.document_manager_guid !== file.document_manager_guid
);
dispatch(change(FORM.ADD_EDIT_PROJECT_SUMMARY, "support_documents", newSupportDocuments));
}
}

const onRemoveFile = (err, fileItem) => {
if (err) {
console.log(err);
}

if (fileItem.serverId) {
const document_type_code = documents.find(
removeFile(documents.find(
(file) => fileItem.serverId === file.document_manager_guid
)?.project_summary_document_type_code;
if (document_type_code === PROJECT_SUMMARY_DOCUMENT_TYPE_CODE.SPATIAL) {
const newSpatialDocuments = [...spatial_documents].filter(
(file) => fileItem.serverId !== file.document_manager_guid
);
dispatch(change(FORM.ADD_EDIT_PROJECT_SUMMARY, "spatial_documents", newSpatialDocuments));
} else if (document_type_code === PROJECT_SUMMARY_DOCUMENT_TYPE_CODE.SUPPORTING) {
const newSupportDocuments = [...support_documents].filter(
(file) => fileItem.serverId !== file.document_manager_guid
);
dispatch(change(FORM.ADD_EDIT_PROJECT_SUMMARY, "support_documents", newSupportDocuments));
}
));
}
};

const onDeleteDocument = (event, key: string) => {
const document = documents.find( (doc) => key === doc.mine_document_guid);
if(document){
dispatch(
removeDocumentFromProjectSummary(
project_guid,
project_summary_guid,
document.mine_document_guid
)).then( () => {
removeFile(document);
})
}
}

const downloadIRTTemplate = (url) => {
const anchor = document.createElement("a");
anchor.href = url;
Expand Down Expand Up @@ -283,6 +301,7 @@ export const DocumentUpload: FC<DocumentUploadProps> = ({ docFieldsDisabled }) =
documents={support_documents}
documentParent="project summary"
documentColumns={documentColumns}
removeDocument={deleteEnabled && isEditMode ? onDeleteDocument : undefined}
/>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const ProjectSummaryFileUpload: FC<WrappedFieldProps & ProjectSummaryFile
}

useEffect(() => {
if (existingFiles.length === 0) {
if (existingFiles.length === 0 || props.documents.length < existingFiles.length) {
setExistingFiles(props.documents);
}
}, [props.documents]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ProjectManagement } from "./ProjectManagement";
import { getSystemFlag } from "@mds/common/redux/selectors/authenticationSelectors";
import { SystemFlagEnum } from "../..";
import { formatProjectPayload } from "@mds/common/utils/helpers";
import { areAuthFieldsDisabled, areDocumentFieldsDisabled, areFieldsDisabled } from "../projects/projectUtils";
import { areAuthFieldsDisabled, areDocumentFieldsDisabled, areFieldsDisabled, isDocumentDeletionEnabled } from "../projects/projectUtils";

interface ProjectSummaryFormProps {
initialValues: IProjectSummary;
Expand Down Expand Up @@ -104,6 +104,7 @@ export const ProjectSummaryForm: FC<ProjectSummaryFormProps> = ({
const fieldsDisabled = areFieldsDisabled(systemFlag, status_code, confirmation_of_submission);
const docFieldsDisabled = areDocumentFieldsDisabled(systemFlag, status_code);
const authFieldsDisabled = areAuthFieldsDisabled(systemFlag, status_code, confirmation_of_submission);
const deleteEnabled = isDocumentDeletionEnabled(systemFlag, status_code);

const handleTransformPayload = (valuesFromForm: any) => {
return formatProjectPayload(valuesFromForm, { projectSummaryAuthorizationTypesArray });
Expand All @@ -128,7 +129,7 @@ export const ProjectSummaryForm: FC<ProjectSummaryFormProps> = ({
"representing-agent": <Agent fieldsDisabled={fieldsDisabled} />,
"mine-components-and-offsite-infrastructure": <FacilityOperator fieldsDisabled={fieldsDisabled} />,
"purpose-and-authorization": <AuthorizationsInvolved fieldsDisabled={authFieldsDisabled} />,
"document-upload": <DocumentUpload docFieldsDisabled={docFieldsDisabled} />,
"document-upload": <DocumentUpload docFieldsDisabled={docFieldsDisabled} deleteEnabled={deleteEnabled} />,
"application-summary": <ApplicationSummary fieldsDisabled={fieldsDisabled} />,
declaration: <Declaration />,
}[tab]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { render } from "@testing-library/react";
import { render, fireEvent } from "@testing-library/react";
import FormWrapper from "../forms/FormWrapper";
import { FORM, SystemFlagEnum } from "@mds/common/constants";
import { ProjectManagement } from "./ProjectManagement";
Expand All @@ -20,10 +20,10 @@ import Declaration from "./Declaration";
import DocumentUpload from "./DocumentUpload";
import { FacilityOperator } from "./FacilityOperator";
import { BrowserRouter } from "react-router-dom";
import * as modalActions from "@mds/common/redux/actions/modalActions";

const { formatProjectSummary } = exportForTesting;


const amsAuthTypes = ['AIR_EMISSIONS_DISCHARGE_PERMIT', 'EFFLUENT_DISCHARGE_PERMIT', 'REFUSE_DISCHARGE_PERMIT'];
const project = { project_lead_party_guid: "project_lead_party_guid" };
const formattedProjectSummary = formatProjectSummary(MOCK.PROJECT_SUMMARY, project, amsAuthTypes);
Expand Down Expand Up @@ -62,12 +62,14 @@ const mockFields = jest.fn();
const mockDocFields = jest.fn();
const mockAuthFields = jest.fn();
const mockEnvFields = jest.fn();
const mockDocDeletion = jest.fn();

jest.mock("@mds/common/components/projects/projectUtils", () => ({
areFieldsDisabled: () => mockFields(),
areDocumentFieldsDisabled: () => mockDocFields(),
areAuthFieldsDisabled: () => mockAuthFields(),
areAuthEnvFieldsDisabled: () => mockEnvFields(),
isDocumentDeletionEnabled: () => mockDocDeletion(),
getProjectStatusDescription: () => jest.fn().mockReturnValue("Status Description")
}));

Expand Down Expand Up @@ -106,12 +108,13 @@ const isEnvMatch = (id: string) => {
return match && !isDoc;
};

describe("ProjectSummaryForm components disable accurately accoring to functions", () => {
describe("ProjectSummaryForm components disable accurately according to functions", () => {
const renderedComponents = ({ fieldsDisabled, authFieldsDisabled, docFieldsDisabled, envFieldsDisabled }) => {
mockFields.mockReturnValue(fieldsDisabled);
mockDocFields.mockReturnValue(docFieldsDisabled);
mockAuthFields.mockReturnValue(authFieldsDisabled);
mockEnvFields.mockReturnValue(envFieldsDisabled);
mockDocDeletion.mockReturnValue(false);

return <BrowserRouter>
<FormWrapper name={FORM.ADD_EDIT_PROJECT_SUMMARY} onSubmit={jest.fn()}>
Expand All @@ -125,7 +128,7 @@ describe("ProjectSummaryForm components disable accurately accoring to functions
<Agent fieldsDisabled={fieldsDisabled} />
<FacilityOperator fieldsDisabled={fieldsDisabled} />
<AuthorizationsInvolved fieldsDisabled={authFieldsDisabled} />
<DocumentUpload docFieldsDisabled={docFieldsDisabled} />
<DocumentUpload docFieldsDisabled={docFieldsDisabled} deleteEnabled={false} />
<ApplicationSummary fieldsDisabled={fieldsDisabled} />
<Declaration />
</FormWrapper>
Expand Down Expand Up @@ -268,4 +271,72 @@ describe("ProjectSummaryForm components disable accurately accoring to functions

expect(enabledAuthIds).toEqual([]);
});
});

describe("ProjectSummaryForm document deletion disables accurately according to functions", () => {
const renderedComponents = ({ deletionEnabled }) => {
mockDocDeletion.mockReturnValue(deletionEnabled);

return <BrowserRouter>
<FormWrapper name={FORM.ADD_EDIT_PROJECT_SUMMARY} onSubmit={jest.fn()}>
<AuthorizationsInvolved fieldsDisabled={false} />
<DocumentUpload docFieldsDisabled={false} deleteEnabled={deletionEnabled}/>
</FormWrapper>
</BrowserRouter>
};

const openModalSpy = jest.spyOn(modalActions, "openModal");
const keys = [
...MOCK.PROJECT_SUMMARY.authorizations.flatMap(auth => auth.amendment_documents.map(doc => doc.document_manager_guid)),
...MOCK.PROJECT_SUMMARY.documents.filter(doc => doc.project_summary_document_type_code === "SPR").map(doc => doc.document_manager_guid)
];

afterEach(() => {
jest.clearAllMocks();
});

test("Document deletion enabled", async () => {
const params = {
deletionEnabled: true
};

const { container, findByTestId} = render(
<ReduxWrapper initialState={initialState}>
{renderedComponents(params)}
</ReduxWrapper>
);

for (const key of keys){
const row = container.querySelector(`tr[data-row-key="${key}"]`)
expect(row).toBeInTheDocument();
const actionsButton = row.querySelector('button[data-cy="menu-actions-button"]')
fireEvent.mouseEnter(actionsButton);
const deleteAction = await findByTestId("action-button-delete");
expect(deleteAction).toBeInTheDocument();
fireEvent.click(deleteAction)
}
expect(openModalSpy).toHaveBeenCalledTimes(keys.length)
});

test("Document deletion disabled", async () => {
const params = {
deletionEnabled: false
};

const { container } = render(
<ReduxWrapper initialState={initialState}>
{renderedComponents(params)}
</ReduxWrapper>
);

for (const key of keys){
const row = container.querySelector(`tr[data-row-key="${key}"]`)
expect(row).toBeInTheDocument();
const actionsButton = row.querySelector('button[data-cy="menu-actions-button"]')
fireEvent.mouseEnter(actionsButton);
const deleteAction = container.querySelector('[data-testid="action-button-delete"]');
expect(deleteAction).not.toBeInTheDocument();
}
expect(openModalSpy).toHaveBeenCalledTimes(0)
});
});
});
Loading

0 comments on commit d81622d

Please sign in to comment.