Skip to content

Commit

Permalink
[MDS-6011] - View geospatial bundles (#3214)
Browse files Browse the repository at this point in the history
* add GEOMARK_URL_BASE to env-example

* Update core-api to handle the saving and fetching of mine_document_bundles in the project summary section.

* Update the fetching/displaying of geomark data in the project summary

* Add polyfills for Node.js globals and update document handling.

Created a new `jest.polyfills.js` for necessary Node.js globals to run Jest tests with JSDOM. Added `mine_document_bundle_id` to the `Document` model and utilized `groupSpatialBundles` in `SpatialDocumentTable`.

* cleaned up some functionality

* cleaned up some functionality

* updated snapshots and added msw updates to core-web

* update jest setups

* update jest configs

* update snap

* addressed pr comments

* moved creation of mine_document_bundles to a helper function in the mine_document_bundle.py

* updated projectsummary factory to include spatial documents and document bundles

* addressed more pr comments

* addressed more pr comments

* fixed tests in api

* added model tests for document bundles
  • Loading branch information
matbusby-fw authored Aug 15, 2024
1 parent 0f7f576 commit c1d147a
Show file tree
Hide file tree
Showing 49 changed files with 2,100 additions and 1,232 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ module.exports = {
"services/core-web/webpack.parts.js",
"services/core-web/cypress.config.ts",
"services/core-web/cypress/**",
"services/common/jest.polyfills.js",
"services/minespace-web/jest.polyfills.js",
"services/core-web/jest.polyfills.js",
"services/core-web/jest.config.js",
],
parserOptions: {
project: [
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/common-package.unit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

- uses: actions/setup-node@v2
with:
node-version: 14.x
node-version: 18.x

- name: Upgrade yarn
run: npm install -g yarn
Expand Down
19 changes: 12 additions & 7 deletions services/common/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
module.exports = {
transform: {
'^.+\\.(t|j)sx?$': ['ts-jest', {
"tsConfigFile": "./tsconfig.json",
isolatedModules: true
}]
"^.+\\.(t|j)sx?$": [
"ts-jest",
{
tsConfigFile: "./tsconfig.json",
isolatedModules: true,
},
],
},
maxWorkers: 4,
verbose: true,
testEnvironmentOptions: {
url: 'http://localhost'
customExportConditions: [""],
url: "http://localhost",
},
testEnvironment: "jest-environment-jsdom-global",
setupFiles: ["jest-localstorage-mock", "jest-canvas-mock", "./src/setupTests.ts"],
setupFiles: ["./jest.polyfills.js", "jest-localstorage-mock", "jest-canvas-mock"],
setupFilesAfterEnv: ["./src/setupTests.ts"],
collectCoverageFrom: ["**/src/**/*.{js,ts,tsx}"],
moduleNameMapper: {
"@mds/common/(.*)": "<rootDir>/../common/src/$1",
Expand All @@ -21,7 +26,7 @@ module.exports = {
"<rootDir>/src/assetsTransformer.js",
"\\.(css|less|scss)$": "<rootDir>/src/assetsTransformer.js",
"^uuid$": "uuid",
"^esm-browser$": "esm-browser"
"^esm-browser$": "esm-browser",
},

transformIgnorePatterns: ["node_modules", "../../node_modules", "vendor"],
Expand Down
31 changes: 31 additions & 0 deletions services/common/jest.polyfills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* @note The block below contains polyfills for Node.js globals
* required for Jest to function when running JSDOM tests.
* These HAVE to be require's and HAVE to be in this exact
* order, since "undici" depends on the "TextEncoder" global API.
*
* Consider migrating to a more modern test runner if
* you don't want to deal with this.
*/

const { TextDecoder, TextEncoder } = require("node:util");
const { ReadableStream } = require("node:stream/web");

Object.defineProperties(globalThis, {
TextDecoder: { value: TextDecoder },
TextEncoder: { value: TextEncoder },
ReadableStream: { value: ReadableStream },
});

const { Blob, File } = require("node:buffer");
const { fetch, Headers, FormData, Request, Response } = require("undici");

Object.defineProperties(globalThis, {
fetch: { value: fetch, writable: true },
Blob: { value: Blob },
File: { value: File },
Headers: { value: Headers },
FormData: { value: FormData },
Request: { value: Request },
Response: { value: Response },
});
4 changes: 4 additions & 0 deletions services/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@
"react-router-dom": "5.3.3"
},
"devDependencies": {
"@testing-library/jest-dom": "6.4.8",
"clean-webpack-plugin": "4.0.0",
"copy-webpack-plugin": "10.1.0",
"hard-source-webpack-plugin": "0.13.1",
"html-webpack-plugin": "5.5.3",
"image-minimizer-webpack-plugin": "3.8.3",
"imagemin": "8.0.1",
"jest": "29.7.0",
"jest-dom": "4.0.0",
"mini-css-extract-plugin": "2.7.6",
"msw": "2.3.5",
"postcss-loader": "7.3.3",
"prettier": "1.19.1",
"react-hot-loader": "4.12.21",
Expand All @@ -60,6 +63,7 @@
"terser-webpack-plugin": "5.3.9",
"ts-jest": "29.1.2",
"typescript": "4.7.4",
"undici": "6.19.7",
"webpack": "5.88.1",
"webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import RenderCancelButton from "../../forms/RenderCancelButton";
import RenderSubmitButton from "../../forms/RenderSubmitButton";
import { closeModal } from "@mds/common/redux/actions/modalActions";
import ViewSpatialDetail from "./ViewSpatialDetail";
import { createSpatialBundle } from "@mds/common/redux/slices/spatialDataSlice";
import { createDocmanSpatialBundle } from "@mds/common/redux/slices/spatialDataSlice";

interface AddSpatialDocumentsModalProps {
formName: string;
Expand Down Expand Up @@ -57,6 +57,10 @@ const AddSpatialDocumentsModal: FC<AddSpatialDocumentsModalProps> = ({
dispatch(change(modalFormName, fieldName, newUploadedFiles));
};

const filesHaveGeomarkIds = () => {
return existingDocuments.some((d) => d.geomark_id);
};

const stepContent = [
{
title: "Upload Spatial Data Files",
Expand Down Expand Up @@ -95,27 +99,44 @@ const AddSpatialDocumentsModal: FC<AddSpatialDocumentsModalProps> = ({
Please confirm that the composed map below correctly represents your selected spatial
data files.
</Typography.Paragraph>
<ViewSpatialDetail spatialDocuments={existingDocuments} />
{filesHaveGeomarkIds() && <ViewSpatialDetail spatialDocuments={existingDocuments} />}
</>
),
},
];

const addDocmanBundleInfotoFiles = ({
docman_bundle_guid,
geomark_id,
}: {
docman_bundle_guid: string;
geomark_id: string;
}) => {
const newFiles = currentValues[fieldName].map((f) => {
return {
...f,
docman_bundle_guid,
geomark_id,
};
});
dispatch(change(modalFormName, fieldName, newFiles));
};

const handleSubmit = async (values) => {
const isFinalStep = currentStep === stepContent.length - 1;
const newFiles = values[fieldName];
const allFiles = [...newFiles, ...initialDocuments];
if (isFinalStep) {
dispatch(change(formName, fieldName, allFiles));
dispatch(change(formName, fieldName, [...newFiles, ...initialDocuments]));
setIsResetting(true);
setCurrentStep(0);
await dispatch(reset(modalFormName));
setIsResetting(false);
} else {
const bundle_document_guids = newFiles.map((f) => f.document_manager_guid);
const name = newFiles[0].document_name.split(".")[0];
const resp = await dispatch(createSpatialBundle({ name, bundle_document_guids }));
const resp = await dispatch(createDocmanSpatialBundle({ name, bundle_document_guids }));
if (resp.payload) {
addDocmanBundleInfotoFiles(resp.payload);
setCurrentStep(currentStep + 1);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ const spatialDocuments = MOCK.PROJECT_SUMMARY.documents
.map((d) => new MineDocument(d));

describe("SpatialDocumentTable", () => {
it("renders properly", () => {
const { container } = render(
it("renders properly", async () => {
const { container, findByTestId } = render(
<ReduxWrapper>
<SpatialDocumentTable documents={spatialDocuments} />
</ReduxWrapper>
);
const spatialTable = await findByTestId("spatial-document-table");
expect(spatialTable).toBeInTheDocument();

expect(container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, useState } from "react";
import React, { FC, useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { GenericDocTableProps } from "@mds/common/interfaces/document/documentTableProps.interface";
import CoreTable from "../../common/CoreTable";
Expand All @@ -12,7 +12,7 @@ import { openModal } from "@mds/common/redux/actions/modalActions";
import ViewSpatialDetailModal from "./ViewSpatialDetailModal";
import DocumentCompression from "../DocumentCompression";
import { MineDocument } from "@mds/common/models/documents/document";
import { spatialBundlesFromFiles } from "@mds/common/redux/slices/spatialDataSlice";
import { groupSpatialBundles } from "@mds/common/redux/slices/spatialDataSlice";
import { downloadFileFromDocumentManager } from "@mds/common/redux/utils/actionlessNetworkCalls";
import { ISpatialBundle } from "@mds/common/interfaces/document/spatialBundle.interface";
import { IMineDocument } from "@mds/common/interfaces";
Expand All @@ -25,9 +25,20 @@ interface SpatialDocumentTableProps extends GenericDocTableProps<ISpatialBundle>
const SpatialDocumentTable: FC<SpatialDocumentTableProps> = ({ documents, categoryText }) => {
const dispatch = useDispatch();
const [isCompressionModalVisible, setIsCompressionModalVisible] = useState(false);
const [spatialBundles, setSpatialBundles] = useState([]);

const handleGetSpatialBundles = async () => {
const newSpatialBundles = groupSpatialBundles(documents);
setSpatialBundles(newSpatialBundles);
};

useEffect(() => {
if (documents) {
handleGetSpatialBundles();
}
}, [documents]);

const mineDocuments = documents.map((doc) => new MineDocument(doc));
const spatial_bundles = spatialBundlesFromFiles(documents);

const downloadSpatialBundle = () => {
setIsCompressionModalVisible(true);
Expand Down Expand Up @@ -60,7 +71,11 @@ const SpatialDocumentTable: FC<SpatialDocumentTableProps> = ({ documents, catego
clickFunction: (_, record) => downloadFileFromDocumentManager(record),
},
{ key: "download-all", label: "Download All", clickFunction: downloadSpatialBundle },
{ key: "view-detail", label: "View Details", clickFunction: viewSpatialBundle },
{
key: "view-detail",
label: "View Details",
clickFunction: viewSpatialBundle,
},
];

const categoryColumn = categoryText
Expand All @@ -78,19 +93,22 @@ const SpatialDocumentTable: FC<SpatialDocumentTableProps> = ({ documents, catego
...categoryColumn,
uploadDateColumn("upload_date", "Last Modified"),
uploadedByColumn("create_user", "Created By"),
renderActionsColumn({ actions, recordActionsFilter }),
renderActionsColumn({
actions,
recordActionsFilter,
}),
];

return (
<>
<div data-testid="spatial-document-table">
<DocumentCompression
mineDocuments={mineDocuments}
setCompressionModalVisible={setIsCompressionModalVisible}
isCompressionModalVisible={isCompressionModalVisible}
showDownloadWarning={false}
/>
<CoreTable
dataSource={spatial_bundles}
dataSource={spatialBundles}
columns={columns}
expandProps={{
getDataSource: (record) => record.bundleFiles,
Expand All @@ -100,7 +118,7 @@ const SpatialDocumentTable: FC<SpatialDocumentTableProps> = ({ documents, catego
rowExpandable: (record) => !record.isSingleFile && record.isParent,
}}
/>
</>
</div>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import * as MOCK from "@mds/common/tests/mocks/dataMocks";
import { ReduxWrapper } from "@mds/common/tests/utils/ReduxWrapper";
import ViewSpatialDetail from "./ViewSpatialDetail";
import {
spatialBundlesFromFiles,
groupSpatialBundles,
spatialDataReducerType,
} from "@mds/common/redux/slices/spatialDataSlice";
import { MAJOR_MINES_APPLICATION_DOCUMENT_TYPE_CODE } from "@mds/common/constants";

const spatialDocuments = MOCK.PROJECT_SUMMARY.documents.filter(
(d) => d.project_summary_document_type_code === MAJOR_MINES_APPLICATION_DOCUMENT_TYPE_CODE.SPATIAL
);
const spatialBundles = spatialBundlesFromFiles(spatialDocuments);
const spatialBundles = groupSpatialBundles(spatialDocuments);
const bundle_id = spatialBundles[0].bundle_id;

const initialState = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,67 @@ import { renderTextColumn } from "../../common/CoreTableCommonColumns";
import { formatDate } from "@mds/common/redux/utils/helpers";
import { getFormattedUserName } from "@mds/common/redux/selectors/authenticationSelectors";
import {
fetchGeomarkMapData,
spatialBundlesFromFiles,
clearSpatialData,
fetchGeomarkMapData,
fetchSpatialBundle,
getGeomarkMapData,
getSpatialBundle,
groupSpatialBundles,
} from "@mds/common/redux/slices/spatialDataSlice";
import { IMineDocument } from "@mds/common/interfaces";
import CoreMap from "../../common/Map";
import { getIsModalOpen } from "@mds/common/redux/selectors/modalSelectors";

export interface ViewSpatialDetailProps {
spatialDocuments: IMineDocument[];
spatialDocuments: (IMineDocument & { geomark_id?: string })[];
}

const ViewSpatialDetail: FC<ViewSpatialDetailProps> = ({ spatialDocuments }) => {
const dispatch = useDispatch();
const username = useSelector(getFormattedUserName);
const spatialBundle = useSelector(getSpatialBundle);
const geomarkMapData = useSelector(getGeomarkMapData);
const isModalOpen = useSelector(getIsModalOpen);
const [mapLoaded, setMapLoaded] = useState(false);
const spatialBundle = spatialBundlesFromFiles(spatialDocuments)[0];
const [isLoaded, setIsLoaded] = useState(false);
const [bundleNotYetCreated, setBundleNotYetCreated] = useState<boolean | null>();

const handleGetSpatialBundles = async () => {
if (!spatialDocuments[0].geomark_id) {
const spatialBundles = groupSpatialBundles(spatialDocuments);
await dispatch(fetchSpatialBundle(spatialBundles[0].bundle_id));
setBundleNotYetCreated(false);
} else {
setBundleNotYetCreated(true);
}

setIsLoaded(true);
};

useEffect(() => {
if (spatialDocuments && !isLoaded) {
handleGetSpatialBundles();
}
}, [spatialDocuments, isModalOpen]);

const handleFetchMapData = () => {
setMapLoaded(false);
dispatch(fetchGeomarkMapData(spatialBundle));
const geomarkId = bundleNotYetCreated
? spatialDocuments[0].geomark_id
: spatialBundle.geomark_id;

dispatch(fetchGeomarkMapData(geomarkId));
};

useEffect(() => {
if (!mapLoaded) {
if ((!mapLoaded && spatialBundle) || bundleNotYetCreated) {
handleFetchMapData();
}
return () => dispatch(clearSpatialData());
}, []);
return () => {
setMapLoaded(false);
dispatch(clearSpatialData());
};
}, [spatialBundle, bundleNotYetCreated, isModalOpen]);

return (
<>
Expand Down
Loading

0 comments on commit c1d147a

Please sign in to comment.