diff --git a/specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/SelectUploadPath.tsx b/specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/SelectUploadPath.tsx index 6954dd98726..90e34edfd66 100644 --- a/specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/SelectUploadPath.tsx +++ b/specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/SelectUploadPath.tsx @@ -62,16 +62,28 @@ export function generateUploadSpec( const field = queryFieldSpec.getField(); const queryResultsFormatter = ( value: number | string | null | undefined - ): string | undefined => - value === undefined || value === null || field?.isRelationship === true - ? undefined - : syncFieldFormat( - field, - value.toString(), - queryFieldSpec.parser, - undefined, - true - ); + ): string | undefined => { + if (value === undefined || value === null || field?.isRelationship === true) + return undefined; + + const rawValue = value.toString(); + const fieldFormatter = field?.getUiFormatter(); + if (fieldFormatter !== undefined) + // Catalog number formatting can vary by Collection Object Type. The + // query field only has the schema-level formatter, so preserve database + // values that do not match that formatter instead of dropping them. + return fieldFormatter.format(rawValue) ?? rawValue; + + return ( + syncFieldFormat( + field, + rawValue, + queryFieldSpec.parser, + undefined, + true + ) ?? rawValue + ); + }; return { staticPathKey, formatQueryResults: queryResultsFormatter, diff --git a/specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/__tests__/SelectUploadPath.test.ts b/specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/__tests__/SelectUploadPath.test.ts new file mode 100644 index 00000000000..551626a52e2 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/AttachmentsBulkImport/__tests__/SelectUploadPath.test.ts @@ -0,0 +1,20 @@ +import { requireContext } from '../../../tests/helpers'; +import { generateUploadSpec } from '../SelectUploadPath'; + +requireContext(); + +describe('generateUploadSpec catalog number result formatting', () => { + test('preserves catalog numbers that do not match the schema formatter', () => + expect( + generateUploadSpec('collectionObjectCatalogNumber').formatQueryResults!( + 'F-250750' + ) + ).toBe('F-250750')); + + test('keeps canonical formatting for values accepted by the schema formatter', () => + expect( + generateUploadSpec('collectionObjectCatalogNumber').formatQueryResults!( + '123' + ) + ).toBe('000000123')); +}); diff --git a/specifyweb/frontend/js_src/lib/components/DataModel/tables.ts b/specifyweb/frontend/js_src/lib/components/DataModel/tables.ts index da35afb63e8..5826da28fad 100644 --- a/specifyweb/frontend/js_src/lib/components/DataModel/tables.ts +++ b/specifyweb/frontend/js_src/lib/components/DataModel/tables.ts @@ -249,8 +249,8 @@ export const getTableById = ( tableId: number ): SpecifyTable => (Object.values(genericTables).find((table) => table.tableId === tableId) as - SpecifyTable | undefined) ?? - error(`Table with id ${tableId} does not exist`); + | SpecifyTable + | undefined) ?? error(`Table with id ${tableId} does not exist`); // If this is true, then you can use {domainfilter:true} when fetching that table export const hasHierarchyField = (table: SpecifyTable): boolean => diff --git a/specifyweb/frontend/js_src/lib/hooks/usePaginatedCollection.tsx b/specifyweb/frontend/js_src/lib/hooks/usePaginatedCollection.tsx index 8016ff6942f..f4013573cb2 100644 --- a/specifyweb/frontend/js_src/lib/hooks/usePaginatedCollection.tsx +++ b/specifyweb/frontend/js_src/lib/hooks/usePaginatedCollection.tsx @@ -29,9 +29,9 @@ export function usePaginatedCollection({ const [results, setResults] = useTriggerState< RA | undefined >(initialRecords); - + const resultsRef = React.useRef(results); - + const handleSetResults: GetOrSet< RA | undefined >[typeof SET] = React.useCallback(