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

[MDS-6273] Project file deletion #3343

Merged
merged 10 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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 @@ -82,18 +82,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
Loading