From b45a031e6130908d259aac2e065d20134a23765f Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 17 Sep 2024 08:01:21 -0700 Subject: [PATCH 01/50] Add COG children picker to forms Fixes #5185 --- .../lib/components/FormCells/COJODialog.tsx | 42 +++++++++++++++++++ .../lib/components/FormCells/FormTable.tsx | 41 ++++++++++-------- .../components/Toolbar/QueryTablesEdit.tsx | 10 +++-- .../frontend/js_src/lib/localization/forms.ts | 3 ++ 4 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx new file mode 100644 index 00000000000..3efd38fc06a --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -0,0 +1,42 @@ +import React from 'react'; + +import { useBooleanState } from '../../hooks/useBooleanState'; +import { commonText } from '../../localization/common'; +import { formsText } from '../../localization/forms'; +import { localized } from '../../utils/types'; +import { DataEntry } from '../Atoms/DataEntry'; +import { tables } from '../DataModel/tables'; +import { Dialog } from '../Molecules/Dialog'; +import { TableIcon } from '../Molecules/TableIcon'; + +export function COJODialog(): JSX.Element | null { + const [isOpen, handleOpen, handleClose] = useBooleanState(); + const COJOChildrentables = [ + tables.CollectionObject, + tables.CollectionObjectGroup, + ]; + return ( + <> + + {isOpen && ( + +
+ {COJOChildrentables.map((table) => ( +
+ + {localized(table.label)} + + +
+ ))} +
+
+ )} + + ); +} diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx index e58d70ba633..9b71149ff4a 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx @@ -34,6 +34,7 @@ import { userPreferences } from '../Preferences/userPreferences'; import { SearchDialog } from '../SearchDialog'; import { AttachmentPluginSkeleton } from '../SkeletonLoaders/AttachmentPlugin'; import { relationshipIsToMany } from '../WbPlanView/mappingHelpers'; +import { COJODialog } from './COJODialog'; import { FormCell } from './index'; const cellToLabel = ( @@ -441,30 +442,34 @@ export function FormTable({ ); - const addButton = - typeof handleAddResources === 'function' && + + const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; + + const addButton = isCOJO ? ( + + ) : typeof handleAddResources === 'function' && mode !== 'view' && !disableAdding && hasTablePermission( relationship.relatedTable.name, isDependent ? 'create' : 'read' ) ? ( - { - const resource = new relationship.relatedTable.Resource(); - handleAddResources([resource]); - } - : (): void => - setState({ - type: 'SearchState', - }) - } - /> - ) : undefined; + { + const resource = new relationship.relatedTable.Resource(); + handleAddResources([resource]); + } + : (): void => + setState({ + type: 'SearchState', + }) + } + /> + ) : undefined; return dialog === false ? ( diff --git a/specifyweb/frontend/js_src/lib/components/Toolbar/QueryTablesEdit.tsx b/specifyweb/frontend/js_src/lib/components/Toolbar/QueryTablesEdit.tsx index 613975104d3..ad60e58b49a 100644 --- a/specifyweb/frontend/js_src/lib/components/Toolbar/QueryTablesEdit.tsx +++ b/specifyweb/frontend/js_src/lib/components/Toolbar/QueryTablesEdit.tsx @@ -42,10 +42,12 @@ export function QueryTablesEdit({ * TODO: Revert #5236 to unhide COType */ export const HIDDEN_GEO_TABLES = new Set([ - 'CollectionObjectType', - 'CollectionObjectGroup', - 'CollectionObjectGroupJoin', - 'CollectionObjectGroupType', + /* + * 'CollectionObjectType', + * 'CollectionObjectGroup', + * 'CollectionObjectGroupJoin', + * 'CollectionObjectGroupType', + */ ]); export function TablesListEdit({ isNoRestrictionMode, diff --git a/specifyweb/frontend/js_src/lib/localization/forms.ts b/specifyweb/frontend/js_src/lib/localization/forms.ts index 74100c1982f..1d837f7b953 100644 --- a/specifyweb/frontend/js_src/lib/localization/forms.ts +++ b/specifyweb/frontend/js_src/lib/localization/forms.ts @@ -1162,4 +1162,7 @@ export const formsText = createDictionary({ invalidTree: { 'en-us': 'Taxon does not belong to the same tree as this Object Type', }, + addCOGChildren: { + 'en-us': 'Add COG Children', + }, } as const); From 85750a793c28b786304dcbfbd2f11f6c1d707bb2 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 17 Sep 2024 08:03:31 -0700 Subject: [PATCH 02/50] Chnage key --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 3efd38fc06a..90088a36205 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -21,7 +21,7 @@ export function COJODialog(): JSX.Element | null { {isOpen && ( From b101753ac2ebffeec3bb3c9066444f7450fda799 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 17 Sep 2024 09:54:51 -0700 Subject: [PATCH 03/50] Add useEffect to create newResource --- .../lib/components/FormCells/COJODialog.tsx | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 90088a36205..d99548fd486 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -5,16 +5,49 @@ import { commonText } from '../../localization/common'; import { formsText } from '../../localization/forms'; import { localized } from '../../utils/types'; import { DataEntry } from '../Atoms/DataEntry'; +import type { AnySchema } from '../DataModel/helperTypes'; +import type { SpecifyResource } from '../DataModel/legacyTypes'; +import type { SpecifyTable } from '../DataModel/specifyTable'; import { tables } from '../DataModel/tables'; +import type { + CollectionObject, + CollectionObjectGroup, +} from '../DataModel/types'; +import { ResourceView } from '../Forms/ResourceView'; import { Dialog } from '../Molecules/Dialog'; import { TableIcon } from '../Molecules/TableIcon'; -export function COJODialog(): JSX.Element | null { +export function COJODialog({ + parentResource, +}: { + readonly parentResource: SpecifyResource | undefined; +}): JSX.Element | null { const [isOpen, handleOpen, handleClose] = useBooleanState(); const COJOChildrentables = [ tables.CollectionObject, tables.CollectionObjectGroup, ]; + const [state, setState] = React.useState<'Add' | 'Search' | undefined>( + undefined + ); + const [resource, setResource] = React.useState< + | SpecifyTable + | SpecifyTable + | undefined + >(undefined); + const [newResource, setNewResource] = React.useState< + | SpecifyResource + | SpecifyResource + | undefined + >(undefined); + + React.useEffect(() => { + if (resource !== undefined) { + const createdResource = new resource.Resource(); + setNewResource(createdResource); + setState('Add'); + } + }, [resource]); return ( <> @@ -30,13 +63,37 @@ export function COJODialog(): JSX.Element | null {
{localized(table.label)} - + { + setResource(table); + }} + />
))}
)} + {state === 'Add' && newResource !== undefined ? ( + } + onAdd={undefined} + onClose={(): void => { + setState(undefined); + handleClose(); + }} + onDeleted={undefined} + onSaved={(): void => { + parentResource?.set('cojo', newResource as never); + setState(undefined); + handleClose(); + }} + onSaving={undefined} + /> + ) : undefined} ); } From bb463de1a718ef78a5ef9c50b3dbf3610092808e Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:10:48 -0700 Subject: [PATCH 04/50] Add search dialog --- .../lib/components/FormCells/COJODialog.tsx | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index d99548fd486..54da5edab85 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -5,7 +5,6 @@ import { commonText } from '../../localization/common'; import { formsText } from '../../localization/forms'; import { localized } from '../../utils/types'; import { DataEntry } from '../Atoms/DataEntry'; -import type { AnySchema } from '../DataModel/helperTypes'; import type { SpecifyResource } from '../DataModel/legacyTypes'; import type { SpecifyTable } from '../DataModel/specifyTable'; import { tables } from '../DataModel/tables'; @@ -16,6 +15,7 @@ import type { import { ResourceView } from '../Forms/ResourceView'; import { Dialog } from '../Molecules/Dialog'; import { TableIcon } from '../Molecules/TableIcon'; +import { SearchDialog } from '../SearchDialog'; export function COJODialog({ parentResource, @@ -45,7 +45,6 @@ export function COJODialog({ if (resource !== undefined) { const createdResource = new resource.Resource(); setNewResource(createdResource); - setState('Add'); } }, [resource]); return ( @@ -65,10 +64,17 @@ export function COJODialog({ {localized(table.label)} { + setState('Add'); + setResource(table); + }} + /> + { + setState('Search'); setResource(table); }} /> - ))} @@ -94,6 +100,22 @@ export function COJODialog({ onSaving={undefined} /> ) : undefined} + {state === 'Search' && resource !== undefined ? ( + } + onClose={(): void => setState(undefined)} + onSelected={([selectedResource]): void => { + // @ts-expect-error Need to refactor this to use generics + void newResource.set('cojo', selectedResource); + setState(undefined); + handleClose(); + }} + /> + ) : undefined} ); } From ae68be1dde135a76cd407bea97d4a000453aee0c Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:01:49 -0700 Subject: [PATCH 05/50] Handle add --- .../lib/components/FormCells/COJODialog.tsx | 32 +++++++++++++++---- .../lib/components/FormCells/FormTable.tsx | 12 +++++-- .../FormCells/FormTableCollection.tsx | 1 + 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 54da5edab85..567dfa4db21 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -5,8 +5,9 @@ import { commonText } from '../../localization/common'; import { formsText } from '../../localization/forms'; import { localized } from '../../utils/types'; import { DataEntry } from '../Atoms/DataEntry'; +import type { AnySchema } from '../DataModel/helperTypes'; import type { SpecifyResource } from '../DataModel/legacyTypes'; -import type { SpecifyTable } from '../DataModel/specifyTable'; +import type { Collection, SpecifyTable } from '../DataModel/specifyTable'; import { tables } from '../DataModel/tables'; import type { CollectionObject, @@ -19,8 +20,10 @@ import { SearchDialog } from '../SearchDialog'; export function COJODialog({ parentResource, + collection, }: { readonly parentResource: SpecifyResource | undefined; + readonly collection: Collection | undefined; }): JSX.Element | null { const [isOpen, handleOpen, handleClose] = useBooleanState(); const COJOChildrentables = [ @@ -80,7 +83,9 @@ export function COJODialog({ )} - {state === 'Add' && newResource !== undefined ? ( + {state === 'Add' && + newResource !== undefined && + parentResource !== undefined ? ( { - parentResource?.set('cojo', newResource as never); + const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); + const field = + newResource.specifyTable.name === 'CollectionObject' + ? 'childco' + : 'childcog'; + newCOJO.set(field, newResource as never); + newCOJO.set('parentcog', parentResource); + collection?.add(newCOJO); setState(undefined); handleClose(); }} onSaving={undefined} /> ) : undefined} - {state === 'Search' && resource !== undefined ? ( + {state === 'Search' && + resource !== undefined && + parentResource !== undefined ? ( } onClose={(): void => setState(undefined)} onSelected={([selectedResource]): void => { - // @ts-expect-error Need to refactor this to use generics - void newResource.set('cojo', selectedResource); + const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); + const field = + selectedResource.specifyTable.name === 'CollectionObject' + ? 'childco' + : 'childcog'; + newCOJO.set(field, selectedResource as never); + newCOJO.set('parentcog', parentResource); + collection?.add(newCOJO); setState(undefined); handleClose(); }} diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx index 9b71149ff4a..a88a31eb8af 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx @@ -19,7 +19,8 @@ import { backboneFieldSeparator } from '../DataModel/helpers'; import type { AnySchema } from '../DataModel/helperTypes'; import type { SpecifyResource } from '../DataModel/legacyTypes'; import type { Relationship } from '../DataModel/specifyField'; -import type { SpecifyTable } from '../DataModel/specifyTable'; +import type { Collection, SpecifyTable } from '../DataModel/specifyTable'; +import type { CollectionObjectGroup } from '../DataModel/types'; import { FormMeta } from '../FormMeta'; import type { FormCellDefinition, SubViewSortField } from '../FormParse/cells'; import { attachmentView } from '../FormParse/webOnlyViews'; @@ -74,6 +75,7 @@ export function FormTable({ onFetchMore: handleFetchMore, isCollapsed = false, preHeaderButtons, + collection, }: { readonly relationship: Relationship; readonly isDependent: boolean; @@ -90,6 +92,7 @@ export function FormTable({ readonly onFetchMore: (() => Promise) | undefined; readonly isCollapsed: boolean | undefined; readonly preHeaderButtons?: JSX.Element; + readonly collection: Collection | undefined; }): JSX.Element { const [sortConfig, setSortConfig] = React.useState< SortConfig | undefined @@ -446,7 +449,12 @@ export function FormTable({ const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; const addButton = isCOJO ? ( - + + } + /> ) : typeof handleAddResources === 'function' && mode !== 'view' && !disableAdding && diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/FormTableCollection.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/FormTableCollection.tsx index ecff42dcdf8..2b9fb8c19e7 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/FormTableCollection.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/FormTableCollection.tsx @@ -68,6 +68,7 @@ export function FormTableCollection({ }} onFetchMore={collection.isComplete() ? undefined : handleFetchMore} {...props} + collection={collection} /> ); } From f3bbf598d685942c50d2cd25d9b1fe599325edb6 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:06:28 -0700 Subject: [PATCH 06/50] Typo --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 567dfa4db21..5f3bf49b4d9 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -26,7 +26,7 @@ export function COJODialog({ readonly collection: Collection | undefined; }): JSX.Element | null { const [isOpen, handleOpen, handleClose] = useBooleanState(); - const COJOChildrentables = [ + const COJOChildrenTables = [ tables.CollectionObject, tables.CollectionObjectGroup, ]; @@ -61,7 +61,7 @@ export function COJODialog({ onClose={handleClose} >
- {COJOChildrentables.map((table) => ( + {COJOChildrenTables.map((table) => (
{localized(table.label)} From 51e0d44fe8d2f3abb7d1795fd99618bbcebaaeaf Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:08:35 -0700 Subject: [PATCH 07/50] Reset resource --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 5f3bf49b4d9..8f7c1d6bd9b 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -107,6 +107,7 @@ export function COJODialog({ newCOJO.set('parentcog', parentResource); collection?.add(newCOJO); setState(undefined); + setResource(undefined); handleClose(); }} onSaving={undefined} From c94f5595064e1b966d29a1ef9ad3861a89922bcd Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:15:15 -0700 Subject: [PATCH 08/50] Unhide geo tables --- .../js_src/lib/components/SchemaConfig/Fields.tsx | 10 +--------- .../SchemaConfig/TableUniquenessRules.tsx | 4 +--- .../js_src/lib/components/SchemaConfig/Tables.tsx | 3 --- .../lib/components/Toolbar/QueryTablesEdit.tsx | 15 +-------------- .../lib/components/WbPlanView/LineComponents.tsx | 3 +-- 5 files changed, 4 insertions(+), 31 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/SchemaConfig/Fields.tsx b/specifyweb/frontend/js_src/lib/components/SchemaConfig/Fields.tsx index bbe118b1884..af860fcb76f 100644 --- a/specifyweb/frontend/js_src/lib/components/SchemaConfig/Fields.tsx +++ b/specifyweb/frontend/js_src/lib/components/SchemaConfig/Fields.tsx @@ -66,15 +66,7 @@ export function SchemaConfigFields({ {relationships.length > 0 && ( - name !== 'collectionObjectType' - ) - : relationships - } - /> + )} diff --git a/specifyweb/frontend/js_src/lib/components/SchemaConfig/TableUniquenessRules.tsx b/specifyweb/frontend/js_src/lib/components/SchemaConfig/TableUniquenessRules.tsx index b2334201c4e..8b6d783d5ee 100644 --- a/specifyweb/frontend/js_src/lib/components/SchemaConfig/TableUniquenessRules.tsx +++ b/specifyweb/frontend/js_src/lib/components/SchemaConfig/TableUniquenessRules.tsx @@ -71,9 +71,7 @@ export function TableUniquenessRules(): JSX.Element { (relationship) => (['many-to-one', 'one-to-one'] as RA).includes( relationship.type - ) && - !relationship.isVirtual && - relationship.name !== 'collectionObjectType' + ) && !relationship.isVirtual ), [table] ); diff --git a/specifyweb/frontend/js_src/lib/components/SchemaConfig/Tables.tsx b/specifyweb/frontend/js_src/lib/components/SchemaConfig/Tables.tsx index 276956a0286..1edf5436416 100644 --- a/specifyweb/frontend/js_src/lib/components/SchemaConfig/Tables.tsx +++ b/specifyweb/frontend/js_src/lib/components/SchemaConfig/Tables.tsx @@ -21,7 +21,6 @@ import { Dialog } from '../Molecules/Dialog'; import { TableIcon } from '../Molecules/TableIcon'; import { hasTablePermission } from '../Permissions/helpers'; import { formatUrl } from '../Router/queryString'; -import { HIDDEN_GEO_TABLES } from '../Toolbar/QueryTablesEdit'; export function SchemaConfigTables(): JSX.Element { const { language = '' } = useParams(); @@ -127,8 +126,6 @@ export function TableList({ () => Object.values(genericTables) .filter((table) => filter(showHiddenTables, table)) - // TODO: temp fix, remove this, use to hide geo tables for COG until 9.8 release - .filter((table) => !HIDDEN_GEO_TABLES.has(table.name)) .sort(sortFunction(({ name }) => name)), [filter, showHiddenTables] ); diff --git a/specifyweb/frontend/js_src/lib/components/Toolbar/QueryTablesEdit.tsx b/specifyweb/frontend/js_src/lib/components/Toolbar/QueryTablesEdit.tsx index ad60e58b49a..5e07f49b1cc 100644 --- a/specifyweb/frontend/js_src/lib/components/Toolbar/QueryTablesEdit.tsx +++ b/specifyweb/frontend/js_src/lib/components/Toolbar/QueryTablesEdit.tsx @@ -37,18 +37,7 @@ export function QueryTablesEdit({ /> ); } -/* - * TODO: temp fix, remove this, use to hide geo tables for COG until 9.8 release - * TODO: Revert #5236 to unhide COType - */ -export const HIDDEN_GEO_TABLES = new Set([ - /* - * 'CollectionObjectType', - * 'CollectionObjectGroup', - * 'CollectionObjectGroupJoin', - * 'CollectionObjectGroupType', - */ -]); + export function TablesListEdit({ isNoRestrictionMode, defaultTables, @@ -69,8 +58,6 @@ export function TablesListEdit({ .filter((table) => tablesFilter(isNoRestrictionMode, false, true, table, selectedValues) ) - // TODO: temp fix, remove this, use to hide geo tables for COG until 9.8 release - .filter((table) => !HIDDEN_GEO_TABLES.has(table.name)) .map(({ name, label }) => ({ name, label })); const handleChanged = (items: RA): void => diff --git a/specifyweb/frontend/js_src/lib/components/WbPlanView/LineComponents.tsx b/specifyweb/frontend/js_src/lib/components/WbPlanView/LineComponents.tsx index 433a4761b77..d4c7648c1e0 100644 --- a/specifyweb/frontend/js_src/lib/components/WbPlanView/LineComponents.tsx +++ b/specifyweb/frontend/js_src/lib/components/WbPlanView/LineComponents.tsx @@ -227,8 +227,7 @@ export function MappingElement({ fieldsData, ...props }: MappingElementProps): JSX.Element { - const { collectionObjectType, ...rest } = fieldsData; - const fieldGroups = Object.entries(rest).reduce< + const fieldGroups = Object.entries(fieldsData).reduce< R> >((fieldGroups, [fieldName, fieldData]) => { const groupName = getFieldGroupName( From d2e72220a6d97c3dde005a0dcf05695f3d33a54c Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:08:23 -0700 Subject: [PATCH 09/50] Remove unused localization --- specifyweb/frontend/js_src/lib/localization/forms.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/localization/forms.ts b/specifyweb/frontend/js_src/lib/localization/forms.ts index 1d837f7b953..b9382efdf03 100644 --- a/specifyweb/frontend/js_src/lib/localization/forms.ts +++ b/specifyweb/frontend/js_src/lib/localization/forms.ts @@ -1159,9 +1159,6 @@ export const formsText = createDictionary({ 'ru-ru': 'Номер по каталогу Числовой', 'uk-ua': 'Каталожний номер Числовий', }, - invalidTree: { - 'en-us': 'Taxon does not belong to the same tree as this Object Type', - }, addCOGChildren: { 'en-us': 'Add COG Children', }, From 1762ce330a36660688ab14bed7651304f0a06fa2 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:50:44 -0700 Subject: [PATCH 10/50] Add cojo dialog to subview --- .../FormSliders/IntegratedRecordSelector.tsx | 67 +++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx b/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx index 36e62af0487..0d0a573a626 100644 --- a/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx @@ -17,6 +17,8 @@ import type { import type { SpecifyResource } from '../DataModel/legacyTypes'; import { useAllSaveBlockers } from '../DataModel/saveBlockers'; import type { Collection, SpecifyTable } from '../DataModel/specifyTable'; +import type { CollectionObjectGroup } from '../DataModel/types'; +import { COJODialog } from '../FormCells/COJODialog'; import { FormTableCollection } from '../FormCells/FormTableCollection'; import type { FormType } from '../FormParse'; import type { SubViewSortField } from '../FormParse/cells'; @@ -128,6 +130,8 @@ export function IntegratedRecordSelector({ const isAttachmentTable = collection.table.specifyTable.name.includes('Attachment'); + const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; + return ( 0) - } - onClick={(): void => { - const resource = - new collection.table.specifyTable.Resource(); - - if ( - isDependent || - viewName === relationship.relatedTable.view - ) { - focusFirstField(); - handleAdd([resource]); - return; + isCOJO ? ( + + } + /> + ) : ( + 0) } + onClick={(): void => { + const resource = + new collection.table.specifyTable.Resource(); - if (state.type === 'AddResourceState') - setState({ type: 'MainState' }); - else - setState({ - type: 'AddResourceState', - resource, - handleAdd, - }); - }} - /> + if ( + isDependent || + viewName === relationship.relatedTable.view + ) { + focusFirstField(); + handleAdd([resource]); + return; + } + + if (state.type === 'AddResourceState') + setState({ type: 'MainState' }); + else + setState({ + type: 'AddResourceState', + resource, + handleAdd, + }); + }} + /> + ) ) : undefined} {hasTablePermission( relationship.relatedTable.name, From 487949b3bab20ce35438daee5a49757d5e045430 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:38:13 +0000 Subject: [PATCH 11/50] Lint code with ESLint and Prettier Triggered by 33a95ddfbb42d9c2c162296829207a198c12a6a7 on branch refs/heads/issue-5185 --- .../frontend/js_src/lib/components/DataModel/collection.ts | 2 +- .../frontend/js_src/lib/components/DataModel/specifyTable.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/collection.ts b/specifyweb/frontend/js_src/lib/components/DataModel/collection.ts index 0c5b516245d..06010a7fbe3 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/collection.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/collection.ts @@ -10,7 +10,7 @@ import type { } from './helperTypes'; import { parseResourceUrl } from './resource'; import { serializeResource } from './serializers'; -import { Collection } from './specifyTable'; +import type { Collection } from './specifyTable'; import { genericTables, tables } from './tables'; import type { Tables } from './types'; diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/specifyTable.ts b/specifyweb/frontend/js_src/lib/components/DataModel/specifyTable.ts index 4995661d1a6..a10d21a6c99 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/specifyTable.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/specifyTable.ts @@ -14,7 +14,7 @@ import { error } from '../Errors/assert'; import { attachmentView } from '../FormParse/webOnlyViews'; import { parentTableRelationship } from '../Forms/parentTables'; import { relationshipIsToMany } from '../WbPlanView/mappingHelpers'; -import { CollectionFetchFilters } from './collection'; +import type { CollectionFetchFilters } from './collection'; import { DependentCollection, IndependentCollection, From 3a6805c8329aed4963c7063300a21f31551ffb2d Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 8 Oct 2024 09:30:00 -0700 Subject: [PATCH 12/50] Check totalCount --- .../lib/components/DataModel/__tests__/collectionApi.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/__tests__/collectionApi.test.ts b/specifyweb/frontend/js_src/lib/components/DataModel/__tests__/collectionApi.test.ts index 42735c60009..75a7bbfa96a 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/__tests__/collectionApi.test.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/__tests__/collectionApi.test.ts @@ -162,7 +162,8 @@ describe('Independent Collection', () => { ); await collection.fetch(); - expect(collection).toHaveLength(collection._totalCount); + const totalCount = collection._totalCount ?? 0; + expect(collection).toHaveLength(totalCount); }); test('specified offset', async () => { From a5f0425b7cc6560dd2fbbf7e11c7c9b7ea4c3759 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:38:55 -0700 Subject: [PATCH 13/50] Change child field --- .../js_src/lib/components/FormCells/COJODialog.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 8f7c1d6bd9b..4ba91d82cc1 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -101,10 +101,10 @@ export function COJODialog({ const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); const field = newResource.specifyTable.name === 'CollectionObject' - ? 'childco' - : 'childcog'; + ? 'childCo' + : 'childCog'; newCOJO.set(field, newResource as never); - newCOJO.set('parentcog', parentResource); + newCOJO.set('parentCog', parentResource as never); collection?.add(newCOJO); setState(undefined); setResource(undefined); @@ -127,10 +127,10 @@ export function COJODialog({ const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); const field = selectedResource.specifyTable.name === 'CollectionObject' - ? 'childco' - : 'childcog'; + ? 'childCo' + : 'childCog'; newCOJO.set(field, selectedResource as never); - newCOJO.set('parentcog', parentResource); + newCOJO.set('parentCog', parentResource as never); collection?.add(newCOJO); setState(undefined); handleClose(); From 5fe79564c2f9704623965a1bc96e0ce02b2f4e70 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:42:04 -0700 Subject: [PATCH 14/50] Research and tries --- .../lib/components/DataModel/resourceApi.ts | 1 + .../lib/components/FormCells/COJODialog.tsx | 23 ++++++++- .../lib/components/FormCells/FormTable.tsx | 51 ++++++++++--------- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/resourceApi.ts b/specifyweb/frontend/js_src/lib/components/DataModel/resourceApi.ts index f115ebfa3db..e9942335f86 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/resourceApi.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/resourceApi.ts @@ -64,6 +64,7 @@ function eventHandlerForToOne(related, field) { function eventHandlerForToMany(_related, field) { return function (event) { + console.log('eventHandlerForToMany', field); const args = _.toArray(arguments); switch (event) { case 'changing': { diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 4ba91d82cc1..7f5bac3e601 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { useBooleanState } from '../../hooks/useBooleanState'; import { commonText } from '../../localization/common'; import { formsText } from '../../localization/forms'; +import type { RA } from '../../utils/types'; import { localized } from '../../utils/types'; import { DataEntry } from '../Atoms/DataEntry'; import type { AnySchema } from '../DataModel/helperTypes'; @@ -103,9 +104,27 @@ export function COJODialog({ newResource.specifyTable.name === 'CollectionObject' ? 'childCo' : 'childCog'; - newCOJO.set(field, newResource as never); - newCOJO.set('parentCog', parentResource as never); + // NewResource.set('cojo', newCOJO); + void newResource.save(); + const newResourceUrl = newResource.url(); + newCOJO.set(field, newResourceUrl as never); + /* + * Might not need to set the parent cog here, can do it with business rules on the main COG form when saving that + * NewCOJO.set('parentCog', parentResource as never); ==> this creates the infinite loop + */ + /* + * Const field = + * newResource.specifyTable.name === 'CollectionObject' + * ? 'childCo' + * : 'childCog'; + * newCOJO.set(field, newResource as never); + * newCOJO.set('parentCog', parentResource as never); + */ collection?.add(newCOJO); + /* + * HandleAdd([newCOJO]); + * Collection?.add(newCOJO); + */ setState(undefined); setResource(undefined); handleClose(); diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx index c9610c547c5..0102817ca2a 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx @@ -456,31 +456,32 @@ export function FormTable({ const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; - const addButtons = isCOJO ? ( - - } - /> - ) : typeof handleAddResources === 'function' && - mode !== 'view' && - !disableAdding ? ( - <> - {!isDependent && - hasTablePermission(relationship.relatedTable.name, 'read') ? ( - - ) : undefined} - {hasTablePermission(relationship.relatedTable.name, 'create') ? ( - { - const resource = new relationship.relatedTable.Resource(); - handleAddResources([resource]); - }} - /> - ) : undefined} - - ) : undefined; + const addButtons = + isCOJO && typeof handleAddResources === 'function' ? ( + + } + /> + ) : typeof handleAddResources === 'function' && + mode !== 'view' && + !disableAdding ? ( + <> + {!isDependent && + hasTablePermission(relationship.relatedTable.name, 'read') ? ( + + ) : undefined} + {hasTablePermission(relationship.relatedTable.name, 'create') ? ( + { + const resource = new relationship.relatedTable.Resource(); + handleAddResources([resource]); + }} + /> + ) : undefined} + + ) : undefined; return dialog === false ? ( From c60941f8cae84c9ea29e2dc96226eb725444c17e Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 15 Oct 2024 13:25:16 -0700 Subject: [PATCH 15/50] Add parentUrl --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 7f5bac3e601..6dd7a98ce1c 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -107,7 +107,9 @@ export function COJODialog({ // NewResource.set('cojo', newCOJO); void newResource.save(); const newResourceUrl = newResource.url(); + const parentResourceUrl = parentResource.url(); newCOJO.set(field, newResourceUrl as never); + newCOJO.set('parentCog', parentResourceUrl as never); /* * Might not need to set the parent cog here, can do it with business rules on the main COG form when saving that * NewCOJO.set('parentCog', parentResource as never); ==> this creates the infinite loop From 6c93b08f919bd3d458afb6178783648de66c335d Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 16 Oct 2024 09:50:47 -0700 Subject: [PATCH 16/50] Handle mutliple COs added at same time --- .../lib/components/FormCells/COJODialog.tsx | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 6dd7a98ce1c..08556b1bf25 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -135,25 +135,34 @@ export function COJODialog({ /> ) : undefined} {state === 'Search' && - resource !== undefined && + newResource !== undefined && parentResource !== undefined ? ( } onClose={(): void => setState(undefined)} - onSelected={([selectedResource]): void => { - const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); - const field = - selectedResource.specifyTable.name === 'CollectionObject' - ? 'childCo' - : 'childCog'; - newCOJO.set(field, selectedResource as never); - newCOJO.set('parentCog', parentResource as never); - collection?.add(newCOJO); + onSelected={(selectedResources): void => { + selectedResources.forEach((selectedResource) => { + const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); + const field = + selectedResource.specifyTable.name === 'CollectionObject' + ? 'childCo' + : 'childCog'; + + const selectedResourceUrl = selectedResource.url(); + const parentResourceUrl = parentResource.url(); + + newCOJO.set(field, selectedResourceUrl as never); + newCOJO.set('parentCog', parentResourceUrl as never); + + collection?.add(newCOJO); + }); + setState(undefined); + setResource(undefined); handleClose(); }} /> From 3a274cf518eeafa8b0426070745e2bd65beafc5a Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 16 Oct 2024 09:53:45 -0700 Subject: [PATCH 17/50] Remove some comments --- .../lib/components/FormCells/COJODialog.tsx | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 08556b1bf25..7370ff5d9ab 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -104,29 +104,13 @@ export function COJODialog({ newResource.specifyTable.name === 'CollectionObject' ? 'childCo' : 'childCog'; - // NewResource.set('cojo', newCOJO); + // NewResource.set('cojo', newCOJO); Do this in bus rule when saving main COG? void newResource.save(); const newResourceUrl = newResource.url(); const parentResourceUrl = parentResource.url(); newCOJO.set(field, newResourceUrl as never); newCOJO.set('parentCog', parentResourceUrl as never); - /* - * Might not need to set the parent cog here, can do it with business rules on the main COG form when saving that - * NewCOJO.set('parentCog', parentResource as never); ==> this creates the infinite loop - */ - /* - * Const field = - * newResource.specifyTable.name === 'CollectionObject' - * ? 'childCo' - * : 'childCog'; - * newCOJO.set(field, newResource as never); - * newCOJO.set('parentCog', parentResource as never); - */ collection?.add(newCOJO); - /* - * HandleAdd([newCOJO]); - * Collection?.add(newCOJO); - */ setState(undefined); setResource(undefined); handleClose(); From f9d1303bdc09f70a607b0cde86394310cd306b41 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:21:50 -0700 Subject: [PATCH 18/50] Remove duplication --- .../lib/components/FormCells/COJODialog.tsx | 76 ++++++++++--------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 7370ff5d9ab..b7177551d1d 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -51,6 +51,42 @@ export function COJODialog({ setNewResource(createdResource); } }, [resource]); + + const handleCOJOCreation = ( + selectedResource?: SpecifyResource + ): void => { + // NewResource.set('cojo', newCOJO); Do this in bus rule when saving main COG? + if (parentResource === undefined) return; + + const resourceToUse = selectedResource ?? newResource; + + if (resourceToUse === undefined) return; + + if (newResource) { + void newResource.save(); + } + + const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); + const field = + resourceToUse.specifyTable.name === 'CollectionObject' + ? 'childCo' + : 'childCog'; + + const resourceUrl = resourceToUse.url(); + const parentResourceUrl = parentResource.url(); + + newCOJO.set(field, resourceUrl as never); + newCOJO.set('parentCog', parentResourceUrl as never); + + collection?.add(newCOJO); + }; + + const handleStates = (): void => { + setState(undefined); + setResource(undefined); + handleClose(); + }; + return ( <> @@ -99,28 +135,13 @@ export function COJODialog({ }} onDeleted={undefined} onSaved={(): void => { - const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); - const field = - newResource.specifyTable.name === 'CollectionObject' - ? 'childCo' - : 'childCog'; - // NewResource.set('cojo', newCOJO); Do this in bus rule when saving main COG? - void newResource.save(); - const newResourceUrl = newResource.url(); - const parentResourceUrl = parentResource.url(); - newCOJO.set(field, newResourceUrl as never); - newCOJO.set('parentCog', parentResourceUrl as never); - collection?.add(newCOJO); - setState(undefined); - setResource(undefined); - handleClose(); + handleCOJOCreation(); + handleStates(); }} onSaving={undefined} /> ) : undefined} - {state === 'Search' && - newResource !== undefined && - parentResource !== undefined ? ( + {state === 'Search' && parentResource !== undefined ? ( setState(undefined)} onSelected={(selectedResources): void => { selectedResources.forEach((selectedResource) => { - const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); - const field = - selectedResource.specifyTable.name === 'CollectionObject' - ? 'childCo' - : 'childCog'; - - const selectedResourceUrl = selectedResource.url(); - const parentResourceUrl = parentResource.url(); - - newCOJO.set(field, selectedResourceUrl as never); - newCOJO.set('parentCog', parentResourceUrl as never); - - collection?.add(newCOJO); + handleCOJOCreation(selectedResource); }); - - setState(undefined); - setResource(undefined); - handleClose(); + handleStates(); }} /> ) : undefined} From 6300e573772caaad5f6817a38062f4249c4d8ab9 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:23:09 -0700 Subject: [PATCH 19/50] Remove log --- .../frontend/js_src/lib/components/DataModel/resourceApi.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/resourceApi.ts b/specifyweb/frontend/js_src/lib/components/DataModel/resourceApi.ts index e9942335f86..f115ebfa3db 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/resourceApi.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/resourceApi.ts @@ -64,7 +64,6 @@ function eventHandlerForToOne(related, field) { function eventHandlerForToMany(_related, field) { return function (event) { - console.log('eventHandlerForToMany', field); const args = _.toArray(arguments); switch (event) { case 'changing': { From 656518e05698ce024fef6e0d7c7050cd72b5262d Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:25:29 -0700 Subject: [PATCH 20/50] Remove import --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index b7177551d1d..bafb579c068 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -3,7 +3,6 @@ import React from 'react'; import { useBooleanState } from '../../hooks/useBooleanState'; import { commonText } from '../../localization/common'; import { formsText } from '../../localization/forms'; -import type { RA } from '../../utils/types'; import { localized } from '../../utils/types'; import { DataEntry } from '../Atoms/DataEntry'; import type { AnySchema } from '../DataModel/helperTypes'; @@ -47,7 +46,9 @@ export function COJODialog({ React.useEffect(() => { if (resource !== undefined) { - const createdResource = new resource.Resource(); + const createdResource = new resource.Resource() as + | SpecifyResource + | SpecifyResource; setNewResource(createdResource); } }, [resource]); From f41106955d6bbd321b147074daa31a85c764186f Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:39:48 -0700 Subject: [PATCH 21/50] Set cojo on parent --- .../lib/components/DataModel/businessRuleDefs.ts | 1 - .../js_src/lib/components/FormCells/COJODialog.tsx | 10 ++++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/businessRuleDefs.ts b/specifyweb/frontend/js_src/lib/components/DataModel/businessRuleDefs.ts index 328c12df255..48b74ae9bdc 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/businessRuleDefs.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/businessRuleDefs.ts @@ -193,7 +193,6 @@ export const businessRuleDefs: MappedBusinessRuleDefs = { }, }, }, - Determination: { fieldChecks: { taxon: async ( diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index bafb579c068..aa85785b9ae 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { useBooleanState } from '../../hooks/useBooleanState'; import { commonText } from '../../localization/common'; import { formsText } from '../../localization/forms'; +import type { RA } from '../../utils/types'; import { localized } from '../../utils/types'; import { DataEntry } from '../Atoms/DataEntry'; import type { AnySchema } from '../DataModel/helperTypes'; @@ -12,6 +13,7 @@ import { tables } from '../DataModel/tables'; import type { CollectionObject, CollectionObjectGroup, + CollectionObjectGroupJoin, } from '../DataModel/types'; import { ResourceView } from '../Forms/ResourceView'; import { Dialog } from '../Molecules/Dialog'; @@ -80,6 +82,14 @@ export function COJODialog({ newCOJO.set('parentCog', parentResourceUrl as never); collection?.add(newCOJO); + + /* + * ParentResource.set('cojo', [newCOJO] as RA< + * SpecifyResource + * >); + */ + const parentResourceCojo = parentResource.getDependentResource('cojo'); + if (typeof parentResourceCojo === 'object') parentResourceCojo.add(newCOJO); }; const handleStates = (): void => { From 5add530647b19660f0cae07942468591b9fad08c Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:00:18 -0700 Subject: [PATCH 22/50] Remove code --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index aa85785b9ae..01a9ca8366b 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -83,11 +83,6 @@ export function COJODialog({ collection?.add(newCOJO); - /* - * ParentResource.set('cojo', [newCOJO] as RA< - * SpecifyResource - * >); - */ const parentResourceCojo = parentResource.getDependentResource('cojo'); if (typeof parentResourceCojo === 'object') parentResourceCojo.add(newCOJO); }; From 6c0174663ae70403dd9b4ac95f00f0a13348bba3 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Thu, 17 Oct 2024 07:51:59 -0700 Subject: [PATCH 23/50] Remove import --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 01a9ca8366b..2562871d206 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -3,7 +3,6 @@ import React from 'react'; import { useBooleanState } from '../../hooks/useBooleanState'; import { commonText } from '../../localization/common'; import { formsText } from '../../localization/forms'; -import type { RA } from '../../utils/types'; import { localized } from '../../utils/types'; import { DataEntry } from '../Atoms/DataEntry'; import type { AnySchema } from '../DataModel/helperTypes'; @@ -13,7 +12,6 @@ import { tables } from '../DataModel/tables'; import type { CollectionObject, CollectionObjectGroup, - CollectionObjectGroupJoin, } from '../DataModel/types'; import { ResourceView } from '../Forms/ResourceView'; import { Dialog } from '../Molecules/Dialog'; From 929060262333cd72dba07591a20d74a79e032404 Mon Sep 17 00:00:00 2001 From: melton-jason Date: Thu, 17 Oct 2024 11:49:40 -0500 Subject: [PATCH 24/50] Datamodel improvements --- .../js_src/lib/components/DataModel/types.ts | 210 +++++++++--------- specifyweb/specify/api.py | 2 +- specifyweb/specify/datamodel.py | 5 +- specifyweb/specify/models.py | 2 +- 4 files changed, 114 insertions(+), 105 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/types.ts b/specifyweb/frontend/js_src/lib/components/DataModel/types.ts index abbf2f321ec..93c0e575828 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/types.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/types.ts @@ -229,24 +229,33 @@ export type Tables = { readonly CollectionObjectGroup: CollectionObjectGroup; readonly CollectionObjectGroupJoin: CollectionObjectGroupJoin; readonly CollectionObjectGroupType: CollectionObjectGroupType; + readonly AbsoluteAge: AbsoluteAge; + readonly RelativeAge: RelativeAge; + readonly AbsoluteAgeAttachment: AbsoluteAgeAttachment; + readonly RelativeAgeAttachment: RelativeAgeAttachment; + readonly AbsoluteAgeCitation: AbsoluteAgeCitation; + readonly RelativeAgeCitation: RelativeAgeCitation; + readonly TectonicUnitTreeDef: TectonicUnitTreeDef; + readonly TectonicUnitTreeDefItem: TectonicUnitTreeDefItem; + readonly TectonicUnit: TectonicUnit; }; export type Accession = { readonly tableName: 'Accession'; readonly fields: { - readonly accessionCondition: string | null; readonly accessionNumber: string; + readonly accessionCondition: string | null; + readonly dateAccessioned: string | null; readonly actualTotalCountAmt: number | null; readonly collectionObjectCount: number | null; - readonly dateAccessioned: string | null; readonly dateAcknowledged: string | null; - readonly dateReceived: string | null; + readonly remarks: string | null; readonly integer1: number | null; readonly integer2: number | null; readonly integer3: number | null; readonly number1: number | null; readonly number2: number | null; readonly preparationCount: number | null; - readonly remarks: string | null; + readonly dateReceived: string | null; readonly status: string | null; readonly text1: string | null; readonly text2: string | null; @@ -452,10 +461,10 @@ export type Agent = { readonly initials: string | null; readonly integer1: number | null; readonly integer2: number | null; - readonly interests: string | null; readonly jobTitle: string | null; readonly lastName: string | null; readonly middleInitial: string | null; + readonly interests: string | null; readonly remarks: string | null; readonly suffix: string | null; readonly text1: string | null; @@ -488,8 +497,8 @@ export type Agent = { readonly agentAttachments: RA; readonly agentGeographies: RA; readonly agentSpecialties: RA; - readonly groups: RA; readonly identifiers: RA; + readonly groups: RA; readonly variants: RA; }; readonly toManyIndependent: { @@ -920,13 +929,13 @@ export type BorrowMaterial = { readonly tableName: 'BorrowMaterial'; readonly fields: { readonly collectionMemberId: number; - readonly description: string | null; readonly inComments: string | null; readonly materialNumber: string; readonly outComments: string | null; readonly quantity: number | null; readonly quantityResolved: number | null; readonly quantityReturned: number | null; + readonly description: string | null; readonly text1: string | null; readonly text2: string | null; readonly timestampCreated: string; @@ -973,12 +982,12 @@ export type CollectingEvent = { readonly endDatePrecision: number | null; readonly endDateVerbatim: string | null; readonly endTime: number | null; + readonly stationFieldNumber: string | null; + readonly method: string | null; readonly guid: string | null; readonly integer1: number | null; readonly integer2: number | null; readonly remarks: string | null; - readonly method: string | null; - readonly stationFieldNumber: string | null; readonly reservedInteger3: number | null; readonly reservedInteger4: number | null; readonly reservedText1: string | null; @@ -1070,6 +1079,10 @@ export type CollectingEventAttr = { export type CollectingEventAttribute = { readonly tableName: 'CollectingEventAttribute'; readonly fields: { + readonly text8: string | null; + readonly text5: string | null; + readonly text4: string | null; + readonly text9: string | null; readonly integer1: number | null; readonly integer10: number | null; readonly integer2: number | null; @@ -1080,11 +1093,11 @@ export type CollectingEventAttribute = { readonly integer7: number | null; readonly integer8: number | null; readonly integer9: number | null; + readonly number12: number | null; + readonly number13: number | null; readonly number1: number | null; readonly number10: number | null; readonly number11: number | null; - readonly number12: number | null; - readonly number13: number | null; readonly number2: number | null; readonly number3: number | null; readonly number4: number | null; @@ -1094,26 +1107,22 @@ export type CollectingEventAttribute = { readonly number8: number | null; readonly number9: number | null; readonly remarks: string | null; + readonly text6: string | null; readonly text1: string | null; readonly text10: string | null; readonly text11: string | null; - readonly text12: string | null; readonly text13: string | null; readonly text14: string | null; readonly text15: string | null; readonly text16: string | null; readonly text17: string | null; readonly text2: string | null; - readonly text3: string | null; - readonly text4: string | null; - readonly text5: string | null; - readonly text6: string | null; readonly text7: string | null; - readonly text8: string | null; - readonly text9: string | null; readonly timestampCreated: string; readonly timestampModified: string | null; + readonly text12: string | null; readonly version: number | null; + readonly text3: string | null; readonly yesNo1: boolean | null; readonly yesNo2: boolean | null; readonly yesNo3: boolean | null; @@ -1154,6 +1163,7 @@ export type CollectingTrip = { readonly tableName: 'CollectingTrip'; readonly fields: { readonly cruise: string | null; + readonly text2: string | null; readonly date1: string | null; readonly date1Precision: number | null; readonly date2: string | null; @@ -1171,8 +1181,6 @@ export type CollectingTrip = { readonly startDatePrecision: number | null; readonly startDateVerbatim: string | null; readonly startTime: number | null; - readonly text1: string | null; - readonly text2: string | null; readonly text3: string | null; readonly text4: string | null; readonly text5: string | null; @@ -1184,6 +1192,7 @@ export type CollectingTrip = { readonly timestampModified: string | null; readonly collectingTripName: string | null; readonly version: number | null; + readonly text1: string | null; readonly vessel: string | null; readonly yesNo1: boolean | null; readonly yesNo2: boolean | null; @@ -1359,51 +1368,51 @@ export type Collection = { export type CollectionObject = { readonly tableName: 'CollectionObject'; readonly fields: { - readonly modifier: string | null; - readonly catalogedDate: string | null; - readonly projectNumber: string | null; readonly actualTotalCountAmt: number | null; readonly age: number | null; readonly availability: string | null; + readonly catalogNumber: string | null; + readonly catalogedDate: string | null; readonly catalogedDatePrecision: number | null; readonly catalogedDateVerbatim: string | null; readonly collectionMemberId: number; readonly countAmt: number | null; + readonly reservedText: string | null; + readonly timestampModified: string | null; readonly date1: string | null; readonly date1Precision: number | null; readonly deaccessioned: boolean | null; - readonly timestampModified: string | null; readonly embargoReason: string | null; readonly embargoReleaseDate: string | null; readonly embargoReleaseDatePrecision: number | null; readonly embargoStartDate: string | null; readonly embargoStartDatePrecision: number | null; - readonly yesNo2: boolean | null; - readonly fieldNumber: string | null; readonly guid: string | null; - readonly text2: string | null; readonly integer1: number | null; readonly integer2: number | null; + readonly text2: string | null; readonly inventoryDate: string | null; readonly inventoryDatePrecision: number | null; - readonly description: string | null; + readonly isMemberOfCOG: boolean | null; + readonly modifier: string | null; + readonly name: string | null; readonly notifications: string | null; readonly numberOfDuplicates: number | null; + readonly number1: number | null; + readonly number2: number | null; readonly objectCondition: string | null; readonly ocr: string | null; - readonly name: string | null; readonly altCatalogNumber: string | null; - readonly text1: string | null; - readonly yesNo1: boolean | null; + readonly projectNumber: string | null; readonly remarks: string | null; readonly reservedInteger3: number | null; readonly reservedInteger4: number | null; - readonly reservedText: string | null; readonly reservedText2: string | null; readonly reservedText3: string | null; readonly restrictions: string | null; readonly sgrStatus: number | null; - readonly catalogNumber: string | null; + readonly text1: string | null; + readonly description: string | null; readonly text3: string | null; readonly text4: string | null; readonly text5: string | null; @@ -1414,10 +1423,11 @@ export type CollectionObject = { readonly totalCountAmt: number | null; readonly totalValue: number | null; readonly uniqueIdentifier: string | null; - readonly number1: number | null; readonly version: number | null; readonly visibility: number | null; - readonly number2: number | null; + readonly fieldNumber: string | null; + readonly yesNo1: boolean | null; + readonly yesNo2: boolean | null; readonly yesNo3: boolean | null; readonly yesNo4: boolean | null; readonly yesNo5: boolean | null; @@ -1430,16 +1440,16 @@ export type CollectionObject = { readonly accession: Accession | null; readonly agent1: Agent | null; readonly appraisal: Appraisal | null; - readonly collectingEvent: CollectingEvent | null; + readonly cataloger: Agent | null; readonly collection: Collection; readonly collectionObjectType: CollectionObjectType; readonly container: Container | null; readonly containerOwner: Container | null; readonly createdByAgent: Agent | null; readonly currentDetermination: Determination | null; - readonly cataloger: Agent | null; readonly modifiedByAgent: Agent | null; readonly embargoAuthority: Agent | null; + readonly collectingEvent: CollectingEvent | null; readonly fieldNotebookPage: FieldNotebookPage | null; readonly inventorizedBy: Agent | null; readonly paleoContext: PaleoContext | null; @@ -1508,23 +1518,12 @@ export type CollectionObjectAttr = { export type CollectionObjectAttribute = { readonly tableName: 'CollectionObjectAttribute'; readonly fields: { - readonly number1: number | null; - readonly text4: string | null; readonly bottomDistance: number | null; readonly collectionMemberId: number; - readonly text11: string | null; - readonly text12: string | null; - readonly text10: string | null; - readonly text2: string | null; - readonly number37: number | null; readonly date1: string | null; readonly date1Precision: number | null; - readonly remarks: string | null; - readonly text15: string | null; readonly direction: string | null; readonly distanceUnits: string | null; - readonly text6: string | null; - readonly number2: number | null; readonly integer1: number | null; readonly integer10: number | null; readonly integer2: number | null; @@ -1535,18 +1534,18 @@ export type CollectionObjectAttribute = { readonly integer7: number | null; readonly integer8: number | null; readonly integer9: number | null; - readonly number38: number | null; - readonly text7: string | null; - readonly number10: number | null; - readonly number11: number | null; readonly number12: number | null; readonly number13: number | null; + readonly number1: number | null; + readonly number10: number | null; + readonly number11: number | null; readonly number14: number | null; readonly number15: number | null; readonly number16: number | null; readonly number17: number | null; readonly number18: number | null; readonly number19: number | null; + readonly number2: number | null; readonly number20: number | null; readonly number21: number | null; readonly number22: number | null; @@ -1565,20 +1564,27 @@ export type CollectionObjectAttribute = { readonly number34: number | null; readonly number35: number | null; readonly number36: number | null; + readonly number37: number | null; + readonly number38: number | null; readonly number39: number | null; readonly number4: number | null; readonly number40: number | null; + readonly number41: number | null; readonly number42: number | null; readonly number5: number | null; readonly number6: number | null; readonly number7: number | null; readonly number8: number | null; readonly number9: number | null; - readonly positionState: string | null; - readonly text3: string | null; - readonly text5: string | null; readonly text13: string | null; readonly text14: string | null; + readonly text1: string | null; + readonly positionState: string | null; + readonly text10: string | null; + readonly remarks: string | null; + readonly text8: string | null; + readonly text11: string | null; + readonly text15: string | null; readonly text16: string | null; readonly text17: string | null; readonly text18: string | null; @@ -1593,6 +1599,7 @@ export type CollectionObjectAttribute = { readonly text27: string | null; readonly text28: string | null; readonly text29: string | null; + readonly text3: string | null; readonly text30: string | null; readonly text31: string | null; readonly text32: string | null; @@ -1603,15 +1610,18 @@ export type CollectionObjectAttribute = { readonly text37: string | null; readonly text38: string | null; readonly text39: string | null; + readonly text4: string | null; readonly text40: string | null; + readonly text5: string | null; + readonly text6: string | null; + readonly text7: string | null; readonly text9: string | null; readonly timestampCreated: string; readonly timestampModified: string | null; + readonly text12: string | null; readonly topDistance: number | null; - readonly text1: string | null; readonly version: number | null; - readonly text8: string | null; - readonly number41: number | null; + readonly text2: string | null; readonly yesNo1: boolean | null; readonly yesNo10: boolean | null; readonly yesNo11: boolean | null; @@ -2185,7 +2195,9 @@ export type DNASequence = { readonly compT: number | null; readonly extractionDate: string | null; readonly extractionDatePrecision: number | null; + readonly text2: string | null; readonly genbankAccessionNumber: string | null; + readonly text1: string | null; readonly geneSequence: string | null; readonly moleculeType: string | null; readonly number1: number | null; @@ -2195,8 +2207,6 @@ export type DNASequence = { readonly sequenceDate: string | null; readonly sequenceDatePrecision: number | null; readonly targetMarker: string | null; - readonly text1: string | null; - readonly text2: string | null; readonly text3: string | null; readonly timestampCreated: string; readonly timestampModified: string | null; @@ -2289,8 +2299,8 @@ export type DNASequencingRun = { readonly runByAgent: Agent | null; }; readonly toManyDependent: { - readonly attachments: RA; readonly citations: RA; + readonly attachments: RA; }; readonly toManyIndependent: RR; }; @@ -2359,10 +2369,11 @@ export type DataType = { export type Deaccession = { readonly tableName: 'Deaccession'; readonly fields: { + readonly timestampModified: string | null; readonly date1: string | null; readonly date2: string | null; - readonly deaccessionDate: string | null; readonly deaccessionNumber: string; + readonly deaccessionDate: string | null; readonly integer1: number | null; readonly integer2: number | null; readonly integer3: number | null; @@ -2381,7 +2392,6 @@ export type Deaccession = { readonly text4: string | null; readonly text5: string | null; readonly timestampCreated: string; - readonly timestampModified: string | null; readonly totalItems: number | null; readonly totalPreps: number | null; readonly type: string | null; @@ -2450,14 +2460,15 @@ export type Determination = { readonly tableName: 'Determination'; readonly fields: { readonly addendum: string | null; - readonly text1: string | null; readonly alternateName: string | null; readonly collectionMemberId: number; readonly confidence: string | null; readonly isCurrent: boolean; readonly determinedDate: string | null; readonly determinedDatePrecision: number | null; + readonly featureOrBasis: string | null; readonly guid: string | null; + readonly yesNo1: boolean | null; readonly integer1: number | null; readonly integer2: number | null; readonly integer3: number | null; @@ -2473,6 +2484,8 @@ export type Determination = { readonly qualifier: string | null; readonly remarks: string | null; readonly subSpQualifier: string | null; + readonly text1: string | null; + readonly text2: string | null; readonly text3: string | null; readonly text4: string | null; readonly text5: string | null; @@ -2481,12 +2494,9 @@ export type Determination = { readonly text8: string | null; readonly timestampCreated: string; readonly timestampModified: string | null; - readonly text2: string | null; readonly typeStatusName: string | null; readonly varQualifier: string | null; - readonly featureOrBasis: string | null; readonly version: number | null; - readonly yesNo1: boolean | null; readonly yesNo2: boolean | null; readonly yesNo3: boolean | null; readonly yesNo4: boolean | null; @@ -2498,8 +2508,8 @@ export type Determination = { readonly createdByAgent: Agent | null; readonly determiner: Agent | null; readonly modifiedByAgent: Agent | null; - readonly taxon: Taxon | null; readonly preferredTaxon: Taxon | null; + readonly taxon: Taxon | null; }; readonly toManyDependent: { readonly determinationCitations: RA; @@ -3337,8 +3347,8 @@ export type Gift = { readonly srcTaxonomy: string | null; readonly specialConditions: string | null; readonly status: string | null; - readonly text1: string | null; readonly text2: string | null; + readonly text1: string | null; readonly text3: string | null; readonly text4: string | null; readonly text5: string | null; @@ -3707,6 +3717,7 @@ export type Loan = { readonly dateClosed: string | null; readonly dateReceived: string | null; readonly yesNo1: boolean | null; + readonly text2: string | null; readonly integer1: number | null; readonly integer2: number | null; readonly integer3: number | null; @@ -3728,7 +3739,6 @@ export type Loan = { readonly specialConditions: string | null; readonly status: string | null; readonly text1: string | null; - readonly text2: string | null; readonly text3: string | null; readonly text4: string | null; readonly text5: string | null; @@ -3854,11 +3864,8 @@ export type LoanReturnPreparation = { export type Locality = { readonly tableName: 'Locality'; readonly fields: { - readonly text1: string | null; - readonly text2: string | null; readonly datum: string | null; readonly elevationAccuracy: number | null; - readonly elevationMethod: string | null; readonly gml: string | null; readonly guid: string | null; readonly latLongMethod: string | null; @@ -3883,6 +3890,8 @@ export type Locality = { readonly sgrStatus: number | null; readonly shortName: string | null; readonly srcLatLongUnit: number; + readonly text1: string | null; + readonly text2: string | null; readonly text3: string | null; readonly text4: string | null; readonly text5: string | null; @@ -3894,6 +3903,7 @@ export type Locality = { readonly verbatimLongitude: string | null; readonly version: number | null; readonly visibility: number | null; + readonly elevationMethod: string | null; readonly yesNo1: boolean | null; readonly yesNo2: boolean | null; readonly yesNo3: boolean | null; @@ -4387,12 +4397,10 @@ export type Preparation = { readonly sampleNumber: string | null; readonly status: string | null; readonly storageLocation: string | null; - readonly text1: string | null; readonly text10: string | null; readonly text11: string | null; readonly text12: string | null; readonly text13: string | null; - readonly text2: string | null; readonly text3: string | null; readonly text4: string | null; readonly text5: string | null; @@ -4402,8 +4410,10 @@ export type Preparation = { readonly text9: string | null; readonly timestampCreated: string; readonly timestampModified: string | null; - readonly version: number | null; + readonly text1: string | null; readonly yesNo1: boolean | null; + readonly version: number | null; + readonly text2: string | null; readonly yesNo2: boolean | null; readonly yesNo3: boolean | null; }; @@ -4780,7 +4790,10 @@ export type RecordSetItem = { export type ReferenceWork = { readonly tableName: 'ReferenceWork'; readonly fields: { + readonly text1: string | null; + readonly workDate: string | null; readonly doi: string | null; + readonly text2: string | null; readonly guid: string | null; readonly isPublished: boolean | null; readonly isbn: string | null; @@ -4791,8 +4804,6 @@ export type ReferenceWork = { readonly placeOfPublication: string | null; readonly publisher: string | null; readonly remarks: string | null; - readonly text1: string | null; - readonly text2: string | null; readonly timestampCreated: string; readonly timestampModified: string | null; readonly title: string; @@ -4801,7 +4812,6 @@ export type ReferenceWork = { readonly url: string | null; readonly version: number | null; readonly volume: string | null; - readonly workDate: string | null; readonly yesNo1: boolean | null; readonly yesNo2: boolean | null; }; @@ -4899,9 +4909,9 @@ export type RepositoryAgreementAttachment = { export type Shipment = { readonly tableName: 'Shipment'; readonly fields: { + readonly numberOfPackages: number | null; readonly insuredForAmount: string | null; readonly shipmentMethod: string | null; - readonly numberOfPackages: number | null; readonly number1: number | null; readonly number2: number | null; readonly remarks: string | null; @@ -5615,7 +5625,6 @@ export type Taxon = { readonly colStatus: string | null; readonly commonName: string | null; readonly cultivarName: string | null; - readonly environmentalProtectionStatus: string | null; readonly esaStatus: string | null; readonly fullName: string | null; readonly groupNumber: string | null; @@ -5639,6 +5648,7 @@ export type Taxon = { readonly number3: number | null; readonly number4: number | null; readonly number5: number | null; + readonly environmentalProtectionStatus: string | null; readonly rankId: number; readonly remarks: string | null; readonly source: string | null; @@ -6500,7 +6510,7 @@ export type CollectionObjectGroup = { readonly yesno2: boolean | null; readonly yesno3: boolean | null; }; - readonly toOneDependent: RR; + readonly toOneDependent: { readonly cojo: CollectionObjectGroupJoin | null }; readonly toOneIndependent: { readonly cogType: CollectionObjectGroupType; readonly collection: Collection | null; @@ -6508,7 +6518,9 @@ export type CollectionObjectGroup = { readonly modifiedByAgent: Agent | null; readonly parentCojo: CollectionObjectGroupJoin | null; }; - readonly toManyDependent: { readonly cojo: RA }; + readonly toManyDependent: { + readonly childCojos: RA; + }; readonly toManyIndependent: RR; }; export type CollectionObjectGroupJoin = { @@ -6575,10 +6587,10 @@ export type AbsoluteAge = { readonly remarks: string | null; readonly text1: string | null; readonly text2: string | null; - readonly yesno1: boolean | null; - readonly yesno2: boolean | null; readonly timestampCreated: string; readonly timestampModified: string | null; + readonly yesno1: boolean | null; + readonly yesno2: boolean | null; }; readonly toOneDependent: RR; readonly toOneIndependent: { @@ -6588,32 +6600,32 @@ export type AbsoluteAge = { readonly modifiedByAgent: Agent | null; }; readonly toManyDependent: { - readonly absoluteAgeAttachments: RA; + readonly absoluteAgeAttachments: RA; }; readonly toManyIndependent: RR; }; export type RelativeAge = { readonly tableName: 'RelativeAge'; readonly fields: { - readonly ageRype: string | null; + readonly ageType: string | null; readonly ageUncertainty: number | null; readonly collectionDate: string | null; readonly date1: string | null; readonly date2: string | null; readonly datingMethod: string | null; readonly datingMethodRemarks: string | null; - readonly relativeAgePeriod: number | null; readonly number1: number | null; readonly number2: number | null; + readonly relativeAgePeriod: number | null; readonly remarks: string | null; readonly text1: string | null; readonly text2: string | null; - readonly yesno1: boolean | null; - readonly yesno2: boolean | null; readonly timestampCreated: string; readonly timestampModified: string | null; readonly verbatimName: string | null; readonly verbatimPeriod: string | null; + readonly yesno1: boolean | null; + readonly yesno2: boolean | null; }; readonly toOneDependent: RR; readonly toOneIndependent: { @@ -6626,7 +6638,7 @@ export type RelativeAge = { readonly modifiedByAgent: Agent | null; }; readonly toManyDependent: { - readonly relativeAgeAttachments: RA; + readonly relativeAgeAttachments: RA; }; readonly toManyIndependent: RR; }; @@ -6639,9 +6651,7 @@ export type AbsoluteAgeAttachment = { readonly timestampModified: string | null; readonly version: number | null; }; - readonly toOneDependent: { - readonly attachment: Attachment; - }; + readonly toOneDependent: { readonly attachment: Attachment }; readonly toOneIndependent: { readonly absoluteAge: AbsoluteAge; readonly collectionMember: Collection; @@ -6660,9 +6670,7 @@ export type RelativeAgeAttachment = { readonly timestampModified: string | null; readonly version: number | null; }; - readonly toOneDependent: { - readonly attachment: Attachment; - }; + readonly toOneDependent: { readonly attachment: Attachment }; readonly toOneIndependent: { readonly collectionMember: Collection; readonly createdByAgent: Agent | null; @@ -6731,8 +6739,8 @@ export type TectonicUnitTreeDef = { readonly toOneDependent: RR; readonly toOneIndependent: { readonly createdByAgent: Agent | null; - readonly modifiedByAgent: Agent | null; readonly discipline: Discipline; + readonly modifiedByAgent: Agent | null; }; readonly toManyDependent: RR; readonly toManyIndependent: RR; @@ -6755,7 +6763,7 @@ export type TectonicUnitTreeDefItem = { }; readonly toOneDependent: RR; readonly toOneIndependent: { - readonly createdByAgent: Agent | null; + readonly createdbyagent: Agent | null; readonly modifiedByAgent: Agent | null; readonly parentItem: TectonicUnitTreeDefItem | null; readonly tectonicUnitTreeDef: TectonicUnitTreeDef; @@ -6763,7 +6771,7 @@ export type TectonicUnitTreeDefItem = { readonly toManyDependent: RR; readonly toManyIndependent: { readonly children: RA; - readonly treeEntries: RA; + readonly tectonicUnits: RA; }; }; export type TectonicUnit = { @@ -6792,7 +6800,7 @@ export type TectonicUnit = { readonly acceptedTectonicUnit: TectonicUnit | null; readonly createdByAgent: Agent | null; readonly modifiedByAgent: Agent | null; - readonly parent: TectonicUnit; + readonly parent: TectonicUnit | null; readonly tectonicUnitTreeDef: TectonicUnitTreeDef; readonly tectonicUnitTreeDefItem: TectonicUnitTreeDefItem; }; diff --git a/specifyweb/specify/api.py b/specifyweb/specify/api.py index 56dd8e72cc2..df0dd8ae210 100644 --- a/specifyweb/specify/api.py +++ b/specifyweb/specify/api.py @@ -575,7 +575,7 @@ def handle_fk_fields(collection, agent, obj, data: Dict[str, Any]) -> Tuple[List dirty: List[FieldChangeInfo] = [] for field_name, val in items: field = obj._meta.get_field(field_name) - if not field.many_to_one: continue + if not field.many_to_one and not field.one_to_one: continue old_related = get_related_or_none(obj, field_name) dependent = is_dependent_field(obj, field_name) diff --git a/specifyweb/specify/datamodel.py b/specifyweb/specify/datamodel.py index 16ca52942e4..ddb8c47c218 100644 --- a/specifyweb/specify/datamodel.py +++ b/specifyweb/specify/datamodel.py @@ -8294,8 +8294,9 @@ relationships=[ Relationship(name='collection', type='many-to-one', required=False, relatedModelName='Collection', column='CollectionID'), Relationship(name='cogType', type='many-to-one', required=True, relatedModelName='CollectionObjectGroupType', column='COGTypeID'), + Relationship(name='cojo', type='one-to-one', required=False, relatedModelName='CollectionObjectGroupJoin', otherSideName='childCog', dependent=True), Relationship(name='parentCojo', type='many-to-one', required=False, relatedModelName='CollectionObjectGroupJoin',column='CollectionObjectGroupJoinID', otherSideName='collectionobjectgroup'), - Relationship(name='cojo', type='one-to-many', required=False, relatedModelName='CollectionObjectGroupJoin', otherSideName='childCog', dependent=True), + Relationship(name='childCojos', type='one-to-many',required=False, dependent=True, relatedModelName='CollectionObjectGroupJoin', otherSideName='parentCog'), Relationship(name='createdByAgent', type='many-to-one', required=False, relatedModelName='Agent', column='CreatedByAgentID'), Relationship(name='modifiedByAgent', type='many-to-one', required=False, relatedModelName='Agent', column='ModifiedByAgentID'), ], @@ -8333,7 +8334,7 @@ ], relationships=[ - Relationship(name='parentCog', type='many-to-one', required=True, relatedModelName='CollectionObjectGroup', column='ParentCOGID', otherSideName='parentcojos'), + Relationship(name='parentCog', type='many-to-one', required=True, relatedModelName='CollectionObjectGroup', column='ParentCOGID', otherSideName='childCojos'), Relationship(name='childCog', type='one-to-one', required=False, relatedModelName='CollectionObjectGroup', column='ChildCOGID', otherSideName='cojo'), Relationship(name='childCo', type='one-to-one', required=False, relatedModelName='CollectionObject', column='ChildCOID', otherSideName='cojo'), Relationship(name='collectionobjectgroup', type='one-to-many',required=False, relatedModelName='CollectionObjectGroup', otherSideName='parentCojo'), diff --git a/specifyweb/specify/models.py b/specifyweb/specify/models.py index 96a40ab312c..c8e84d357ef 100644 --- a/specifyweb/specify/models.py +++ b/specifyweb/specify/models.py @@ -7604,7 +7604,7 @@ class Collectionobjectgroupjoin(models.Model): # aka. CoJo or CogJoin yesno3 = models.BooleanField(blank=True, null=True, unique=False, db_column='YesNo3', db_index=False) # Relationships: Many-to-One - parentcog = models.ForeignKey('CollectionObjectGroup', db_column='ParentCOGID', related_name='parentcojos', null=False, on_delete=models.CASCADE) + parentcog = models.ForeignKey('CollectionObjectGroup', db_column='ParentCOGID', related_name='childcojos', null=False, on_delete=models.CASCADE) # Relationships: One-to-One childcog = models.OneToOneField('CollectionObjectGroup', db_column='ChildCOGID', related_name='cojo', null=True, on_delete=models.CASCADE) From e19d2913b22e8d82c28e3c11e88374e2ce5551bb Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Thu, 17 Oct 2024 13:11:33 -0700 Subject: [PATCH 25/50] Remove unecessary code --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 2562871d206..bafb579c068 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -80,9 +80,6 @@ export function COJODialog({ newCOJO.set('parentCog', parentResourceUrl as never); collection?.add(newCOJO); - - const parentResourceCojo = parentResource.getDependentResource('cojo'); - if (typeof parentResourceCojo === 'object') parentResourceCojo.add(newCOJO); }; const handleStates = (): void => { From a3e4d35c2a246bc7ddb1f6f7d3b6c63684108ec5 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Fri, 18 Oct 2024 06:59:35 -0700 Subject: [PATCH 26/50] Remove comment --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index bafb579c068..f106a46d405 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -56,7 +56,6 @@ export function COJODialog({ const handleCOJOCreation = ( selectedResource?: SpecifyResource ): void => { - // NewResource.set('cojo', newCOJO); Do this in bus rule when saving main COG? if (parentResource === undefined) return; const resourceToUse = selectedResource ?? newResource; From ee44f359bd59cdaed5a1c364aaa3aee240022a81 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Fri, 18 Oct 2024 07:17:33 -0700 Subject: [PATCH 27/50] Remove condition --- .../lib/components/FormCells/FormTable.tsx | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx index 0102817ca2a..c9610c547c5 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx @@ -456,32 +456,31 @@ export function FormTable({ const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; - const addButtons = - isCOJO && typeof handleAddResources === 'function' ? ( - - } - /> - ) : typeof handleAddResources === 'function' && - mode !== 'view' && - !disableAdding ? ( - <> - {!isDependent && - hasTablePermission(relationship.relatedTable.name, 'read') ? ( - - ) : undefined} - {hasTablePermission(relationship.relatedTable.name, 'create') ? ( - { - const resource = new relationship.relatedTable.Resource(); - handleAddResources([resource]); - }} - /> - ) : undefined} - - ) : undefined; + const addButtons = isCOJO ? ( + + } + /> + ) : typeof handleAddResources === 'function' && + mode !== 'view' && + !disableAdding ? ( + <> + {!isDependent && + hasTablePermission(relationship.relatedTable.name, 'read') ? ( + + ) : undefined} + {hasTablePermission(relationship.relatedTable.name, 'create') ? ( + { + const resource = new relationship.relatedTable.Resource(); + handleAddResources([resource]); + }} + /> + ) : undefined} + + ) : undefined; return dialog === false ? ( From 96d39939a4431208f27f80fcfab5e36087720f5b Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 22 Oct 2024 06:23:58 -0700 Subject: [PATCH 28/50] Add field check for childCOJOs --- .../lib/components/FormCells/COJODialog.tsx | 22 ++++---- .../lib/components/FormCells/FormTable.tsx | 52 ++++++++++--------- .../FormSliders/IntegratedRecordSelector.tsx | 3 +- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index f106a46d405..5cf5fd6c2f4 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -33,7 +33,7 @@ export function COJODialog({ const [state, setState] = React.useState<'Add' | 'Search' | undefined>( undefined ); - const [resource, setResource] = React.useState< + const [resourceTable, setResourceTable] = React.useState< | SpecifyTable | SpecifyTable | undefined @@ -45,13 +45,13 @@ export function COJODialog({ >(undefined); React.useEffect(() => { - if (resource !== undefined) { - const createdResource = new resource.Resource() as + if (resourceTable !== undefined) { + const createdResource = new resourceTable.Resource() as | SpecifyResource | SpecifyResource; setNewResource(createdResource); } - }, [resource]); + }, [resourceTable]); const handleCOJOCreation = ( selectedResource?: SpecifyResource @@ -62,9 +62,7 @@ export function COJODialog({ if (resourceToUse === undefined) return; - if (newResource) { - void newResource.save(); - } + void newResource?.save(); const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); const field = @@ -83,7 +81,7 @@ export function COJODialog({ const handleStates = (): void => { setState(undefined); - setResource(undefined); + setResourceTable(undefined); handleClose(); }; @@ -101,18 +99,18 @@ export function COJODialog({ {COJOChildrenTables.map((table) => (
- {localized(table.label)} + {table.label} { setState('Add'); - setResource(table); + setResourceTable(table); }} /> { setState('Search'); - setResource(table); + setResourceTable(table); }} />
@@ -147,7 +145,7 @@ export function COJODialog({ forceCollection={undefined} multiple searchView={undefined} - table={resource as SpecifyTable} + table={resourceTable as SpecifyTable} onClose={(): void => setState(undefined)} onSelected={(selectedResources): void => { selectedResources.forEach((selectedResource) => { diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx index c9610c547c5..82f78bfc361 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx @@ -455,32 +455,34 @@ export function FormTable({ ); const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; + const isChildCojos = relationship.name === 'childCojos'; - const addButtons = isCOJO ? ( - - } - /> - ) : typeof handleAddResources === 'function' && - mode !== 'view' && - !disableAdding ? ( - <> - {!isDependent && - hasTablePermission(relationship.relatedTable.name, 'read') ? ( - - ) : undefined} - {hasTablePermission(relationship.relatedTable.name, 'create') ? ( - { - const resource = new relationship.relatedTable.Resource(); - handleAddResources([resource]); - }} - /> - ) : undefined} - - ) : undefined; + const addButtons = + isCOJO && isChildCojos ? ( + + } + /> + ) : typeof handleAddResources === 'function' && + mode !== 'view' && + !disableAdding ? ( + <> + {!isDependent && + hasTablePermission(relationship.relatedTable.name, 'read') ? ( + + ) : undefined} + {hasTablePermission(relationship.relatedTable.name, 'create') ? ( + { + const resource = new relationship.relatedTable.Resource(); + handleAddResources([resource]); + }} + /> + ) : undefined} + + ) : undefined; return dialog === false ? ( diff --git a/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx b/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx index 2b77e767da1..f2c1a954884 100644 --- a/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx @@ -134,6 +134,7 @@ export function IntegratedRecordSelector({ collection.table.specifyTable.name.includes('Attachment'); const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; + const isChildCojos = relationship.name === 'childCojos'; return ( @@ -219,7 +220,7 @@ export function IntegratedRecordSelector({ relationship.relatedTable.name, 'create' ) && typeof handleAdd === 'function' ? ( - isCOJO ? ( + isCOJO && isChildCojos ? ( Date: Tue, 22 Oct 2024 06:24:52 -0700 Subject: [PATCH 29/50] Add to do --- .../frontend/js_src/lib/components/FormCells/FormTable.tsx | 1 + .../lib/components/FormSliders/IntegratedRecordSelector.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx index 82f78bfc361..40bc24ea3ff 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx @@ -455,6 +455,7 @@ export function FormTable({ ); const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; + // TODO: change when upadte childCojos to children in models const isChildCojos = relationship.name === 'childCojos'; const addButtons = diff --git a/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx b/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx index f2c1a954884..3c6882476f0 100644 --- a/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx @@ -134,6 +134,7 @@ export function IntegratedRecordSelector({ collection.table.specifyTable.name.includes('Attachment'); const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; + // TODO: change when upadte childCojos to children in models const isChildCojos = relationship.name === 'childCojos'; return ( From 7faa4ffab6489e80fccb983916b836333ea02b0d Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 23 Oct 2024 05:55:03 -0700 Subject: [PATCH 30/50] Test setting parentCojo --- .../js_src/lib/components/FormCells/COJODialog.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 5cf5fd6c2f4..21ec84d25a6 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -54,7 +54,9 @@ export function COJODialog({ }, [resourceTable]); const handleCOJOCreation = ( - selectedResource?: SpecifyResource + selectedResource?: + | SpecifyResource + | SpecifyResource ): void => { if (parentResource === undefined) return; @@ -76,6 +78,13 @@ export function COJODialog({ newCOJO.set(field, resourceUrl as never); newCOJO.set('parentCog', parentResourceUrl as never); + if (resourceToUse.specifyTable.name === 'CollectionObjectGroup') { + (resourceToUse as SpecifyResource).set( + 'parentCojo', + newCOJO + ); + } + collection?.add(newCOJO); }; From a97855aff508209f42341556007c0c58e8938217 Mon Sep 17 00:00:00 2001 From: Sharad S Date: Fri, 25 Oct 2024 11:27:40 -0400 Subject: [PATCH 31/50] Add cojo back to COG --- specifyweb/frontend/js_src/lib/components/DataModel/types.ts | 1 + specifyweb/specify/datamodel.py | 1 + 2 files changed, 2 insertions(+) diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/types.ts b/specifyweb/frontend/js_src/lib/components/DataModel/types.ts index 25cb57137f9..bbe15086419 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/types.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/types.ts @@ -6522,6 +6522,7 @@ export type CollectionObjectGroup = { }; readonly toManyDependent: { readonly children: RA; + readonly cojo: RA; }; readonly toManyIndependent: RR; }; diff --git a/specifyweb/specify/datamodel.py b/specifyweb/specify/datamodel.py index b445e89b28a..366d6b76385 100644 --- a/specifyweb/specify/datamodel.py +++ b/specifyweb/specify/datamodel.py @@ -8297,6 +8297,7 @@ Relationship(name='collection', type='many-to-one', required=False, relatedModelName='Collection', column='CollectionID'), Relationship(name='cogType', type='many-to-one', required=True, relatedModelName='CollectionObjectGroupType', column='COGTypeID'), Relationship(name='parentCojo', type='many-to-one', required=False, relatedModelName='CollectionObjectGroupJoin',column='CollectionObjectGroupJoinID', otherSideName='collectionobjectgroup'), + Relationship(name='cojo', type='one-to-many', required=False, relatedModelName='CollectionObjectGroupJoin', otherSideName='childCog', dependent=True), Relationship(name='children', type='one-to-many', required=False, dependent=True, relatedModelName='CollectionObjectGroupJoin', otherSideName='parentCog'), Relationship(name='createdByAgent', type='many-to-one', required=False, relatedModelName='Agent', column='CreatedByAgentID'), Relationship(name='modifiedByAgent', type='many-to-one', required=False, relatedModelName='Agent', column='ModifiedByAgentID'), From 5a94c4ffba19d87d1d6b038d12b0a3b19d73e957 Mon Sep 17 00:00:00 2001 From: Sharad S Date: Fri, 25 Oct 2024 11:52:14 -0400 Subject: [PATCH 32/50] Use children relationship for opening COJO dialog --- .../lib/components/FormCells/FormTable.tsx | 57 +++++++++---------- .../FormSliders/IntegratedRecordSelector.tsx | 8 +-- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx index 40bc24ea3ff..8d59431d024 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/FormTable.tsx @@ -454,36 +454,35 @@ export function FormTable({
); - const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; - // TODO: change when upadte childCojos to children in models - const isChildCojos = relationship.name === 'childCojos'; + const isCOJO = + relationship.relatedTable.name === 'CollectionObjectGroupJoin' && + relationship.name === 'children'; - const addButtons = - isCOJO && isChildCojos ? ( - - } - /> - ) : typeof handleAddResources === 'function' && - mode !== 'view' && - !disableAdding ? ( - <> - {!isDependent && - hasTablePermission(relationship.relatedTable.name, 'read') ? ( - - ) : undefined} - {hasTablePermission(relationship.relatedTable.name, 'create') ? ( - { - const resource = new relationship.relatedTable.Resource(); - handleAddResources([resource]); - }} - /> - ) : undefined} - - ) : undefined; + const addButtons = isCOJO ? ( + + } + /> + ) : typeof handleAddResources === 'function' && + mode !== 'view' && + !disableAdding ? ( + <> + {!isDependent && + hasTablePermission(relationship.relatedTable.name, 'read') ? ( + + ) : undefined} + {hasTablePermission(relationship.relatedTable.name, 'create') ? ( + { + const resource = new relationship.relatedTable.Resource(); + handleAddResources([resource]); + }} + /> + ) : undefined} + + ) : undefined; return dialog === false ? ( diff --git a/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx b/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx index 63c29d1d65a..fe31b2fe546 100644 --- a/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormSliders/IntegratedRecordSelector.tsx @@ -135,9 +135,9 @@ export function IntegratedRecordSelector({ const isAttachmentTable = collection.table.specifyTable.name.includes('Attachment'); - const isCOJO = relationship.relatedTable.name === 'CollectionObjectGroupJoin'; - // TODO: change when upadte childCojos to children in models - const isChildCojos = relationship.name === 'childCojos'; + const isCOJO = + relationship.relatedTable.name === 'CollectionObjectGroupJoin' && + relationship.name === 'children'; return ( @@ -223,7 +223,7 @@ export function IntegratedRecordSelector({ relationship.relatedTable.name, 'create' ) && typeof handleAdd === 'function' ? ( - isCOJO && isChildCojos ? ( + isCOJO ? ( Date: Fri, 25 Oct 2024 12:22:35 -0400 Subject: [PATCH 33/50] Remove unused import --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index 21ec84d25a6..bd96517f493 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -3,7 +3,6 @@ import React from 'react'; import { useBooleanState } from '../../hooks/useBooleanState'; import { commonText } from '../../localization/common'; import { formsText } from '../../localization/forms'; -import { localized } from '../../utils/types'; import { DataEntry } from '../Atoms/DataEntry'; import type { AnySchema } from '../DataModel/helperTypes'; import type { SpecifyResource } from '../DataModel/legacyTypes'; From 6c220a4a76f24c50b5bee94a23d8c71ba3471b84 Mon Sep 17 00:00:00 2001 From: Sharad S Date: Fri, 25 Oct 2024 15:25:52 -0400 Subject: [PATCH 34/50] Save parentCojo on childCog --- specifyweb/businessrules/rules/cojo_rules.py | 9 +++++++-- .../js_src/lib/components/FormCells/COJODialog.tsx | 8 -------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/specifyweb/businessrules/rules/cojo_rules.py b/specifyweb/businessrules/rules/cojo_rules.py index d4925fa5932..574cb3a5623 100644 --- a/specifyweb/businessrules/rules/cojo_rules.py +++ b/specifyweb/businessrules/rules/cojo_rules.py @@ -1,6 +1,6 @@ from specifyweb.businessrules.exceptions import BusinessRuleException from specifyweb.businessrules.orm_signal_handler import orm_signal_handler -from specifyweb.specify.models import Collectionobjectgroupjoin +from specifyweb.specify.models import Collectionobjectgroupjoin, Collectionobjectgroup @orm_signal_handler('pre_save', 'Collectionobjectgroupjoin') def cojo_pre_save(cojo): @@ -24,4 +24,9 @@ def cojo_pre_save(cojo): (Collectionobjectgroupjoin.objects .filter(parentcog=cojo.parentcog) .update(issubstrate=False)) - \ No newline at end of file + +@orm_signal_handler('post_save', 'Collectionobjectgroupjoin') +def cojo_post_save(cojo): + if cojo.childcog is not None: + cojo.childcog.parentcojo = cojo + cojo.childcog.save() \ No newline at end of file diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index bd96517f493..f224be0ec71 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -76,14 +76,6 @@ export function COJODialog({ newCOJO.set(field, resourceUrl as never); newCOJO.set('parentCog', parentResourceUrl as never); - - if (resourceToUse.specifyTable.name === 'CollectionObjectGroup') { - (resourceToUse as SpecifyResource).set( - 'parentCojo', - newCOJO - ); - } - collection?.add(newCOJO); }; From 40d55c1330cdc708156cf147fb5a92f9c4626850 Mon Sep 17 00:00:00 2001 From: Sharad S Date: Fri, 25 Oct 2024 16:06:48 -0400 Subject: [PATCH 35/50] Remove unused import --- specifyweb/businessrules/rules/cojo_rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specifyweb/businessrules/rules/cojo_rules.py b/specifyweb/businessrules/rules/cojo_rules.py index 574cb3a5623..8633d0f666e 100644 --- a/specifyweb/businessrules/rules/cojo_rules.py +++ b/specifyweb/businessrules/rules/cojo_rules.py @@ -1,6 +1,6 @@ from specifyweb.businessrules.exceptions import BusinessRuleException from specifyweb.businessrules.orm_signal_handler import orm_signal_handler -from specifyweb.specify.models import Collectionobjectgroupjoin, Collectionobjectgroup +from specifyweb.specify.models import Collectionobjectgroupjoin @orm_signal_handler('pre_save', 'Collectionobjectgroupjoin') def cojo_pre_save(cojo): From 301e676eba0c7e71f8ba7467b1247a3cd882ca86 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Mon, 28 Oct 2024 07:53:22 -0700 Subject: [PATCH 36/50] Chnage resource to save --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index f224be0ec71..dbd0bec5e2a 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -63,7 +63,7 @@ export function COJODialog({ if (resourceToUse === undefined) return; - void newResource?.save(); + void resourceToUse?.save(); const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); const field = From 3a121c412c4b2bb12ba6d4a98fd13e28eaea8e98 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:26:56 -0700 Subject: [PATCH 37/50] Remove unecessary code --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index dbd0bec5e2a..df519599411 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -6,6 +6,7 @@ import { formsText } from '../../localization/forms'; import { DataEntry } from '../Atoms/DataEntry'; import type { AnySchema } from '../DataModel/helperTypes'; import type { SpecifyResource } from '../DataModel/legacyTypes'; +import { fetchResource } from '../DataModel/resource'; import type { Collection, SpecifyTable } from '../DataModel/specifyTable'; import { tables } from '../DataModel/tables'; import type { @@ -63,8 +64,6 @@ export function COJODialog({ if (resourceToUse === undefined) return; - void resourceToUse?.save(); - const newCOJO = new tables.CollectionObjectGroupJoin.Resource(); const field = resourceToUse.specifyTable.name === 'CollectionObject' From 4ad6de624a4baac96c792acde16f062ba060dd55 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:31:27 -0700 Subject: [PATCH 38/50] Remove import --- .../frontend/js_src/lib/components/FormCells/COJODialog.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx index df519599411..0f2e9a347dd 100644 --- a/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/FormCells/COJODialog.tsx @@ -6,7 +6,6 @@ import { formsText } from '../../localization/forms'; import { DataEntry } from '../Atoms/DataEntry'; import type { AnySchema } from '../DataModel/helperTypes'; import type { SpecifyResource } from '../DataModel/legacyTypes'; -import { fetchResource } from '../DataModel/resource'; import type { Collection, SpecifyTable } from '../DataModel/specifyTable'; import { tables } from '../DataModel/tables'; import type { From b11972eb758a4771f3746e66c98d9e3b2c8d4b60 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:51:33 -0700 Subject: [PATCH 39/50] Test bus rule on delte cojo for parent --- specifyweb/businessrules/rules/cojo_rules.py | 7 ++++++- .../js_src/lib/components/DataModel/businessRuleDefs.ts | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/specifyweb/businessrules/rules/cojo_rules.py b/specifyweb/businessrules/rules/cojo_rules.py index 8633d0f666e..d98ce0310b7 100644 --- a/specifyweb/businessrules/rules/cojo_rules.py +++ b/specifyweb/businessrules/rules/cojo_rules.py @@ -29,4 +29,9 @@ def cojo_pre_save(cojo): def cojo_post_save(cojo): if cojo.childcog is not None: cojo.childcog.parentcojo = cojo - cojo.childcog.save() \ No newline at end of file + cojo.childcog.save() + +@orm_signal_handler('pre_delete', 'Collectionobjectgroupjoin') +def cojo_pre_delete(cojo): + cojo.childcog.parentcojo = None + cojo.childcog.save() \ No newline at end of file diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/businessRuleDefs.ts b/specifyweb/frontend/js_src/lib/components/DataModel/businessRuleDefs.ts index 5f32c1f55c9..3c58b79a5a0 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/businessRuleDefs.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/businessRuleDefs.ts @@ -142,7 +142,6 @@ export const businessRuleDefs: MappedBusinessRuleDefs = { }, }, }, - CollectionObject: { customInit: (collectionObject: SpecifyResource): void => { const ceField = collectionObject.specifyTable.getField('collectingEvent'); From 8e335039bf3743aa876cae2b9fca6eddc75ca538 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:13:22 -0700 Subject: [PATCH 40/50] Update delete for parentcojo --- .../0009_updateDelete_parentcojo.py | 20 +++++++++++++++++++ specifyweb/specify/models.py | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 specifyweb/specify/migrations/0009_updateDelete_parentcojo.py diff --git a/specifyweb/specify/migrations/0009_updateDelete_parentcojo.py b/specifyweb/specify/migrations/0009_updateDelete_parentcojo.py new file mode 100644 index 00000000000..b52d511a828 --- /dev/null +++ b/specifyweb/specify/migrations/0009_updateDelete_parentcojo.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.15 on 2024-10-29 18:01 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + #change dep when merge with prod + ('specify', '0007_schema_config_update'), + ] + + operations = [ + migrations.AlterField( + model_name='collectionobjectgroup', + name='parentcojo', + field=models.ForeignKey(db_column='CollectionObjectGroupJoinID', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='collectionobjectgroup', to='specify.collectionobjectgroupjoin'), + ), + ] diff --git a/specifyweb/specify/models.py b/specifyweb/specify/models.py index cd219404848..ab572ce2d27 100644 --- a/specifyweb/specify/models.py +++ b/specifyweb/specify/models.py @@ -7573,7 +7573,7 @@ class Collectionobjectgroup(models.Model): # aka. Cog cogtype = models.ForeignKey('CollectionObjectGroupType', db_column='COGTypeID', related_name='collectionobjectgroups', null=False, on_delete=protect_with_blockers) createdbyagent = models.ForeignKey('Agent', db_column='CreatedByAgentID', related_name='+', null=True, on_delete=protect_with_blockers) modifiedbyagent = models.ForeignKey('Agent', db_column='ModifiedByAgentID', related_name='+', null=True, on_delete=protect_with_blockers) - parentcojo = models.ForeignKey('CollectionObjectGroupJoin', db_column='CollectionObjectGroupJoinID', related_name='collectionobjectgroup', null=True, on_delete=protect_with_blockers) + parentcojo = models.ForeignKey('CollectionObjectGroupJoin', db_column='CollectionObjectGroupJoinID', related_name='collectionobjectgroup', null=True, on_delete=models.SET_NULL) class Meta: db_table = 'collectionobjectgroup' From d2f97b1bf7b6536159acd3e1578a2cc73b62e8d5 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:39:00 -0700 Subject: [PATCH 41/50] Remove pre delte cojo --- specifyweb/businessrules/rules/cojo_rules.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/specifyweb/businessrules/rules/cojo_rules.py b/specifyweb/businessrules/rules/cojo_rules.py index d98ce0310b7..8633d0f666e 100644 --- a/specifyweb/businessrules/rules/cojo_rules.py +++ b/specifyweb/businessrules/rules/cojo_rules.py @@ -29,9 +29,4 @@ def cojo_pre_save(cojo): def cojo_post_save(cojo): if cojo.childcog is not None: cojo.childcog.parentcojo = cojo - cojo.childcog.save() - -@orm_signal_handler('pre_delete', 'Collectionobjectgroupjoin') -def cojo_pre_delete(cojo): - cojo.childcog.parentcojo = None - cojo.childcog.save() \ No newline at end of file + cojo.childcog.save() \ No newline at end of file From 6da2c73d5757151fd8f5b33f7edd8caf9dd73717 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:03:35 -0700 Subject: [PATCH 42/50] Add one cogParent bus rule --- specifyweb/businessrules/rules/cojo_rules.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specifyweb/businessrules/rules/cojo_rules.py b/specifyweb/businessrules/rules/cojo_rules.py index 8633d0f666e..5a1b6df0fd8 100644 --- a/specifyweb/businessrules/rules/cojo_rules.py +++ b/specifyweb/businessrules/rules/cojo_rules.py @@ -24,6 +24,9 @@ def cojo_pre_save(cojo): (Collectionobjectgroupjoin.objects .filter(parentcog=cojo.parentcog) .update(issubstrate=False)) + + if cojo.childcog.parentcojo is not None: + raise BusinessRuleException('ChildCog is already in use as a child in another COG.') @orm_signal_handler('post_save', 'Collectionobjectgroupjoin') def cojo_post_save(cojo): From df1439e19b78f3b690186b680353cb720ad3359a Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:28:42 -0700 Subject: [PATCH 43/50] Add check for COG present --- specifyweb/businessrules/rules/cojo_rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specifyweb/businessrules/rules/cojo_rules.py b/specifyweb/businessrules/rules/cojo_rules.py index 5a1b6df0fd8..73c8f9623ca 100644 --- a/specifyweb/businessrules/rules/cojo_rules.py +++ b/specifyweb/businessrules/rules/cojo_rules.py @@ -25,7 +25,7 @@ def cojo_pre_save(cojo): .filter(parentcog=cojo.parentcog) .update(issubstrate=False)) - if cojo.childcog.parentcojo is not None: + if cojo.childcog is not None and cojo.childcog.parentcojo is not None: raise BusinessRuleException('ChildCog is already in use as a child in another COG.') @orm_signal_handler('post_save', 'Collectionobjectgroupjoin') From be175f2d69fb72c6acb72cf207a130620f9493d9 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:42:48 -0700 Subject: [PATCH 44/50] Improve bus rule --- specifyweb/businessrules/rules/cojo_rules.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specifyweb/businessrules/rules/cojo_rules.py b/specifyweb/businessrules/rules/cojo_rules.py index 73c8f9623ca..d2dec6035fe 100644 --- a/specifyweb/businessrules/rules/cojo_rules.py +++ b/specifyweb/businessrules/rules/cojo_rules.py @@ -25,7 +25,7 @@ def cojo_pre_save(cojo): .filter(parentcog=cojo.parentcog) .update(issubstrate=False)) - if cojo.childcog is not None and cojo.childcog.parentcojo is not None: + if cojo.childcog is not None and cojo.childcog.parentcojo is not None and cojo.childcog.parentcojo.id is not cojo.id: raise BusinessRuleException('ChildCog is already in use as a child in another COG.') @orm_signal_handler('post_save', 'Collectionobjectgroupjoin') From 397d2cb2fe19bb3d1cf6b5b414d9304ed756fe2f Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:55:29 -0700 Subject: [PATCH 45/50] Test --- specifyweb/businessrules/tests/test_cojo.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/specifyweb/businessrules/tests/test_cojo.py b/specifyweb/businessrules/tests/test_cojo.py index 0c28acfacde..78662a12fbf 100644 --- a/specifyweb/businessrules/tests/test_cojo.py +++ b/specifyweb/businessrules/tests/test_cojo.py @@ -16,6 +16,10 @@ def test_cojo_rules_enforcement(self): collection=self.collection, cogtype=cog_type ) + cog_4 = Collectionobjectgroup.objects.create( + collection=self.collection, + cogtype=cog_type + ) cojo_1 = Collectionobjectgroupjoin.objects.create( parentcog=cog_1, childcog=cog_2, @@ -23,7 +27,7 @@ def test_cojo_rules_enforcement(self): issubstrate=True ) cojo_2 = Collectionobjectgroupjoin.objects.create( - parentcog=cog_1, + parentcog=cog_4, childcog=cog_3, isprimary=True, issubstrate=True From 0e5220115027d9d902dd041dca3e47ca8f0cfe72 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:07:57 -0700 Subject: [PATCH 46/50] Revert --- specifyweb/businessrules/tests/test_cojo.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/specifyweb/businessrules/tests/test_cojo.py b/specifyweb/businessrules/tests/test_cojo.py index 78662a12fbf..0c28acfacde 100644 --- a/specifyweb/businessrules/tests/test_cojo.py +++ b/specifyweb/businessrules/tests/test_cojo.py @@ -16,10 +16,6 @@ def test_cojo_rules_enforcement(self): collection=self.collection, cogtype=cog_type ) - cog_4 = Collectionobjectgroup.objects.create( - collection=self.collection, - cogtype=cog_type - ) cojo_1 = Collectionobjectgroupjoin.objects.create( parentcog=cog_1, childcog=cog_2, @@ -27,7 +23,7 @@ def test_cojo_rules_enforcement(self): issubstrate=True ) cojo_2 = Collectionobjectgroupjoin.objects.create( - parentcog=cog_4, + parentcog=cog_1, childcog=cog_3, isprimary=True, issubstrate=True From 28195f6a32301c97750bc1db96c86518b33ade2a Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:14:16 -0700 Subject: [PATCH 47/50] Test with refresh --- specifyweb/businessrules/tests/test_cojo.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/specifyweb/businessrules/tests/test_cojo.py b/specifyweb/businessrules/tests/test_cojo.py index 0c28acfacde..d7e38383362 100644 --- a/specifyweb/businessrules/tests/test_cojo.py +++ b/specifyweb/businessrules/tests/test_cojo.py @@ -32,6 +32,9 @@ def test_cojo_rules_enforcement(self): cojo_1 = Collectionobjectgroupjoin.objects.get(id=cojo_1.id) cojo_2 = Collectionobjectgroupjoin.objects.get(id=cojo_2.id) + cojo_1.refresh_from_db() + cojo_2.refresh_from_db() + self.assertFalse(cojo_1.isprimary) self.assertFalse(cojo_1.issubstrate) self.assertTrue(cojo_2.isprimary) @@ -48,6 +51,10 @@ def test_cojo_rules_enforcement(self): issubstrate=False ) + cojo_1.refresh_from_db() + cojo_2.refresh_from_db() + cojo_3.refresh_from_db() + cojo_1 = Collectionobjectgroupjoin.objects.get(id=cojo_1.id) cojo_2 = Collectionobjectgroupjoin.objects.get(id=cojo_2.id) cojo_3 = Collectionobjectgroupjoin.objects.get(id=cojo_3.id) From 3b1ac8d49b987164bb74ce19d21a6ca324093c30 Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:35:24 -0700 Subject: [PATCH 48/50] Remove db refresh --- specifyweb/businessrules/tests/test_cojo.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/specifyweb/businessrules/tests/test_cojo.py b/specifyweb/businessrules/tests/test_cojo.py index d7e38383362..0c28acfacde 100644 --- a/specifyweb/businessrules/tests/test_cojo.py +++ b/specifyweb/businessrules/tests/test_cojo.py @@ -32,9 +32,6 @@ def test_cojo_rules_enforcement(self): cojo_1 = Collectionobjectgroupjoin.objects.get(id=cojo_1.id) cojo_2 = Collectionobjectgroupjoin.objects.get(id=cojo_2.id) - cojo_1.refresh_from_db() - cojo_2.refresh_from_db() - self.assertFalse(cojo_1.isprimary) self.assertFalse(cojo_1.issubstrate) self.assertTrue(cojo_2.isprimary) @@ -51,10 +48,6 @@ def test_cojo_rules_enforcement(self): issubstrate=False ) - cojo_1.refresh_from_db() - cojo_2.refresh_from_db() - cojo_3.refresh_from_db() - cojo_1 = Collectionobjectgroupjoin.objects.get(id=cojo_1.id) cojo_2 = Collectionobjectgroupjoin.objects.get(id=cojo_2.id) cojo_3 = Collectionobjectgroupjoin.objects.get(id=cojo_3.id) From 31ee30a5be0de444230794fc2e15f9b00e33d90c Mon Sep 17 00:00:00 2001 From: Grant Fitzsimmons <37256050+grantfitzsimmons@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:57:36 -0500 Subject: [PATCH 49/50] Resolve duplicate migration --- ...dateDelete_parentcojo.py => 0010_updateDelete_parentcojo.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename specifyweb/specify/migrations/{0009_updateDelete_parentcojo.py => 0010_updateDelete_parentcojo.py} (92%) diff --git a/specifyweb/specify/migrations/0009_updateDelete_parentcojo.py b/specifyweb/specify/migrations/0010_updateDelete_parentcojo.py similarity index 92% rename from specifyweb/specify/migrations/0009_updateDelete_parentcojo.py rename to specifyweb/specify/migrations/0010_updateDelete_parentcojo.py index b52d511a828..b156c2c12d2 100644 --- a/specifyweb/specify/migrations/0009_updateDelete_parentcojo.py +++ b/specifyweb/specify/migrations/0010_updateDelete_parentcojo.py @@ -8,7 +8,7 @@ class Migration(migrations.Migration): dependencies = [ #change dep when merge with prod - ('specify', '0007_schema_config_update'), + ('specify', '0009_tectonic_ranks'), ] operations = [ From 02f576f29a796dbf9d26fcef7d19d5f0c6bb2b7d Mon Sep 17 00:00:00 2001 From: Caroline D <108160931+CarolineDenis@users.noreply.github.com> Date: Thu, 31 Oct 2024 10:18:05 -0700 Subject: [PATCH 50/50] Make result in qb unique --- .../frontend/js_src/lib/components/QueryBuilder/Results.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Results.tsx b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Results.tsx index 4b5ffa7ff43..9239859d899 100644 --- a/specifyweb/frontend/js_src/lib/components/QueryBuilder/Results.tsx +++ b/specifyweb/frontend/js_src/lib/components/QueryBuilder/Results.tsx @@ -373,8 +373,9 @@ export function QueryResults(props: QueryResultsProps): JSX.Element { ), ...(isSelected ? ids : []), ]; + const uniqueSelectedRows = Array.from(new Set(newSelectedRows)); setSelectedRows(new Set(newSelectedRows)); - handleSelected?.(newSelectedRows); + handleSelected?.(uniqueSelectedRows); lastSelectedRow.current = rowIndex; }}