diff --git a/specifyweb/frontend/js_src/lib/components/WbPlanView/__tests__/navigator.test.ts b/specifyweb/frontend/js_src/lib/components/WbPlanView/__tests__/navigator.test.ts index f6487ecf342..27c453c6d9f 100644 --- a/specifyweb/frontend/js_src/lib/components/WbPlanView/__tests__/navigator.test.ts +++ b/specifyweb/frontend/js_src/lib/components/WbPlanView/__tests__/navigator.test.ts @@ -20,8 +20,8 @@ theories(getMappingLineData, [ ], out: [ { - defaultValue: 'determinations', customSelectSubtype: 'simple', + defaultValue: 'determinations', selectLabel: localized('Collection Object'), fieldsData: { catalogNumber: { @@ -74,15 +74,6 @@ theories(getMappingLineData, [ isDefault: false, isRelationship: false, }, - leftSideRels: { - isDefault: false, - isEnabled: true, - isHidden: false, - isRelationship: true, - isRequired: false, - optionLabel: 'Left Side Rels', - tableName: 'CollectionRelationship', - }, altCatalogNumber: { optionLabel: 'Prev/Exch #', isEnabled: true, @@ -115,15 +106,6 @@ theories(getMappingLineData, [ isDefault: false, isRelationship: false, }, - rightSideRels: { - isDefault: false, - isEnabled: true, - isHidden: false, - isRelationship: true, - isRequired: false, - optionLabel: 'Right Side Rels', - tableName: 'CollectionRelationship', - }, fieldNumber: { optionLabel: 'Voucher', isEnabled: true, @@ -168,6 +150,24 @@ theories(getMappingLineData, [ isRelationship: true, tableName: 'CollectionObjectAttribute', }, + collection: { + optionLabel: 'Collection', + isEnabled: true, + isRequired: false, + isHidden: false, + isDefault: false, + isRelationship: true, + tableName: 'Collection', + }, + collectionObjectAttachments: { + optionLabel: 'Collection Object Attachments', + isEnabled: true, + isRequired: false, + isHidden: false, + isDefault: false, + isRelationship: true, + tableName: 'CollectionObjectAttachment', + }, collectionObjectCitations: { optionLabel: 'Collection Object Citations', isEnabled: true, @@ -213,23 +213,14 @@ theories(getMappingLineData, [ isRelationship: true, tableName: 'CollectingEvent', }, - collection: { - isDefault: false, + leftSideRels: { + optionLabel: 'Left Side Rels', isEnabled: true, - isHidden: false, - isRelationship: true, isRequired: false, - optionLabel: 'Collection', - tableName: 'Collection', - }, - collectionObjectAttachments: { - isDefault: false, - isEnabled: true, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Collection Object Attachments', - tableName: 'CollectionObjectAttachment', + tableName: 'CollectionRelationship', }, preparations: { optionLabel: 'Preparations', @@ -240,6 +231,15 @@ theories(getMappingLineData, [ isRelationship: true, tableName: 'Preparation', }, + rightSideRels: { + optionLabel: 'Right Side Rels', + isEnabled: true, + isRequired: false, + isHidden: false, + isDefault: false, + isRelationship: true, + tableName: 'CollectionRelationship', + }, voucherRelationships: { optionLabel: 'Voucher Relationships', isEnabled: true, @@ -253,8 +253,8 @@ theories(getMappingLineData, [ tableName: 'CollectionObject', }, { - defaultValue: '#1', customSelectSubtype: 'toMany', + defaultValue: '#1', selectLabel: localized('Determination'), fieldsData: { '#1': { @@ -273,8 +273,8 @@ theories(getMappingLineData, [ tableName: 'Determination', }, { - defaultValue: 'taxon', customSelectSubtype: 'simple', + defaultValue: 'taxon', selectLabel: localized('Determination'), fieldsData: { determinedDate: { @@ -310,6 +310,15 @@ theories(getMappingLineData, [ isRelationship: true, tableName: 'Agent', }, + determiners: { + optionLabel: 'Determiners', + isEnabled: true, + isRequired: false, + isHidden: false, + isDefault: false, + isRelationship: true, + tableName: 'Determiner', + }, taxon: { optionLabel: 'Taxon', isEnabled: true, @@ -323,8 +332,8 @@ theories(getMappingLineData, [ tableName: 'Determination', }, { - defaultValue: '$Family', customSelectSubtype: 'tree', + defaultValue: '$Family', selectLabel: localized('Taxon'), fieldsData: { $Kingdom: { @@ -391,8 +400,8 @@ theories(getMappingLineData, [ tableName: 'Taxon', }, { - defaultValue: 'name', customSelectSubtype: 'simple', + defaultValue: 'name', selectLabel: localized('Taxon'), fieldsData: { author: { @@ -462,13 +471,14 @@ theories(getMappingLineData, [ { customSelectSubtype: 'simple', defaultValue: 'determinations', + selectLabel: localized('Collection Object'), fieldsData: { '-formatted': { - isDefault: false, - isEnabled: true, - isRelationship: false, optionLabel: '(formatted)', tableName: 'CollectionObject', + isRelationship: false, + isDefault: false, + isEnabled: true, }, absoluteAges: { isDefault: false, @@ -479,71 +489,142 @@ theories(getMappingLineData, [ optionLabel: 'Absolute Ages', tableName: 'AbsoluteAge', }, - accession: { - isDefault: false, + catalogNumber: { + optionLabel: 'Cat #', isEnabled: true, - isHidden: false, - isRelationship: true, isRequired: false, - optionLabel: 'Accession #', - tableName: 'Accession', - }, - altCatalogNumber: { + isHidden: false, isDefault: false, + isRelationship: false, + }, + 'catalogedDate-fullDate': { + optionLabel: 'Cat Date', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, - isRequired: false, - optionLabel: 'Prev/Exch #', }, - catalogNumber: { - isDefault: false, + 'catalogedDate-day': { + optionLabel: 'Cat Date (Day)', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, - isRequired: false, - optionLabel: 'Cat #', }, - 'catalogedDate-day': { + 'catalogedDate-month': { + optionLabel: 'Cat Date (Month)', + isEnabled: true, + isRequired: false, + isHidden: false, isDefault: false, + isRelationship: false, + }, + 'catalogedDate-year': { + optionLabel: 'Cat Date (Year)', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, + }, + reservedText: { + optionLabel: 'CT Scan', + isEnabled: true, isRequired: false, - optionLabel: 'Cat Date (Day)', + isHidden: false, + isDefault: false, + isRelationship: false, }, - 'catalogedDate-fullDate': { + 'timestampModified-fullDate': { + optionLabel: 'Date Edited', + isEnabled: true, + isRequired: false, + isHidden: false, isDefault: false, + isRelationship: false, + }, + 'timestampModified-day': { + optionLabel: 'Date Edited (Day)', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, + }, + 'timestampModified-month': { + optionLabel: 'Date Edited (Month)', + isEnabled: true, isRequired: false, - optionLabel: 'Cat Date', + isHidden: false, + isDefault: false, + isRelationship: false, }, - 'catalogedDate-month': { + 'timestampModified-year': { + optionLabel: 'Date Edited (Year)', + isEnabled: true, + isRequired: false, + isHidden: false, isDefault: false, + isRelationship: false, + }, + guid: { + optionLabel: 'GUID', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, + }, + altCatalogNumber: { + optionLabel: 'Prev/Exch #', + isEnabled: true, isRequired: false, - optionLabel: 'Cat Date (Month)', + isHidden: false, + isDefault: false, + isRelationship: false, }, - 'catalogedDate-year': { + projectNumber: { + optionLabel: 'Project Number', + isEnabled: true, + isRequired: false, + isHidden: false, isDefault: false, + isRelationship: false, + }, + remarks: { + optionLabel: 'Remarks', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, + }, + reservedText2: { + optionLabel: 'Reserved Text2', + isEnabled: true, isRequired: false, - optionLabel: 'Cat Date (Year)', + isHidden: false, + isDefault: false, + isRelationship: false, }, - cataloger: { + fieldNumber: { + optionLabel: 'Voucher', + isEnabled: true, + isRequired: false, + isHidden: false, isDefault: false, + isRelationship: false, + }, + accession: { + optionLabel: 'Accession #', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Cataloger', - tableName: 'Agent', + tableName: 'Accession', }, cojo: { isDefault: false, @@ -554,49 +635,49 @@ theories(getMappingLineData, [ optionLabel: 'Cojo', tableName: 'CollectionObjectGroupJoin', }, - collectingEvent: { - isDefault: false, + cataloger: { + optionLabel: 'Cataloger', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, + tableName: 'Agent', + }, + collectionObjectAttribute: { + optionLabel: 'Col Obj Attribute', + isEnabled: true, isRequired: false, - optionLabel: 'Field No: Locality', - tableName: 'CollectingEvent', + isHidden: false, + isDefault: false, + isRelationship: true, + tableName: 'CollectionObjectAttribute', }, collection: { - isDefault: false, + optionLabel: 'Collection', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Collection', tableName: 'Collection', }, collectionObjectAttachments: { - isDefault: false, - isEnabled: true, - isHidden: false, - isRelationship: true, - isRequired: false, optionLabel: 'Collection Object Attachments', - tableName: 'CollectionObjectAttachment', - }, - collectionObjectAttribute: { - isDefault: false, isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Col Obj Attribute', - tableName: 'CollectionObjectAttribute', + tableName: 'CollectionObjectAttachment', }, collectionObjectCitations: { - isDefault: false, + optionLabel: 'Collection Object Citations', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Collection Object Citations', tableName: 'CollectionObjectCitation', }, collectionObjectType: { @@ -609,73 +690,40 @@ theories(getMappingLineData, [ tableName: 'CollectionObjectType', }, determinations: { - isDefault: true, + optionLabel: 'Determinations', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: true, isRelationship: true, - isRequired: false, - optionLabel: 'Determinations', tableName: 'Determination', }, dnaSequences: { - isDefault: false, - isEnabled: true, - isHidden: false, - isRelationship: true, - isRequired: false, optionLabel: 'DNA Sequences', - tableName: 'DNASequence', - }, - fieldNumber: { - isDefault: false, isEnabled: true, - isHidden: false, - isRelationship: false, isRequired: false, - optionLabel: 'Voucher', - }, - guid: { - isDefault: false, - isEnabled: true, isHidden: false, - isRelationship: false, - isRequired: false, - optionLabel: 'GUID', - }, - leftSideRels: { isDefault: false, - isEnabled: true, - isHidden: false, isRelationship: true, - isRequired: false, - optionLabel: 'Left Side Rels', - tableName: 'CollectionRelationship', + tableName: 'DNASequence', }, modifiedByAgent: { - isDefault: false, + optionLabel: 'Edited By', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Edited By', tableName: 'Agent', }, - preparations: { - isDefault: false, + collectingEvent: { + optionLabel: 'Field No: Locality', isEnabled: true, - isHidden: false, - isRelationship: true, isRequired: false, - optionLabel: 'Preparations', - tableName: 'Preparation', - }, - projectNumber: { - isDefault: false, - isEnabled: true, isHidden: false, - isRelationship: false, - isRequired: false, - optionLabel: 'Project Number', + isDefault: false, + isRelationship: true, + tableName: 'CollectingEvent', }, relativeAges: { isDefault: false, @@ -686,297 +734,319 @@ theories(getMappingLineData, [ optionLabel: 'Relative Ages', tableName: 'RelativeAge', }, - remarks: { - isDefault: false, + leftSideRels: { + optionLabel: 'Left Side Rels', isEnabled: true, - isHidden: false, - isRelationship: false, isRequired: false, - optionLabel: 'Remarks', - }, - reservedText: { - isDefault: false, - isEnabled: true, isHidden: false, - isRelationship: false, - isRequired: false, - optionLabel: 'CT Scan', - }, - reservedText2: { isDefault: false, - isEnabled: true, - isHidden: false, - isRelationship: false, - isRequired: false, - optionLabel: 'Reserved Text2', - }, - rightSideRels: { - isDefault: false, - isEnabled: true, - isHidden: false, isRelationship: true, - isRequired: false, - optionLabel: 'Right Side Rels', tableName: 'CollectionRelationship', }, - 'timestampModified-day': { - isDefault: false, + preparations: { + optionLabel: 'Preparations', isEnabled: true, - isHidden: false, - isRelationship: false, isRequired: false, - optionLabel: 'Date Edited (Day)', - }, - 'timestampModified-fullDate': { - isDefault: false, - isEnabled: true, isHidden: false, - isRelationship: false, - isRequired: false, - optionLabel: 'Date Edited', - }, - 'timestampModified-month': { isDefault: false, - isEnabled: true, - isHidden: false, - isRelationship: false, - isRequired: false, - optionLabel: 'Date Edited (Month)', + isRelationship: true, + tableName: 'Preparation', }, - 'timestampModified-year': { - isDefault: false, + rightSideRels: { + optionLabel: 'Right Side Rels', isEnabled: true, - isHidden: false, - isRelationship: false, isRequired: false, - optionLabel: 'Date Edited (Year)', + isHidden: false, + isDefault: false, + isRelationship: true, + tableName: 'CollectionRelationship', }, voucherRelationships: { - isDefault: false, + optionLabel: 'Voucher Relationships', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Voucher Relationships', tableName: 'VoucherRelationship', }, }, - selectLabel: localized('Collection Object'), tableName: 'CollectionObject', }, { customSelectSubtype: 'simple', defaultValue: 'taxon', + selectLabel: localized('Determination'), fieldsData: { '-formatted': { - isDefault: false, - isEnabled: true, - isRelationship: false, optionLabel: '(aggregated)', tableName: 'Determination', - }, - collectionObject: { + isRelationship: false, isDefault: false, isEnabled: true, - isHidden: false, - isRelationship: true, - isRequired: false, - optionLabel: 'Collection Object', - tableName: 'CollectionObject', }, - 'determinedDate-day': { - isDefault: false, + isCurrent: { + optionLabel: 'Current', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, - isRequired: false, - optionLabel: 'Date (Day)', }, 'determinedDate-fullDate': { - isDefault: false, + optionLabel: 'Date', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, + }, + 'determinedDate-day': { + optionLabel: 'Date (Day)', + isEnabled: true, isRequired: false, - optionLabel: 'Date', + isHidden: false, + isDefault: false, + isRelationship: false, }, 'determinedDate-month': { - isDefault: false, + optionLabel: 'Date (Month)', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, - isRequired: false, - optionLabel: 'Date (Month)', }, 'determinedDate-year': { + optionLabel: 'Date (Year)', + isEnabled: true, + isRequired: false, + isHidden: false, isDefault: false, + isRelationship: false, + }, + guid: { + optionLabel: 'GUID', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, + }, + typeStatusName: { + optionLabel: 'Type Status', + isEnabled: true, isRequired: false, - optionLabel: 'Date (Year)', + isHidden: false, + isDefault: false, + isRelationship: false, }, determiner: { - isDefault: false, + optionLabel: 'Determiner', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Determiner', tableName: 'Agent', }, determiners: { - isDefault: false, + optionLabel: 'Determiners', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: true, - isRequired: false, - optionLabel: 'Determiners', tableName: 'Determiner', }, - guid: { - isDefault: false, + preferredTaxon: { + optionLabel: 'Preferred Taxon', isEnabled: true, - isHidden: false, - isRelationship: false, isRequired: false, - optionLabel: 'GUID', - }, - isCurrent: { - isDefault: false, - isEnabled: true, isHidden: false, - isRelationship: false, - isRequired: false, - optionLabel: 'Current', - }, - preferredTaxon: { isDefault: false, - isEnabled: true, - isHidden: false, isRelationship: true, - isRequired: false, - optionLabel: 'Preferred Taxon', tableName: 'Taxon', }, taxon: { - isDefault: true, + optionLabel: 'Taxon', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: true, isRelationship: true, - isRequired: false, - optionLabel: 'Taxon', tableName: 'Taxon', }, - typeStatusName: { - isDefault: false, - isEnabled: true, - isHidden: false, - isRelationship: false, - isRequired: false, - optionLabel: 'Type Status', - }, }, - selectLabel: localized('Determination'), tableName: 'Determination', }, { customSelectSubtype: 'tree', defaultValue: '$Family', + selectLabel: localized('Taxon'), fieldsData: { '$-any': { + optionLabel: '(any rank)', + isRelationship: true, isDefault: false, isEnabled: true, - isRelationship: true, - optionLabel: '(any rank)', tableName: 'Taxon', }, - $Class: { - isDefault: false, + $Kingdom: { + optionLabel: 'Kingdom', isRelationship: true, - optionLabel: 'Class', + isDefault: false, tableName: 'Taxon', }, - $Family: { - isDefault: true, + $Phylum: { + optionLabel: 'Phylum', isRelationship: true, - optionLabel: 'Family', - tableName: 'Taxon', - }, - $Genus: { isDefault: false, - isRelationship: true, - optionLabel: 'Genus', tableName: 'Taxon', }, - $Kingdom: { - isDefault: false, + $Class: { + optionLabel: 'Class', isRelationship: true, - optionLabel: 'Kingdom', + isDefault: false, tableName: 'Taxon', }, $Order: { - isDefault: false, - isRelationship: true, optionLabel: 'Order', - tableName: 'Taxon', - }, - $Phylum: { - isDefault: false, isRelationship: true, - optionLabel: 'Phylum', + isDefault: false, tableName: 'Taxon', }, - $Species: { - isDefault: false, + $Family: { + optionLabel: 'Family', isRelationship: true, - optionLabel: 'Species', + isDefault: true, tableName: 'Taxon', }, $Subfamily: { + optionLabel: 'Subfamily', + isRelationship: true, isDefault: false, + tableName: 'Taxon', + }, + $Genus: { + optionLabel: 'Genus', isRelationship: true, - optionLabel: 'Subfamily', + isDefault: false, tableName: 'Taxon', }, $Subgenus: { + optionLabel: 'Subgenus', + isRelationship: true, isDefault: false, + tableName: 'Taxon', + }, + $Species: { + optionLabel: 'Species', isRelationship: true, - optionLabel: 'Subgenus', + isDefault: false, tableName: 'Taxon', }, $Subspecies: { - isDefault: false, - isRelationship: true, optionLabel: 'Subspecies', + isRelationship: true, + isDefault: false, tableName: 'Taxon', }, }, - selectLabel: localized('Taxon'), tableName: 'Taxon', }, { customSelectSubtype: 'simple', defaultValue: 'name', + selectLabel: localized('Taxon'), fieldsData: { author: { - isDefault: false, + optionLabel: 'Author', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, - isRequired: false, - optionLabel: 'Author', }, + /* + * TODO: Needed in #6196 and not in #6216 + * commonName: { + * optionLabel: 'Common Name', + * isEnabled: true, + * isRequired: false, + * isHidden: false, + * isDefault: false, + * isRelationship: false, + * }, + */ fullName: { - isDefault: false, + optionLabel: 'Full Name', isEnabled: true, + isRequired: false, isHidden: false, + isDefault: false, isRelationship: false, - isRequired: false, - optionLabel: 'Full Name', }, + /* + * TODO: Needed in #6196 and not in #6216 + * guid: { + * optionLabel: 'GUID', + * isEnabled: true, + * isRequired: false, + * isHidden: false, + * isDefault: false, + * isRelationship: false, + * }, + * isHybrid: { + * optionLabel: 'Is Hybrid', + * isEnabled: true, + * isRequired: false, + * isHidden: false, + * isDefault: false, + * isRelationship: false, + * }, + * isAccepted: { + * optionLabel: 'Is Preferred', + * isEnabled: true, + * isRequired: false, + * isHidden: false, + * isDefault: false, + * isRelationship: false, + * }, + * name: { + * optionLabel: 'Name', + * isEnabled: true, + * isRequired: false, + * isHidden: false, + * isDefault: true, + * isRelationship: false, + * }, + * rankId: { + * optionLabel: 'Rank ID', + * isEnabled: true, + * isRequired: false, + * isHidden: false, + * isDefault: false, + * isRelationship: false, + * }, + * remarks: { + * optionLabel: 'Remarks', + * isEnabled: true, + * isRequired: false, + * isHidden: false, + * isDefault: false, + * isRelationship: false, + * }, + * source: { + * optionLabel: 'Source', + * isEnabled: true, + * isRequired: false, + * isHidden: false, + * isDefault: false, + * isRelationship: false, + * }, + */ }, - selectLabel: localized('Taxon'), tableName: 'Taxon', }, ], diff --git a/specifyweb/frontend/js_src/lib/components/WbPlanView/navigator.ts b/specifyweb/frontend/js_src/lib/components/WbPlanView/navigator.ts index 1dd5a3291a1..e77ceb04ecb 100644 --- a/specifyweb/frontend/js_src/lib/components/WbPlanView/navigator.ts +++ b/specifyweb/frontend/js_src/lib/components/WbPlanView/navigator.ts @@ -588,15 +588,15 @@ export function getMappingLineData({ if (field.isRelationship) { isIncluded &&= - spec.allowNestedToMany || parentRelationship === undefined || (!isCircularRelationship(parentRelationship, field) && - !( - (relationshipIsToMany(field) || - relationshipIsRemoteToOne(field)) && - (relationshipIsToMany(parentRelationship) || - relationshipIsRemoteToOne(parentRelationship)) - )); + (spec.allowNestedToMany || + !( + (relationshipIsToMany(field) || + relationshipIsRemoteToOne(field)) && + (relationshipIsToMany(parentRelationship) || + relationshipIsRemoteToOne(parentRelationship)) + ))); isIncluded &&= !canDoAction || diff --git a/specifyweb/frontend/js_src/lib/components/WbPlanView/navigatorSpecs.ts b/specifyweb/frontend/js_src/lib/components/WbPlanView/navigatorSpecs.ts index 86c639f5167..96fdea7a477 100644 --- a/specifyweb/frontend/js_src/lib/components/WbPlanView/navigatorSpecs.ts +++ b/specifyweb/frontend/js_src/lib/components/WbPlanView/navigatorSpecs.ts @@ -56,7 +56,7 @@ const wbPlanView: NavigatorSpec = { * Hide nested -to-many relationships as they are not * supported by the WorkBench */ - allowNestedToMany: false, + allowNestedToMany: true, ensurePermission: () => userPreferences.get('workBench', 'wbPlanView', 'showNoAccessTables') ? 'create' diff --git a/specifyweb/frontend/js_src/lib/components/WbPlanView/uploadPlanBuilder.ts b/specifyweb/frontend/js_src/lib/components/WbPlanView/uploadPlanBuilder.ts index 72ca16707f4..dde8d53188d 100644 --- a/specifyweb/frontend/js_src/lib/components/WbPlanView/uploadPlanBuilder.ts +++ b/specifyweb/frontend/js_src/lib/components/WbPlanView/uploadPlanBuilder.ts @@ -1,5 +1,5 @@ import type { IR, RA, RR } from '../../utils/types'; -import { group, removeKey, split, toLowerCase } from '../../utils/utils'; +import { group, split, toLowerCase } from '../../utils/utils'; import type { SpecifyTable } from '../DataModel/specifyTable'; import { strictGetTable } from '../DataModel/tables'; import type { Tables } from '../DataModel/types'; @@ -139,13 +139,10 @@ function toUploadTable( [ fieldName.toLowerCase(), indexMappings(lines).map(([_index, lines]) => - removeKey( - toUploadTable( - table.strictGetRelationship(fieldName).relatedTable, - lines, - mustMatchPreferences - ), - 'toMany' + toUploadTable( + table.strictGetRelationship(fieldName).relatedTable, + lines, + mustMatchPreferences ) ), ] as const diff --git a/specifyweb/frontend/js_src/lib/components/WbPlanView/uploadPlanParser.ts b/specifyweb/frontend/js_src/lib/components/WbPlanView/uploadPlanParser.ts index ebcbed09e33..bd9717f6824 100644 --- a/specifyweb/frontend/js_src/lib/components/WbPlanView/uploadPlanParser.ts +++ b/specifyweb/frontend/js_src/lib/components/WbPlanView/uploadPlanParser.ts @@ -1,4 +1,4 @@ -import type { IR, RA, RR } from '../../utils/types'; +import type { IR, PartialBy, RA, RR } from '../../utils/types'; import type { SpecifyTable } from '../DataModel/specifyTable'; import { strictGetTable } from '../DataModel/tables'; import type { Tables } from '../DataModel/types'; @@ -23,7 +23,11 @@ export type ColumnDefinition = | string | (ColumnOptions & { readonly column: string }); -export type NestedUploadTable = Omit; +/* + * NOTE: This comment was added after workbench supports nested-to-manys. + * Type is made Partial to not chock on legacy upload plans + */ +export type NestedUploadTable = PartialBy; export type UploadTable = { readonly wbcols: IR; @@ -146,23 +150,21 @@ const parseUploadTable = ( [...mappingPath, table.strictGetRelationship(relationshipName).name] ) ), - ...('toMany' in uploadPlan - ? Object.entries(uploadPlan.toMany).flatMap( - ([relationshipName, mappings]) => - Object.values(mappings).flatMap((mapping, index) => - parseUploadTable( - table.strictGetRelationship(relationshipName).relatedTable, - mapping, - makeMustMatch, - [ - ...mappingPath, - table.strictGetRelationship(relationshipName).name, - formatToManyIndex(index + 1), - ] - ) - ) + ...Object.entries(uploadPlan.toMany ?? []).flatMap( + ([relationshipName, mappings]) => + Object.values(mappings).flatMap((mapping, index) => + parseUploadTable( + table.strictGetRelationship(relationshipName).relatedTable, + mapping, + makeMustMatch, + [ + ...mappingPath, + table.strictGetRelationship(relationshipName).name, + formatToManyIndex(index + 1), + ] + ) ) - : []), + ), ]; function parseUploadTableTypes( diff --git a/specifyweb/frontend/js_src/lib/components/WorkBench/index.tsx b/specifyweb/frontend/js_src/lib/components/WorkBench/index.tsx index 7246bbd6ce5..6db77592704 100644 --- a/specifyweb/frontend/js_src/lib/components/WorkBench/index.tsx +++ b/specifyweb/frontend/js_src/lib/components/WorkBench/index.tsx @@ -21,12 +21,20 @@ export function WorkBench(): JSX.Element { const datasetId = f.parseInt(id); const [dataset, setDataset] = useDataset(datasetId); - return datasetId === undefined ? - : - dataset === undefined ? : ; + return datasetId === undefined ? ( + + ) : dataset === undefined ? ( + + ) : ( + + ); } -export function WorkBenchSafe({getSetDataset}: {readonly getSetDataset: GetSet}): JSX.Element { +export function WorkBenchSafe({ + getSetDataset, +}: { + readonly getSetDataset: GetSet; +}): JSX.Element { const [dataset, setDataset] = getSetDataset; const [treeRanksLoaded = false] = useAsyncState(fetchTreeRanks, true); @@ -50,7 +58,9 @@ export function WorkBenchSafe({getSetDataset}: {readonly getSetDataset: GetSet - ) : ; + ) : ( + + ); } const fetchTreeRanks = async (): Promise => treeRanksPromise.then(f.true); diff --git a/specifyweb/frontend/js_src/lib/tests/fixtures/uploadplan.1.json b/specifyweb/frontend/js_src/lib/tests/fixtures/uploadplan.1.json index a639bc1327d..e5684fe5584 100644 --- a/specifyweb/frontend/js_src/lib/tests/fixtures/uploadplan.1.json +++ b/specifyweb/frontend/js_src/lib/tests/fixtures/uploadplan.1.json @@ -160,7 +160,8 @@ "toMany": {} } } - } + }, + "toMany": {} }, { "wbcols": {}, @@ -179,7 +180,8 @@ "toMany": {} } } - } + }, + "toMany": {} }, { "wbcols": {}, @@ -198,7 +200,8 @@ "toMany": {} } } - } + }, + "toMany": {} }, { "wbcols": {}, @@ -217,7 +220,8 @@ "toMany": {} } } - } + }, + "toMany": {} } ] } @@ -246,7 +250,8 @@ "toMany": {} } } - } + }, + "toMany": {} } ] } @@ -276,6 +281,7 @@ "mustMatchTreeRecord": { "ranks": { "Class": { + "treeId": 1, "treeNodeCols": { "name": { "matchBehavior": "ignoreAlways", @@ -283,40 +289,39 @@ "default": null, "column": "Class" } - }, - "treeId": 1 + } }, "Family": { + "treeId": 1, "treeNodeCols": { "name": "Family" - }, - "treeId": 1 + } }, "Genus": { + "treeId": 1, "treeNodeCols": { "name": "Genus" - }, - "treeId": 1 + } }, "Subgenus": { + "treeId": 1, "treeNodeCols": { "name": "Subgenus" - }, - "treeId": 1 + } }, "Species": { + "treeId": 1, "treeNodeCols": { "name": "Species", "author": "Species Author" - }, - "treeId": 1 + } }, "Subspecies": { + "treeId": 1, "treeNodeCols": { "name": "Subspecies", "author": "Subspecies Author" - }, - "treeId": 1 + } } } } @@ -334,7 +339,8 @@ "toMany": {} } } - } + }, + "toMany": {} }, { "wbcols": { @@ -352,7 +358,8 @@ "toMany": {} } } - } + }, + "toMany": {} } ], "preparations": [ @@ -370,7 +377,8 @@ "toMany": {} } } - } + }, + "toMany": {} } ] }