From ae2be2a747300a0723f0fe9a54c1ac9ed39fa271 Mon Sep 17 00:00:00 2001 From: sophia-massie Date: Thu, 9 Jan 2025 16:26:59 -0600 Subject: [PATCH 1/7] task/WG-389-Asset-Panel-Questionnaire - Initial commit, no tests --- .../AssetDetail/AssetDetail.module.css | 8 ++ .../components/AssetDetail/AssetDetail.tsx | 43 ++++++---- .../AssetDetail/AssetQuestionnaire.tsx | 82 +++++++++++++++++++ .../components/AssetDetail/AssetRenderer.tsx | 8 +- react/src/types/feature.ts | 6 ++ 5 files changed, 132 insertions(+), 15 deletions(-) create mode 100644 react/src/components/AssetDetail/AssetQuestionnaire.tsx diff --git a/react/src/components/AssetDetail/AssetDetail.module.css b/react/src/components/AssetDetail/AssetDetail.module.css index 429a21ce..3730c736 100644 --- a/react/src/components/AssetDetail/AssetDetail.module.css +++ b/react/src/components/AssetDetail/AssetDetail.module.css @@ -86,3 +86,11 @@ th { height: 35em; width: 100%; } +.caption { + color: #1f5c7a; + font-size: 0.8em; +} +.questionnaireImage { + width: 100%; + height: 30em; +} diff --git a/react/src/components/AssetDetail/AssetDetail.tsx b/react/src/components/AssetDetail/AssetDetail.tsx index cc2d98a1..a955b054 100644 --- a/react/src/components/AssetDetail/AssetDetail.tsx +++ b/react/src/components/AssetDetail/AssetDetail.tsx @@ -77,21 +77,36 @@ const AssetDetail: React.FC = ({ {selectedFeature?.properties && Object.keys(selectedFeature.properties).length > 0 ? ( - Object.entries(selectedFeature.properties) - .filter(([key]) => !key.startsWith('_hazmapper')) - .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)) // Alphabetizes metadata - .map(([propKey, propValue]) => ( - - {_.startCase(propKey)} - - {propKey.startsWith('description') ? ( - {propValue} - ) : ( - _.trim(JSON.stringify(propValue), '"') - )} - + (() => { + /* Function check that shows the "There are no metadata properties" + in any of these cases: + - The properties object is empty or null + - The properties object only contains keys that start with "_hazmapper" + - The properties object exists but has no properties*/ + const filteredProperties = Object.entries( + selectedFeature.properties + ) + .filter(([key]) => !key.startsWith('_hazmapper')) + .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)); + return filteredProperties.length > 0 ? ( + filteredProperties.map(([propKey, propValue]) => ( + + {_.startCase(propKey)} + + {propKey.startsWith('description') ? ( + {propValue} + ) : ( + _.trim(JSON.stringify(propValue), '"') + )} + + + )) + ) : ( + + There are no metadata properties. - )) + ); + })() ) : ( There are no metadata properties. diff --git a/react/src/components/AssetDetail/AssetQuestionnaire.tsx b/react/src/components/AssetDetail/AssetQuestionnaire.tsx new file mode 100644 index 00000000..2107bef9 --- /dev/null +++ b/react/src/components/AssetDetail/AssetQuestionnaire.tsx @@ -0,0 +1,82 @@ +import React, { useRef } from 'react'; +import { Feature, QuestionnaireAsset } from '@hazmapper/types'; +import { Carousel, Space, Flex } from 'antd'; +import { Button } from '@tacc/core-components'; +import styles from './AssetDetail.module.css'; +import type { CarouselRef } from 'antd/es/carousel'; + +type QuestionnaireProps = { + feature: Feature; + featureSource: string; +}; + +export const AssetQuestionnaire: React.FC = ({ + feature, + featureSource, +}) => { + const carouselRef = useRef(null); + + const processAssetImages = (): QuestionnaireAsset[] => { + if (feature.properties?._hazmapper?.questionnaire?.assets) { + return feature.properties._hazmapper.questionnaire.assets.map((asset) => { + const pathToFullImage = `${featureSource}/${asset.filename}`; + const fileExtension = pathToFullImage.substring( + pathToFullImage.lastIndexOf('.') + ); + const pathWithoutExtension = pathToFullImage.substring( + 0, + pathToFullImage.lastIndexOf('.') + ); + const pathToPreviewImage = `${pathWithoutExtension}.preview${fileExtension}`; + + return { + filename: asset.filename, + coordinates: asset.coordinates, + path: pathToFullImage, + previewPath: pathToPreviewImage, + }; + }); + } + return []; + }; + + const assetImages = processAssetImages(); + + const next = () => { + carouselRef.current?.next(); + }; + + const previous = () => { + carouselRef.current?.prev(); + }; + + if (assetImages.length === 0) { + return
No images available
; + } + + return ( +
+ + {assetImages.map((asset, index) => ( +
+ + {asset.filename} +
{asset.filename}
+
+
+ ))} +
+ + + + + +
+ ); +}; + +export default AssetQuestionnaire; diff --git a/react/src/components/AssetDetail/AssetRenderer.tsx b/react/src/components/AssetDetail/AssetRenderer.tsx index bd7e2187..e2823031 100644 --- a/react/src/components/AssetDetail/AssetRenderer.tsx +++ b/react/src/components/AssetDetail/AssetRenderer.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Feature, FeatureType, getFeatureType } from '@hazmapper/types'; import { SectionMessage } from '@tacc/core-components'; import AssetPointCloud from './AssetPointCloud'; +import AssetQuestionnaire from './AssetQuestionnaire'; interface AssetRendererProps { selectedFeature: Feature; @@ -30,7 +31,12 @@ const AssetRenderer: React.FC = ({ case FeatureType.PointCloud: return ; case FeatureType.Questionnaire: - return
source={featureSource}
; + return ( + + ); case FeatureType.GeometryCollection: default: if (isGeometry(featureType)) { diff --git a/react/src/types/feature.ts b/react/src/types/feature.ts index 9ac46fb9..6f48f95d 100644 --- a/react/src/types/feature.ts +++ b/react/src/types/feature.ts @@ -141,3 +141,9 @@ export interface FeatureFileNode { featureType: FeatureTypeNullable; children?: FeatureFileNode[]; } +export interface QuestionnaireAsset { + filename: string; + coordinates: any; + path: string; + previewPath: string; +} From 5a575a491cf841db7858bcd8f5d4dccc4d3a86bd Mon Sep 17 00:00:00 2001 From: sophia-massie Date: Fri, 10 Jan 2025 17:32:56 -0600 Subject: [PATCH 2/7] Questionnaire and other Asset test changes - addresses errors on geometry and asset AssetDetail - adds questionnaire fixture - adds questionnaire tests --- react/src/__fixtures__/featuresFixture.ts | 54 +++++++ .../AssetDetail/AssetDetail.test.tsx | 12 +- .../AssetDetail/AssetGeometry.test.tsx | 4 +- .../AssetDetail/AssetQuestionnaire.test.tsx | 140 ++++++++++++++++++ 4 files changed, 206 insertions(+), 4 deletions(-) create mode 100644 react/src/components/AssetDetail/AssetQuestionnaire.test.tsx diff --git a/react/src/__fixtures__/featuresFixture.ts b/react/src/__fixtures__/featuresFixture.ts index 41624232..bdae0b49 100644 --- a/react/src/__fixtures__/featuresFixture.ts +++ b/react/src/__fixtures__/featuresFixture.ts @@ -287,3 +287,57 @@ export const mockVideoFeature: Feature = { }, ], }; + +export const mockQuestionnaireFeature : Feature = { + "id": 2466139, + "project_id": 94, + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + -122.306436952, + 47.653046488 + ] + }, + "properties": { + "_hazmapper": { + "questionnaire": { + "assets": [ + { + "filename": "Q11-Photo-001.jpg", + "coordinates": [ + -122.30645555555556, + 47.65306388888889 + ] + }, + { + "filename": "Q12-Photo-001.jpg", + "coordinates": [ + -122.30648611111111, + 47.65299722222222 + ] + }, + { + "filename": "Q13-Photo-001.jpg", + "coordinates": [ + -122.3064611111111, + 47.652975 + ] + } + ] + } + } + }, + "styles": {}, + "assets": [ + { + "id": 2037094, + "path": "94/816c47f4-b34d-4a30-b0d8-e92b11ba100c", + "uuid": "816c47f4-b34d-4a30-b0d8-e92b11ba100c", + "asset_type": "questionnaire", + "original_path": "project-3891343857756007955-242ac117-0001-012/RApp/asif27/Home/GNSS Base Station Setup (Copy 1) 1690582474191.rqa/GNSS Base Station Setup (Copy 1) 1690582474191.rq", + "original_name": null, + "display_path": "project-3891343857756007955-242ac117-0001-012/RApp/asif27/Home/GNSS Base Station Setup (Copy 1) 1690582474191.rqa/GNSS Base Station Setup (Copy 1) 1690582474191.rq" + } + ] +} diff --git a/react/src/components/AssetDetail/AssetDetail.test.tsx b/react/src/components/AssetDetail/AssetDetail.test.tsx index 41293a55..7d387d7e 100644 --- a/react/src/components/AssetDetail/AssetDetail.test.tsx +++ b/react/src/components/AssetDetail/AssetDetail.test.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render, screen, act } from '@testing-library/react'; import AssetDetail from './AssetDetail'; import { mockImgFeature } from '@hazmapper/__fixtures__/featuresFixture'; +import AssetGeometry from './AssetGeometry'; jest.mock('@hazmapper/hooks', () => ({ useFeatureSelection: jest.fn(), @@ -23,9 +24,16 @@ describe('AssetDetail', () => { isPublicView: false, }; - it('renders all main components', () => { + it('renders all main components', async () => { const { getByText } = render(); const assetGeometry = screen.getByTestId('asset-geometry'); + await act(async () => { + render( + + ); + }); // Check for title, button, and tables expect(getByText('Photo 4.jpg')).toBeDefined(); expect(getByText('Download')).toBeDefined(); diff --git a/react/src/components/AssetDetail/AssetGeometry.test.tsx b/react/src/components/AssetDetail/AssetGeometry.test.tsx index 9d4e67b1..23634f13 100644 --- a/react/src/components/AssetDetail/AssetGeometry.test.tsx +++ b/react/src/components/AssetDetail/AssetGeometry.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; -import GeometryAsset from './AssetGeometry'; +import AssetGeometry from './AssetGeometry'; import { mockImgFeature } from '@hazmapper/__fixtures__/featuresFixture'; jest.mock('@turf/turf', () => ({ @@ -20,7 +20,7 @@ describe('AssetGeometry', () => { }; it('renders geometry for point on an image', () => { - const { getByText } = render(); + const { getByText } = render(); expect(getByText('Geometry: Point')).toBeDefined(); expect(getByText('Latitude')).toBeDefined(); expect(getByText('Longitude')).toBeDefined(); diff --git a/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx b/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx new file mode 100644 index 00000000..b992b782 --- /dev/null +++ b/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx @@ -0,0 +1,140 @@ +import React, { forwardRef } from 'react'; +import { render, screen, fireEvent, act } from '@testing-library/react'; +import { mockQuestionnaireFeature } from '@hazmapper/__fixtures__/featuresFixture'; +import AssetQuestionnaire from './AssetQuestionnaire'; + +// Create a mock ref implementation for Carousel +const mockCarouselRef = { + next: jest.fn(), + prev: jest.fn(), +}; + +// Mock the antd components used in AssetQuestionnaire +jest.mock('antd', () => ({ + Carousel: forwardRef(({ children }: any, ref: any) => { + // Assign the mock methods to the ref + React.useImperativeHandle(ref, () => mockCarouselRef); + return ( +
+ {children} +
+ ); + }), + Space: ({ children }: any) =>
{children}
, + Flex: ({ children }: any) =>
{children}
, +})); + +jest.mock('@tacc/core-components', () => ({ + Button: ({ children, onClick, iconNameBefore }: any) => ( + + ), +})); + +describe('AssetQuestionnaire', () => { + const mockFeatureSource = 'https://example.com/api/assets/123'; + + beforeEach(() => { + // Clear mock function calls before each test + mockCarouselRef.next.mockClear(); + mockCarouselRef.prev.mockClear(); + }); + + const setup = () => { + return render( + + ); + }; + + it('renders all images from the questionnaire assets', async () => { + await act(async () => { + setup(); + }); + + const images = screen.getAllByRole('img'); + expect(images).toHaveLength(mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets.length); + + mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets.forEach((asset, index) => { + const image = images[index]; + const expectedPreviewPath = `${mockFeatureSource}/${asset.filename}`.replace(/\.([^.]+)$/, '.preview.$1'); + + expect(image.getAttribute('src')).toBe(expectedPreviewPath); + expect(image.getAttribute('alt')).toBe(asset.filename); + }); + }); + + it('renders navigation buttons', async () => { + await act(async () => { + setup(); + }); + + const prevButton = screen.getByTestId('button-push-left'); + const nextButton = screen.getByTestId('button-push-right'); + + expect(prevButton).toBeTruthy(); + expect(nextButton).toBeTruthy(); + }); + + it('displays image filenames as captions', async () => { + await act(async () => { + setup(); + }); + + mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets.forEach((asset) => { + const caption = screen.getByText(asset.filename); + expect(caption).toBeTruthy(); + }); + }); + + it('handles carousel navigation', async () => { + await act(async () => { + setup(); + }); + + const prevButton = screen.getByTestId('button-push-left'); + const nextButton = screen.getByTestId('button-push-right'); + + await act(async () => { + fireEvent.click(nextButton); + }); + expect(mockCarouselRef.next).toHaveBeenCalled(); + + await act(async () => { + fireEvent.click(prevButton); + }); + expect(mockCarouselRef.prev).toHaveBeenCalled(); + }); + + it('renders "No images available" when there are no assets', async () => { + const emptyFeature = { + ...mockQuestionnaireFeature, + properties: { + _hazmapper: { + questionnaire: { + assets: [], + }, + }, + }, + }; + + await act(async () => { + render( + + ); + }); + + const noImagesText = screen.getByText('No images available'); + expect(noImagesText).toBeTruthy(); + }); +}); From e22a933dc3e846208717c9fc5968ea412b62a098 Mon Sep 17 00:00:00 2001 From: sophia-massie Date: Fri, 10 Jan 2025 17:42:27 -0600 Subject: [PATCH 3/7] - Linting and asset style fixes - Adds padding to questionnaire image caption - Adds better scrolling behavior to geometry table --- react/src/__fixtures__/featuresFixture.ts | 80 ++++++++----------- .../AssetDetail/AssetDetail.module.css | 1 + .../AssetDetail/AssetDetail.test.tsx | 6 +- .../components/AssetDetail/AssetGeometry.tsx | 5 +- .../AssetDetail/AssetQuestionnaire.test.tsx | 50 ++++++------ 5 files changed, 67 insertions(+), 75 deletions(-) diff --git a/react/src/__fixtures__/featuresFixture.ts b/react/src/__fixtures__/featuresFixture.ts index bdae0b49..5af397f2 100644 --- a/react/src/__fixtures__/featuresFixture.ts +++ b/react/src/__fixtures__/featuresFixture.ts @@ -288,56 +288,46 @@ export const mockVideoFeature: Feature = { ], }; -export const mockQuestionnaireFeature : Feature = { - "id": 2466139, - "project_id": 94, - "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [ - -122.306436952, - 47.653046488 - ] +export const mockQuestionnaireFeature: Feature = { + id: 2466139, + project_id: 94, + type: 'Feature', + geometry: { + type: 'Point', + coordinates: [-122.306436952, 47.653046488], }, - "properties": { - "_hazmapper": { - "questionnaire": { - "assets": [ + properties: { + _hazmapper: { + questionnaire: { + assets: [ { - "filename": "Q11-Photo-001.jpg", - "coordinates": [ - -122.30645555555556, - 47.65306388888889 - ] + filename: 'Q11-Photo-001.jpg', + coordinates: [-122.30645555555556, 47.65306388888889], }, { - "filename": "Q12-Photo-001.jpg", - "coordinates": [ - -122.30648611111111, - 47.65299722222222 - ] + filename: 'Q12-Photo-001.jpg', + coordinates: [-122.30648611111111, 47.65299722222222], }, { - "filename": "Q13-Photo-001.jpg", - "coordinates": [ - -122.3064611111111, - 47.652975 - ] - } - ] - } - } + filename: 'Q13-Photo-001.jpg', + coordinates: [-122.3064611111111, 47.652975], + }, + ], + }, + }, }, - "styles": {}, - "assets": [ + styles: {}, + assets: [ { - "id": 2037094, - "path": "94/816c47f4-b34d-4a30-b0d8-e92b11ba100c", - "uuid": "816c47f4-b34d-4a30-b0d8-e92b11ba100c", - "asset_type": "questionnaire", - "original_path": "project-3891343857756007955-242ac117-0001-012/RApp/asif27/Home/GNSS Base Station Setup (Copy 1) 1690582474191.rqa/GNSS Base Station Setup (Copy 1) 1690582474191.rq", - "original_name": null, - "display_path": "project-3891343857756007955-242ac117-0001-012/RApp/asif27/Home/GNSS Base Station Setup (Copy 1) 1690582474191.rqa/GNSS Base Station Setup (Copy 1) 1690582474191.rq" - } - ] -} + id: 2037094, + path: '94/816c47f4-b34d-4a30-b0d8-e92b11ba100c', + uuid: '816c47f4-b34d-4a30-b0d8-e92b11ba100c', + asset_type: 'questionnaire', + original_path: + 'project-3891343857756007955-242ac117-0001-012/RApp/asif27/Home/GNSS Base Station Setup (Copy 1) 1690582474191.rqa/GNSS Base Station Setup (Copy 1) 1690582474191.rq', + original_name: null, + display_path: + 'project-3891343857756007955-242ac117-0001-012/RApp/asif27/Home/GNSS Base Station Setup (Copy 1) 1690582474191.rqa/GNSS Base Station Setup (Copy 1) 1690582474191.rq', + }, + ], +}; diff --git a/react/src/components/AssetDetail/AssetDetail.module.css b/react/src/components/AssetDetail/AssetDetail.module.css index 3730c736..ea06ed06 100644 --- a/react/src/components/AssetDetail/AssetDetail.module.css +++ b/react/src/components/AssetDetail/AssetDetail.module.css @@ -89,6 +89,7 @@ th { .caption { color: #1f5c7a; font-size: 0.8em; + padding-bottom: 0.8em; } .questionnaireImage { width: 100%; diff --git a/react/src/components/AssetDetail/AssetDetail.test.tsx b/react/src/components/AssetDetail/AssetDetail.test.tsx index 7d387d7e..3bfa46fe 100644 --- a/react/src/components/AssetDetail/AssetDetail.test.tsx +++ b/react/src/components/AssetDetail/AssetDetail.test.tsx @@ -28,11 +28,7 @@ describe('AssetDetail', () => { const { getByText } = render(); const assetGeometry = screen.getByTestId('asset-geometry'); await act(async () => { - render( - - ); + render(); }); // Check for title, button, and tables expect(getByText('Photo 4.jpg')).toBeDefined(); diff --git a/react/src/components/AssetDetail/AssetGeometry.tsx b/react/src/components/AssetDetail/AssetGeometry.tsx index 7cc7b2fa..cb9513a3 100644 --- a/react/src/components/AssetDetail/AssetGeometry.tsx +++ b/react/src/components/AssetDetail/AssetGeometry.tsx @@ -2,6 +2,7 @@ import React from 'react'; import _ from 'lodash'; import * as turf from '@turf/turf'; import { Feature, FeatureType } from '@hazmapper/types'; +import styles from './AssetDetail.module.css'; interface AssetGeometryProps { selectedFeature: Feature; @@ -18,7 +19,7 @@ const AssetGeometry: React.FC = ({ selectedFeature }) => { const geometryType = selectedFeature.geometry.type; return ( - <> +
{geometryType === FeatureType.Point && ( @@ -111,7 +112,7 @@ const AssetGeometry: React.FC = ({ selectedFeature }) => {
)} - +
); }; diff --git a/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx b/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx index b992b782..f0bb8c9d 100644 --- a/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx +++ b/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx @@ -14,11 +14,7 @@ jest.mock('antd', () => ({ Carousel: forwardRef(({ children }: any, ref: any) => { // Assign the mock methods to the ref React.useImperativeHandle(ref, () => mockCarouselRef); - return ( -
- {children} -
- ); + return
{children}
; }), Space: ({ children }: any) =>
{children}
, Flex: ({ children }: any) =>
{children}
, @@ -26,10 +22,7 @@ jest.mock('antd', () => ({ jest.mock('@tacc/core-components', () => ({ Button: ({ children, onClick, iconNameBefore }: any) => ( - @@ -60,15 +53,24 @@ describe('AssetQuestionnaire', () => { }); const images = screen.getAllByRole('img'); - expect(images).toHaveLength(mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets.length); - - mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets.forEach((asset, index) => { - const image = images[index]; - const expectedPreviewPath = `${mockFeatureSource}/${asset.filename}`.replace(/\.([^.]+)$/, '.preview.$1'); - - expect(image.getAttribute('src')).toBe(expectedPreviewPath); - expect(image.getAttribute('alt')).toBe(asset.filename); - }); + expect(images).toHaveLength( + mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets + .length + ); + + mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets.forEach( + (asset, index) => { + const image = images[index]; + const expectedPreviewPath = + `${mockFeatureSource}/${asset.filename}`.replace( + /\.([^.]+)$/, + '.preview.$1' + ); + + expect(image.getAttribute('src')).toBe(expectedPreviewPath); + expect(image.getAttribute('alt')).toBe(asset.filename); + } + ); }); it('renders navigation buttons', async () => { @@ -78,7 +80,7 @@ describe('AssetQuestionnaire', () => { const prevButton = screen.getByTestId('button-push-left'); const nextButton = screen.getByTestId('button-push-right'); - + expect(prevButton).toBeTruthy(); expect(nextButton).toBeTruthy(); }); @@ -88,10 +90,12 @@ describe('AssetQuestionnaire', () => { setup(); }); - mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets.forEach((asset) => { - const caption = screen.getByText(asset.filename); - expect(caption).toBeTruthy(); - }); + mockQuestionnaireFeature?.properties?._hazmapper.questionnaire.assets.forEach( + (asset) => { + const caption = screen.getByText(asset.filename); + expect(caption).toBeTruthy(); + } + ); }); it('handles carousel navigation', async () => { From 5a325f4242274a296a66a8b982c1a4ded1a9bbfc Mon Sep 17 00:00:00 2001 From: sophia-massie Date: Fri, 10 Jan 2025 18:45:04 -0600 Subject: [PATCH 4/7] - React linting fix --- react/src/components/AssetDetail/AssetQuestionnaire.test.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx b/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx index f0bb8c9d..975ff7f6 100644 --- a/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx +++ b/react/src/components/AssetDetail/AssetQuestionnaire.test.tsx @@ -11,8 +11,7 @@ const mockCarouselRef = { // Mock the antd components used in AssetQuestionnaire jest.mock('antd', () => ({ - Carousel: forwardRef(({ children }: any, ref: any) => { - // Assign the mock methods to the ref + Carousel: forwardRef(function Carousel({ children }: any, ref: any) { React.useImperativeHandle(ref, () => mockCarouselRef); return
{children}
; }), From d835fea2cae89d81490c40ccb523d328c92e5f08 Mon Sep 17 00:00:00 2001 From: sophia-massie Date: Mon, 13 Jan 2025 15:49:15 -0600 Subject: [PATCH 5/7] Removes metadata tables for questionnaires based on RAPP feedback --- .../components/AssetDetail/AssetDetail.tsx | 96 ++++++++++--------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/react/src/components/AssetDetail/AssetDetail.tsx b/react/src/components/AssetDetail/AssetDetail.tsx index a955b054..49e4c906 100644 --- a/react/src/components/AssetDetail/AssetDetail.tsx +++ b/react/src/components/AssetDetail/AssetDetail.tsx @@ -64,59 +64,61 @@ const AssetDetail: React.FC = ({ /> -
-
- - - - - - - - {selectedFeature?.properties && - Object.keys(selectedFeature.properties).length > 0 ? ( - (() => { - /* Function check that shows the "There are no metadata properties" + {featureType !== FeatureType.Questionnaire && ( +
+
+
- Metadata -
+ + + + + + + {selectedFeature?.properties && + Object.keys(selectedFeature.properties).length > 0 ? ( + (() => { + /* Function check that shows the "There are no metadata properties" in any of these cases: - The properties object is empty or null - The properties object only contains keys that start with "_hazmapper" - The properties object exists but has no properties*/ - const filteredProperties = Object.entries( - selectedFeature.properties - ) - .filter(([key]) => !key.startsWith('_hazmapper')) - .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)); - return filteredProperties.length > 0 ? ( - filteredProperties.map(([propKey, propValue]) => ( - - - + const filteredProperties = Object.entries( + selectedFeature.properties + ) + .filter(([key]) => !key.startsWith('_hazmapper')) + .sort(([keyA], [keyB]) => keyA.localeCompare(keyB)); + return filteredProperties.length > 0 ? ( + filteredProperties.map(([propKey, propValue]) => ( + + + + + )) + ) : ( + + - )) - ) : ( - - - - ); - })() - ) : ( - - - - )} - -
+ Metadata +
{_.startCase(propKey)} - {propKey.startsWith('description') ? ( - {propValue} - ) : ( - _.trim(JSON.stringify(propValue), '"') - )} -
{_.startCase(propKey)} + {propKey.startsWith('description') ? ( + {propValue} + ) : ( + _.trim(JSON.stringify(propValue), '"') + )} +
There are no metadata properties.
There are no metadata properties.
There are no metadata properties.
- + ); + })() + ) : ( + + There are no metadata properties. + + )} + + + +
- + )} ); }; From d4ac77d81e13e570c2a0c63985026e9b90bfaa8f Mon Sep 17 00:00:00 2001 From: sophia-massie Date: Mon, 13 Jan 2025 16:01:51 -0600 Subject: [PATCH 6/7] - Stops restricting carousel height in Questionnaire --- react/src/components/AssetDetail/AssetDetail.module.css | 1 - 1 file changed, 1 deletion(-) diff --git a/react/src/components/AssetDetail/AssetDetail.module.css b/react/src/components/AssetDetail/AssetDetail.module.css index ea06ed06..bd94b345 100644 --- a/react/src/components/AssetDetail/AssetDetail.module.css +++ b/react/src/components/AssetDetail/AssetDetail.module.css @@ -93,5 +93,4 @@ th { } .questionnaireImage { width: 100%; - height: 30em; } From 667f29ae0d02efb3bc922c46189a53de7875fc26 Mon Sep 17 00:00:00 2001 From: sophia-massie Date: Mon, 13 Jan 2025 16:40:54 -0600 Subject: [PATCH 7/7] - Reverts style change from last commit --- react/src/components/AssetDetail/AssetDetail.module.css | 1 + 1 file changed, 1 insertion(+) diff --git a/react/src/components/AssetDetail/AssetDetail.module.css b/react/src/components/AssetDetail/AssetDetail.module.css index bd94b345..ea06ed06 100644 --- a/react/src/components/AssetDetail/AssetDetail.module.css +++ b/react/src/components/AssetDetail/AssetDetail.module.css @@ -93,4 +93,5 @@ th { } .questionnaireImage { width: 100%; + height: 30em; }