From 4aa25217767219b8326498576e7466464f802ff5 Mon Sep 17 00:00:00 2001 From: John Phan Date: Tue, 19 Nov 2024 12:35:21 -0800 Subject: [PATCH 1/5] 35176 Allow selecting multiple agents on workbook upload - Enable multi select for certain fields TODO: - Fix saving and POST request logic --- .../components/workbook/column-mapping/useColumnMapping.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx b/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx index aa5d929f9..3b7901ca2 100644 --- a/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx +++ b/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx @@ -847,6 +847,7 @@ export function useColumnMapping() { const duplicateResourcesSelected = duplicateResources.includes(fieldValue); const showDuplicateWarningTooltip = hasDuplicatesResources && duplicateResourcesSelected; + const multiSelectFields = new Set(["preparedBy.displayName"]); return (
@@ -855,7 +856,7 @@ export function useColumnMapping() { name={selectElemName} options={options} hideLabel={true} - isMulti={false} + isMulti={multiSelectFields.has(fieldPath)} selectProps={{ isClearable: true, menuPortalTarget: document.body, From 6f5e7eb69a8b014daa73d4a80896743b810363ca Mon Sep 17 00:00:00 2001 From: John Phan Date: Wed, 20 Nov 2024 12:38:11 -0800 Subject: [PATCH 2/5] 35176 Allow selecting multile agents on workbook upload - Use PersonSelectField dropdown instead of SelectField for column headers that sets agents - Change resolving relationships to allow for array values - Change relationship validation mapping and onchange to handle new array values TODO: - Fix final linking and saving step --- .../column-mapping/WorkbookColumnMapping.tsx | 42 +++++--- .../column-mapping/useColumnMapping.tsx | 98 +++++++++++++------ .../components/workbook/types/Workbook.ts | 17 ++-- 3 files changed, 107 insertions(+), 50 deletions(-) diff --git a/packages/dina-ui/components/workbook/column-mapping/WorkbookColumnMapping.tsx b/packages/dina-ui/components/workbook/column-mapping/WorkbookColumnMapping.tsx index 3c75b81c1..b94b1074e 100644 --- a/packages/dina-ui/components/workbook/column-mapping/WorkbookColumnMapping.tsx +++ b/packages/dina-ui/components/workbook/column-mapping/WorkbookColumnMapping.tsx @@ -139,12 +139,20 @@ export function WorkbookColumnMapping({ const values = Object.keys( (columnUniqueValues ?? {})[sheet]?.[columnName] || {} ); - if (!relationshipMapping[columnName] && values.length > 0) { + + if (Array.isArray(relationshipMapping[columnName])) { + if (!relationshipMapping[columnName].length) { + unmappedColumnNames.push( + workbookColumnMap[columnName].originalColumnName + ); + } + } else if (!relationshipMapping[columnName] && values.length > 0) { unmappedColumnNames.push( workbookColumnMap[columnName].originalColumnName ); } else { const mappedValues = Object.keys(relationshipMapping[columnName] || {}); + for (const value of values) { if (mappedValues.indexOf(value.replace(".", "_")) === -1) { unmappedColumnNames.push( @@ -530,12 +538,11 @@ export function WorkbookColumnMapping({ async function onRelatedRecordChange( columnHeader: string, fieldValue: string, - relatedRecord: string, + relatedRecord: string | string[], targetType: string ) { const columnHeaderFormatted = columnHeader.replaceAll(".", "_"); const fieldValueFormatted = fieldValue.replaceAll(".", "_"); - if (relationshipMapping) { // Check if the dropdown option selected is undefined (was cleared) if (!relatedRecord) { @@ -546,16 +553,27 @@ export function WorkbookColumnMapping({ setRelationshipMapping(updatedMapping); } } else { - setRelationshipMapping({ - ...relationshipMapping, - [columnHeaderFormatted]: { - ...relationshipMapping?.[columnHeaderFormatted], - [fieldValueFormatted]: { - id: relatedRecord, - type: targetType + if (Array.isArray(relatedRecord)) { + const newValue = relatedRecord.map((id) => ({ + id, + type: targetType + })); + setRelationshipMapping({ + ...relationshipMapping, + [columnHeaderFormatted]: newValue + }); + } else { + setRelationshipMapping({ + ...relationshipMapping, + [columnHeaderFormatted]: { + ...relationshipMapping?.[columnHeaderFormatted], + [fieldValueFormatted]: { + id: relatedRecord, + type: targetType + } } - } - }); + }); + } } } } diff --git a/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx b/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx index 3b7901ca2..d70aa307d 100644 --- a/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx +++ b/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx @@ -6,6 +6,7 @@ import { Tooltip, filterBy, useApiClient, + useDinaFormContext, useQuery } from "../../../../common-ui/lib"; import { useDinaIntl } from "../../../intl/dina-ui-intl"; @@ -31,6 +32,12 @@ import { FieldMapType } from "./WorkbookColumnMapping"; import { Person } from "../../../types/agent-api/resources/Person"; import { FaExclamationTriangle } from "react-icons/fa"; import { ResourceNameIdentifier } from "../../../types/common/resources/ResourceNameIdentifier"; +import { PersonSelectField } from "../../resource-select-fields/resource-select-fields"; + +const PERSON_SELECT_FIELDS = new Set([ + "preparedBy.displayName", + "collectingEvent.collectors.displayName" +]); export function useColumnMapping() { const { formatMessage } = useDinaIntl(); @@ -721,13 +728,16 @@ export function useColumnMapping() { metadatas.find((item) => compareAlphanumeric(item.name, value)); break; } - // If relationship is found, set it. If not, reset it so it's empty. if (found) { - theRelationshipMapping[columnHeader][value.replace(".", "_")] = pick( - found, - ["id", "type"] - ); + if (PERSON_SELECT_FIELDS.has(fieldPath)) { + theRelationshipMapping[columnHeader] = [ + pick(found, ["id", "type"]) + ]; + } else { + theRelationshipMapping[columnHeader][value.replace(".", "_")] = + pick(found, ["id", "type"]); + } } } } @@ -748,10 +758,12 @@ export function useColumnMapping() { return undefined; } - const selectElemName = `relationshipMapping.${columnHeader.replaceAll( - ".", - "_" - )}.${fieldValue.replaceAll(".", "_")}.id`; + const selectElemName = PERSON_SELECT_FIELDS.has(fieldPath) + ? `relationshipMapping.${columnHeader.replaceAll(".", "_")}` + : `relationshipMapping.${columnHeader.replaceAll( + ".", + "_" + )}.${fieldValue.replaceAll(".", "_")}.id`; let options: any[] = []; let targetType: string = ""; @@ -847,32 +859,54 @@ export function useColumnMapping() { const duplicateResourcesSelected = duplicateResources.includes(fieldValue); const showDuplicateWarningTooltip = hasDuplicatesResources && duplicateResourcesSelected; - const multiSelectFields = new Set(["preparedBy.displayName"]); return (
- ({ ...base, zIndex: 9999 }) - } - }} - onChange={(newValue) => { - onChangeRelatedRecord( - columnHeader, - fieldValue, - newValue as string, - targetType - ); - }} - /> + {PERSON_SELECT_FIELDS.has(fieldPath) ? ( + { + onChangeRelatedRecord( + columnHeader, + fieldValue, + (newValue as any)?.map((person) => person.id), + targetType + ); + }} + className="flex-fill" + name={selectElemName} + hideLabel={true} + isMulti={true} + selectProps={{ + isClearable: true, + menuPortalTarget: document.body, + styles: { + menuPortal: (base) => ({ ...base, zIndex: 9999 }) + } + }} + /> + ) : ( + ({ ...base, zIndex: 9999 }) + } + }} + onChange={(newValue) => { + onChangeRelatedRecord( + columnHeader, + fieldValue, + newValue as string, + targetType + ); + }} + /> + )} {showDuplicateWarningTooltip && ( Date: Wed, 20 Nov 2024 13:21:53 -0800 Subject: [PATCH 3/5] 35176 Allow selecting multiple agents on workbook upload - Fixed handling linking and saving multiple agents on submission --- .../column-mapping/useColumnMapping.tsx | 6 +--- .../workbook/utils/useWorkbookConverter.tsx | 31 +++++++++++++------ .../workbook/utils/workbookMappingUtils.ts | 4 +++ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx b/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx index d70aa307d..d9eb7c372 100644 --- a/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx +++ b/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx @@ -21,6 +21,7 @@ import FieldMappingConfig from "../utils/FieldMappingConfig"; import { useWorkbookConverter } from "../utils/useWorkbookConverter"; import { FieldOptionType, + PERSON_SELECT_FIELDS, WorkbookColumnInfo, compareAlphanumeric, findMatchField, @@ -34,11 +35,6 @@ import { FaExclamationTriangle } from "react-icons/fa"; import { ResourceNameIdentifier } from "../../../types/common/resources/ResourceNameIdentifier"; import { PersonSelectField } from "../../resource-select-fields/resource-select-fields"; -const PERSON_SELECT_FIELDS = new Set([ - "preparedBy.displayName", - "collectingEvent.collectors.displayName" -]); - export function useColumnMapping() { const { formatMessage } = useDinaIntl(); const { apiClient } = useApiClient(); diff --git a/packages/dina-ui/components/workbook/utils/useWorkbookConverter.tsx b/packages/dina-ui/components/workbook/utils/useWorkbookConverter.tsx index 7d98183ef..8e8da4c9e 100644 --- a/packages/dina-ui/components/workbook/utils/useWorkbookConverter.tsx +++ b/packages/dina-ui/components/workbook/utils/useWorkbookConverter.tsx @@ -6,6 +6,7 @@ import { FieldMappingConfigType, getFlattenedConfig, LinkOrCreateSetting, + PERSON_SELECT_FIELDS, WorkbookColumnMap, WorkbookDataTypeEnum } from ".."; @@ -400,10 +401,12 @@ export function useWorkbookConverter( ) { const attributeName = fieldPath.substring(fieldPath.lastIndexOf(".") + 1); const value = resource[attributeName]; + if (isEmptyWorkbookValue(value)) { delete resource[attributeName]; return; } + if (attributeName === "relationshipConfig") { resource.type = value.type; resource.relationships = {}; @@ -574,10 +577,17 @@ export function useWorkbookConverter( !isObject(childValue) && !Array.isArray(childValue) ) { - valueToLink = - columnMap[fieldPath + "." + attrNameInValue]?.[ - childValue.trim().replace(".", "_") - ]; + if ( + PERSON_SELECT_FIELDS.has(`${fieldPath}.${attrNameInValue}`) + ) { + valueToLink = columnMap[fieldPath + "." + attrNameInValue]; + } else { + valueToLink = + columnMap[fieldPath + "." + attrNameInValue]?.[ + childValue.trim().replace(".", "_") + ]; + } + if (valueToLink) { break; } @@ -585,7 +595,9 @@ export function useWorkbookConverter( } } if (valueToLink) { - valuesForRelationship.push(valueToLink); + valuesForRelationship.push( + ...(Array.isArray(valueToLink) ? valueToLink : [valueToLink]) + ); } else { if ( relationshipConfig.linkOrCreateSetting === @@ -648,15 +660,14 @@ export function useWorkbookConverter( } } } - if (valuesForRelationship.length === value.length) { - if (!resource.relationships) { - resource.relationships = {}; - } + if (!resource.relationships) { + resource.relationships = {}; + } + if (valuesForRelationship.length) { resource.relationships[attributeName] = { data: valuesForRelationship }; delete resource[attributeName]; - return; } } } diff --git a/packages/dina-ui/components/workbook/utils/workbookMappingUtils.ts b/packages/dina-ui/components/workbook/utils/workbookMappingUtils.ts index e73aa14a6..3c3475910 100644 --- a/packages/dina-ui/components/workbook/utils/workbookMappingUtils.ts +++ b/packages/dina-ui/components/workbook/utils/workbookMappingUtils.ts @@ -900,3 +900,7 @@ export function trimSpace(workbookData: WorkbookJSON) { } return workbookData; } +export const PERSON_SELECT_FIELDS = new Set([ + "preparedBy.displayName", + "collectingEvent.collectors.displayName" +]); From b73c17c4e47f0fd39b22fe60cddd78d7895bd977 Mon Sep 17 00:00:00 2001 From: BrandonAndre Date: Tue, 26 Nov 2024 11:41:19 -0500 Subject: [PATCH 4/5] - Fix test --- .../collection/collecting-event/__test__/edit.test.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/dina-ui/page-tests/collection/collecting-event/__test__/edit.test.tsx b/packages/dina-ui/page-tests/collection/collecting-event/__test__/edit.test.tsx index 410a8488c..2e3ad9d0e 100644 --- a/packages/dina-ui/page-tests/collection/collecting-event/__test__/edit.test.tsx +++ b/packages/dina-ui/page-tests/collection/collecting-event/__test__/edit.test.tsx @@ -449,12 +449,7 @@ describe("collecting-event edit page", () => { expect(wrapper.getByRole("button", { name: /primary/i })).toBeDisabled(); // Add a second assertion: - userEvent.click( - wrapper.getByRole("button", { - name: /add another georeference assertion/i - }) - ); - + userEvent.click(wrapper.getByTestId("add-another-button")); await new Promise(setImmediate); // Make 2nd assertion primary: From 86e734690191d17e46e2db53ba48eeaad984fce2 Mon Sep 17 00:00:00 2001 From: John Phan Date: Tue, 26 Nov 2024 13:39:15 -0800 Subject: [PATCH 5/5] 35176 Review - Fixed selecting agents for one sample changed agents for all rows - Fixe saving to handle different agents for each sample --- .../column-mapping/WorkbookColumnMapping.tsx | 5 ++++- .../column-mapping/useColumnMapping.tsx | 7 +++++-- .../components/workbook/types/Workbook.ts | 18 +++++++++--------- .../workbook/utils/useWorkbookConverter.tsx | 14 ++++---------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/dina-ui/components/workbook/column-mapping/WorkbookColumnMapping.tsx b/packages/dina-ui/components/workbook/column-mapping/WorkbookColumnMapping.tsx index b94b1074e..1c6edefed 100644 --- a/packages/dina-ui/components/workbook/column-mapping/WorkbookColumnMapping.tsx +++ b/packages/dina-ui/components/workbook/column-mapping/WorkbookColumnMapping.tsx @@ -560,7 +560,10 @@ export function WorkbookColumnMapping({ })); setRelationshipMapping({ ...relationshipMapping, - [columnHeaderFormatted]: newValue + [columnHeaderFormatted]: { + ...relationshipMapping?.[columnHeaderFormatted], + [fieldValueFormatted]: newValue + } }); } else { setRelationshipMapping({ diff --git a/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx b/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx index d9eb7c372..039fd1e39 100644 --- a/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx +++ b/packages/dina-ui/components/workbook/column-mapping/useColumnMapping.tsx @@ -727,7 +727,7 @@ export function useColumnMapping() { // If relationship is found, set it. If not, reset it so it's empty. if (found) { if (PERSON_SELECT_FIELDS.has(fieldPath)) { - theRelationshipMapping[columnHeader] = [ + theRelationshipMapping[columnHeader][value.replace(".", "_")] = [ pick(found, ["id", "type"]) ]; } else { @@ -755,7 +755,10 @@ export function useColumnMapping() { } const selectElemName = PERSON_SELECT_FIELDS.has(fieldPath) - ? `relationshipMapping.${columnHeader.replaceAll(".", "_")}` + ? `relationshipMapping.${columnHeader.replaceAll( + ".", + "_" + )}.${fieldValue.replaceAll(".", "_")}` : `relationshipMapping.${columnHeader.replaceAll( ".", "_" diff --git a/packages/dina-ui/components/workbook/types/Workbook.ts b/packages/dina-ui/components/workbook/types/Workbook.ts index b0462805f..887472863 100644 --- a/packages/dina-ui/components/workbook/types/Workbook.ts +++ b/packages/dina-ui/components/workbook/types/Workbook.ts @@ -156,15 +156,15 @@ export interface WorkbookColumnMap { } export interface RelationshipMapping { - [columnHeader: string]: - | { - [value: string]: { + [columnHeader: string]: { + [value: string]: + | { id: string; type: string; - }; - } - | { - id: string; - type: string; - }[]; + } + | { + id: string; + type: string; + }[]; + }; } diff --git a/packages/dina-ui/components/workbook/utils/useWorkbookConverter.tsx b/packages/dina-ui/components/workbook/utils/useWorkbookConverter.tsx index 8e8da4c9e..a4dd94af5 100644 --- a/packages/dina-ui/components/workbook/utils/useWorkbookConverter.tsx +++ b/packages/dina-ui/components/workbook/utils/useWorkbookConverter.tsx @@ -577,16 +577,10 @@ export function useWorkbookConverter( !isObject(childValue) && !Array.isArray(childValue) ) { - if ( - PERSON_SELECT_FIELDS.has(`${fieldPath}.${attrNameInValue}`) - ) { - valueToLink = columnMap[fieldPath + "." + attrNameInValue]; - } else { - valueToLink = - columnMap[fieldPath + "." + attrNameInValue]?.[ - childValue.trim().replace(".", "_") - ]; - } + valueToLink = + columnMap[fieldPath + "." + attrNameInValue]?.[ + childValue.trim().replace(".", "_") + ]; if (valueToLink) { break;