From b80e5dfb5fac55777dd361b6a7fbd877959bb179 Mon Sep 17 00:00:00 2001 From: alec_dev Date: Mon, 13 Apr 2026 10:51:38 -0500 Subject: [PATCH 1/5] Fix formatted CO query results for nested relationship fields --- .../backend/stored_queries/queryfieldspec.py | 44 ++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/specifyweb/backend/stored_queries/queryfieldspec.py b/specifyweb/backend/stored_queries/queryfieldspec.py index ceec7f6c8bf..dd11312a559 100644 --- a/specifyweb/backend/stored_queries/queryfieldspec.py +++ b/specifyweb/backend/stored_queries/queryfieldspec.py @@ -235,12 +235,6 @@ def from_stringid(cls, stringid: str, is_relation: bool): path = deque(path_str.split(",")) root_table = datamodel.get_table_by_id(int(path.popleft())) - if is_relation: - extracted_fieldname, _ = extract_date_part(field_name) - root_field = root_table.get_field(extracted_fieldname, strict=False) - if isinstance(root_field, Relationship): - path.pop() - join_path = [] node = root_table for elem in path: @@ -256,6 +250,44 @@ def from_stringid(cls, stringid: str, is_relation: bool): node = table extracted_fieldname, date_part = extract_date_part(field_name) + + if is_relation: + relation = None + if join_path and isinstance(join_path[-1], Relationship): + last_relation = join_path[-1] + related_table = datamodel.get_table( + last_relation.relatedModelName, strict=True + ) + if related_table.name.lower() == table_name.lower(): + relation = last_relation + + if relation is None: + relation = node.get_field(extracted_fieldname, strict=False) + if isinstance(relation, Relationship): + join_path.append(relation) + node = datamodel.get_table(relation.relatedModelName, strict=True) + else: + relation = None + + if relation is not None: + result = cls( + root_table=root_table, + root_sql_table=getattr(models, root_table.name), + join_path=tuple(join_path), + table=node, + date_part=None, + tree_rank=None, + tree_field=relation, + ) + logger.debug( + "parsed %s (is_relation %s) to %s. extracted_fieldname = %s", + stringid, + is_relation, + result, + extracted_fieldname, + ) + return result + field = node.get_field(extracted_fieldname, strict=False) tree_rank_name = None From ab40fa0c77669466049279702894ac90467e41b1 Mon Sep 17 00:00:00 2001 From: alec_dev Date: Mon, 13 Apr 2026 12:56:17 -0500 Subject: [PATCH 2/5] fix failing batch edit tests --- .../stored_queries/tests/static/co_query_row_plan.py | 7 +++---- specifyweb/backend/stored_queries/tests/tests_legacy.py | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/specifyweb/backend/stored_queries/tests/static/co_query_row_plan.py b/specifyweb/backend/stored_queries/tests/static/co_query_row_plan.py index 09008570f2f..d00943eb4a6 100644 --- a/specifyweb/backend/stored_queries/tests/static/co_query_row_plan.py +++ b/specifyweb/backend/stored_queries/tests/static/co_query_row_plan.py @@ -41,11 +41,11 @@ ), "collectingevent": RowPlanMap( batch_edit_pack=BatchEditPack( - id=BatchEditFieldPack(field=None, idx=18, value=None), + id=BatchEditFieldPack(field=None, idx=19, value=None), order=BatchEditFieldPack(field=None, idx=None, value=None), - version=BatchEditFieldPack(field=None, idx=19, value=None), + version=BatchEditFieldPack(field=None, idx=20, value=None), ), - columns=[], + columns=[BatchEditFieldPack(field=None, idx=18, value=None)], to_one={ "locality": RowPlanMap( batch_edit_pack=BatchEditPack( @@ -54,7 +54,6 @@ version=BatchEditFieldPack(field=None, idx=31, value=None), ), columns=[ - BatchEditFieldPack(field=None, idx=20, value=None), BatchEditFieldPack(field=None, idx=21, value=None), BatchEditFieldPack(field=None, idx=22, value=None), BatchEditFieldPack(field=None, idx=23, value=None), diff --git a/specifyweb/backend/stored_queries/tests/tests_legacy.py b/specifyweb/backend/stored_queries/tests/tests_legacy.py index cb34b27ae22..af9952a5350 100644 --- a/specifyweb/backend/stored_queries/tests/tests_legacy.py +++ b/specifyweb/backend/stored_queries/tests/tests_legacy.py @@ -1,4 +1,4 @@ -from unittest import TestCase, expectedFailure, skip +from unittest import TestCase, skip from sqlalchemy import orm, inspect import specifyweb.specify.models as spmodels @@ -11,7 +11,6 @@ def test_stringid_roundtrip_from_bug(self) -> None: fs = QueryFieldSpec.from_stringid("4.taxon.Genus", False) self.assertEqual("4.taxon.Genus", fs.to_stringid()) - @expectedFailure def test_stringid_roundtrip_en_masse(self) -> None: for (stringid, relfld) in STRINGID_LIST: fs = QueryFieldSpec.from_stringid(stringid, relfld) From e89962327c8adb0968bd3f5c3903dc05cc2201cb Mon Sep 17 00:00:00 2001 From: alec_dev Date: Mon, 13 Apr 2026 12:57:40 -0500 Subject: [PATCH 3/5] Add new unit tests for nested relationships --- .../test_field_specs_from_json.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/specifyweb/backend/stored_queries/tests/test_execution/test_field_specs_from_json.py b/specifyweb/backend/stored_queries/tests/test_execution/test_field_specs_from_json.py index c317fa53cf1..6749e225c89 100644 --- a/specifyweb/backend/stored_queries/tests/test_execution/test_field_specs_from_json.py +++ b/specifyweb/backend/stored_queries/tests/test_execution/test_field_specs_from_json.py @@ -101,6 +101,20 @@ def generate_fields_test_str(query_fields, var_name): # pragma: no cover class TestFieldSpecsFromJson(ApiTests): + def assert_relation_stringid(self, stringid: str, expected_path: tuple[str, ...]): + fieldspec = QueryFieldSpec.from_stringid(stringid, True) + round_tripped = QueryFieldSpec.from_stringid(fieldspec.to_stringid(), True) + + self.assertTrue(fieldspec.is_relationship()) + self.assertEqual(fieldspec, round_tripped) + self.assertEqual( + tuple(node.name for node in fieldspec.join_path), + expected_path, + ) + self.assertFalse( + any(isinstance(node, TreeRankQuery) for node in fieldspec.join_path) + ) + def test_static_field_specs(self): # pragma: no cover query = json.load(open("specifyweb/backend/stored_queries/tests/static/co_query.json")) query_fields = fields_from_json(query["fields"]) @@ -108,3 +122,27 @@ def test_static_field_specs(self): # pragma: no cover # generate_fields_test_str(query_fields, "static_simple_field_spec") self.assertEqual(static_simple_field_spec, query_fields) + + def test_nested_formatted_prep_type_stringid_stays_relationship(self): + self.assert_relation_stringid( + "1,63-preparations,65.preptype.prepType", + ("preparations", "prepType"), + ) + + def test_direct_formatted_collecting_event_stringid_stays_relationship(self): + self.assert_relation_stringid( + "1,10.collectingevent.collectingEvent", + ("collectingEvent",), + ) + + def test_nested_formatted_taxon_stringid_stays_relationship(self): + self.assert_relation_stringid( + "1,9-determinations,4.taxon.taxon", + ("determinations", "taxon"), + ) + + def test_nested_formatted_chronostrat_stringid_stays_relationship(self): + self.assert_relation_stringid( + "1,32,46-chronosStrat.geologictimeperiod.chronosStrat", + ("paleoContext", "chronosStrat"), + ) From df7e09122d48ee2249c951ca4e6b174db17198e3 Mon Sep 17 00:00:00 2001 From: alec_dev Date: Mon, 13 Apr 2026 16:31:26 -0500 Subject: [PATCH 4/5] Fix fields in unit test --- .../tests/static/simple_static_fields.py | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/specifyweb/backend/stored_queries/tests/static/simple_static_fields.py b/specifyweb/backend/stored_queries/tests/static/simple_static_fields.py index a84b3664c07..4afbd44c120 100644 --- a/specifyweb/backend/stored_queries/tests/static/simple_static_fields.py +++ b/specifyweb/backend/stored_queries/tests/static/simple_static_fields.py @@ -170,12 +170,12 @@ def get_sql_table(name): "cataloger" ), ), - "table": datamodel.get_table_strict("CollectionObject"), + "table": datamodel.get_table_strict("Agent"), "date_part": None, "tree_rank": None, - "tree_field": datamodel.get_table_strict( - "CollectionObject" - ).get_field_strict("cataloger"), + "tree_field": datamodel.get_table_strict("CollectionObject").get_field_strict( + "cataloger" + ), } ), op_num=8, @@ -308,12 +308,12 @@ def get_sql_table(name): "determinations" ), ), - "table": datamodel.get_table_strict("CollectionObject"), + "table": datamodel.get_table_strict("Determination"), "date_part": None, "tree_rank": None, - "tree_field": datamodel.get_table_strict( - "CollectionObject" - ).get_field_strict("determinations"), + "tree_field": datamodel.get_table_strict("CollectionObject").get_field_strict( + "determinations" + ), } ), op_num=8, @@ -334,12 +334,12 @@ def get_sql_table(name): "preparations" ), ), - "table": datamodel.get_table_strict("CollectionObject"), + "table": datamodel.get_table_strict("Preparation"), "date_part": None, "tree_rank": None, - "tree_field": datamodel.get_table_strict( - "CollectionObject" - ).get_field_strict("preparations"), + "tree_field": datamodel.get_table_strict("CollectionObject").get_field_strict( + "preparations" + ), } ), op_num=8, @@ -387,12 +387,12 @@ def get_sql_table(name): "collectingEvent" ), ), - "table": datamodel.get_table_strict("CollectionObject"), + "table": datamodel.get_table_strict("CollectingEvent"), "date_part": None, "tree_rank": None, - "tree_field": datamodel.get_table_strict( - "CollectionObject" - ).get_field_strict("collectingEvent"), + "tree_field": datamodel.get_table_strict("CollectionObject").get_field_strict( + "collectingEvent" + ), } ), op_num=8, @@ -415,19 +415,13 @@ def get_sql_table(name): datamodel.get_table_strict("CollectingEvent").get_field_strict( "locality" ), - TreeRankQuery( - **{ - "name": "locality", - "relatedModelName": "Locality", - "type": "many-to-one", - "column": "localityId", - } - ), ), "table": datamodel.get_table_strict("Locality"), "date_part": None, - "tree_rank": "locality", - "tree_field": None, + "tree_rank": None, + "tree_field": datamodel.get_table_strict("CollectingEvent").get_field_strict( + "locality" + ), } ), op_num=8, From a7463b4abdf0608deac0fa4cc25b87617899955e Mon Sep 17 00:00:00 2001 From: alec_dev Date: Mon, 18 May 2026 21:35:41 +0000 Subject: [PATCH 5/5] Lint code with ESLint and Prettier Triggered by 140013281d01d2a395e1191eb8ef7156624063d5 on branch refs/heads/issue-7919 --- .../ExpressSearchConfigDialog.tsx | 4 +- .../ResultsOrderingTab.tsx | 28 +++++++++---- .../ExpressSearchConfigEditor.test.tsx | 41 ++++++++++--------- .../__tests__/RelatedTablesTab.test.tsx | 8 +++- .../__tests__/ResultsOrderingTab.test.tsx | 4 +- .../lib/components/Formatters/formatters.ts | 9 ++-- .../components/Header/ExpressSearchHooks.tsx | 15 ++++--- .../components/Header/ExpressSearchTask.tsx | 20 ++++----- .../lib/components/WbPlanView/navigator.ts | 2 +- .../js_src/lib/localization/common.ts | 9 ++-- .../js_src/lib/localization/utils/config.ts | 2 +- .../js_src/lib/utils/schemaVisibility.ts | 2 +- 12 files changed, 82 insertions(+), 62 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/ExpressSearchConfigDialog.tsx b/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/ExpressSearchConfigDialog.tsx index 6c5b8a531b5..81cc07e0bd3 100644 --- a/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/ExpressSearchConfigDialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/ExpressSearchConfigDialog.tsx @@ -14,7 +14,7 @@ type ExpressSearchConfigDialogProps = { readonly isOpen: boolean; readonly onClose: () => void; readonly onSave?: () => void; -} +}; export function ExpressSearchConfigDialog({ isOpen, @@ -76,7 +76,7 @@ export function ExpressSearchConfigDialog({ isOpen={isOpen} onClose={onClose} > - diff --git a/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/ResultsOrderingTab.tsx b/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/ResultsOrderingTab.tsx index 4478fd66f5a..437e55abc1b 100644 --- a/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/ResultsOrderingTab.tsx +++ b/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/ResultsOrderingTab.tsx @@ -11,12 +11,17 @@ import { genericTables } from '../DataModel/tables'; function tableLabel(tableName: string): string { return ( - (genericTables[tableName as keyof typeof genericTables]?.label as string | undefined) ?? - camelToHuman(tableName) + (genericTables[tableName as keyof typeof genericTables]?.label as + | string + | undefined) ?? camelToHuman(tableName) ); } -export function ResultsOrderingTab({ config, relatedQueriesDefinitions = [], onChangeConfig }: any) { +export function ResultsOrderingTab({ + config, + relatedQueriesDefinitions = [], + onChangeConfig, +}: any) { const baseTables = config.tables .filter((t: any) => t.searchFields.some((sf: any) => sf.inUse !== false)) .map((t: any) => ({ @@ -29,8 +34,12 @@ export function ResultsOrderingTab({ config, relatedQueriesDefinitions = [], onC const activeQueries = config.relatedQueries .filter((rq: any) => rq.isActive) .map((rq: any) => { - const def = relatedQueriesDefinitions.find((def: any) => def.id === rq.id); - const title = def?.name ? getExpressSearchQueryTitle(def.name) : undefined; + const def = relatedQueriesDefinitions.find( + (def: any) => def.id === rq.id + ); + const title = def?.name + ? getExpressSearchQueryTitle(def.name) + : undefined; if (!def || !title || title === String(def.name)) { return undefined; @@ -86,7 +95,9 @@ export function ResultsOrderingTab({ config, relatedQueriesDefinitions = [], onC return (
-

{expressSearchConfigText.configureResultsOrdering()}

+

+ {expressSearchConfigText.configureResultsOrdering()} +

{expressSearchConfigText.reorderResultsOrderingDescription()}

@@ -99,7 +110,10 @@ export function ResultsOrderingTab({ config, relatedQueriesDefinitions = [], onC > {item.label}
- moveItem(index, 'up')}> + moveItem(index, 'up')} + > {icons.chevronUp} { @@ -65,42 +65,43 @@ describe('ExpressSearchConfigEditor', () => { }); expect(onChangeJSON).toHaveBeenCalled(); - const latestConfig = onChangeJSON.mock.calls[onChangeJSON.mock.calls.length - 1][0]; + const latestConfig = + onChangeJSON.mock.calls[onChangeJSON.mock.calls.length - 1][0]; expect(latestConfig.tables[0].tableName).toBe('Agent'); expect(latestConfig.tables[0].searchFields[0].fieldName).toBe('firstName'); }); test('renders loading state initially', async () => { const { getByText } = mount( - ); expect(getByText('Loading...')).toBeInTheDocument(); - + // Wait for it to finish loading to avoid act warnings await act(async () => { - await new Promise(resolve => setTimeout(resolve, 0)); + await new Promise((resolve) => setTimeout(resolve, 0)); }); }); test('renders tabs after data load', async () => { const { findByRole } = mount( - ); - + expect(await findByRole('tablist')).toBeInTheDocument(); }); test('switches tabs correctly', async () => { const { findByText, getByRole, user } = mount( - ); @@ -112,7 +113,7 @@ describe('ExpressSearchConfigEditor', () => { await act(async () => { await user.click(relatedTab); }); - + expect(await findByText('Related Tables Tab')).toBeInTheDocument(); // Click Results Ordering diff --git a/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/__tests__/RelatedTablesTab.test.tsx b/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/__tests__/RelatedTablesTab.test.tsx index bacba609689..e096a045a54 100644 --- a/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/__tests__/RelatedTablesTab.test.tsx +++ b/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/__tests__/RelatedTablesTab.test.tsx @@ -43,7 +43,9 @@ describe('RelatedTablesTab', () => { expect(onChangeConfig).toHaveBeenCalledTimes(1); const newConfig = onChangeConfig.mock.calls[0][0]; - expect(newConfig.relatedQueries.find((rq: any) => rq.id === '2').isActive).toBe(true); + expect( + newConfig.relatedQueries.find((rq: any) => rq.id === '2').isActive + ).toBe(true); const activeRow = rows[0]; const activeCheckbox = activeRow.querySelector('input[type="checkbox"]'); @@ -54,6 +56,8 @@ describe('RelatedTablesTab', () => { expect(onChangeConfig).toHaveBeenCalledTimes(2); const secondConfig = onChangeConfig.mock.calls[1][0]; - expect(secondConfig.relatedQueries.find((rq: any) => rq.id === '1').isActive).toBe(false); + expect( + secondConfig.relatedQueries.find((rq: any) => rq.id === '1').isActive + ).toBe(false); }); }); diff --git a/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/__tests__/ResultsOrderingTab.test.tsx b/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/__tests__/ResultsOrderingTab.test.tsx index 5997fc65f7c..4b15f595931 100644 --- a/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/__tests__/ResultsOrderingTab.test.tsx +++ b/specifyweb/frontend/js_src/lib/components/ExpressSearchConfig/__tests__/ResultsOrderingTab.test.tsx @@ -39,9 +39,7 @@ describe('ResultsOrderingTab', () => { displayFields: [], }, ], - relatedQueries: [ - { id: '8', isActive: true, displayOrder: 1 }, - ], + relatedQueries: [{ id: '8', isActive: true, displayOrder: 1 }], }; const onChangeConfig = jest.fn(); diff --git a/specifyweb/frontend/js_src/lib/components/Formatters/formatters.ts b/specifyweb/frontend/js_src/lib/components/Formatters/formatters.ts index 73acc8afab4..356b993e3de 100644 --- a/specifyweb/frontend/js_src/lib/components/Formatters/formatters.ts +++ b/specifyweb/frontend/js_src/lib/components/Formatters/formatters.ts @@ -198,9 +198,12 @@ async function formatField( if (trimZeros) { const num = Number(formatted); - formatted = Number.isNaN(num) || (formatted ?? '').trim() === '' || !Number.isSafeInteger(num) - ? formatted - : num.toString(); + formatted = + Number.isNaN(num) || + (formatted ?? '').trim() === '' || + !Number.isSafeInteger(num) + ? formatted + : num.toString(); } return { diff --git a/specifyweb/frontend/js_src/lib/components/Header/ExpressSearchHooks.tsx b/specifyweb/frontend/js_src/lib/components/Header/ExpressSearchHooks.tsx index a59d68078c7..62177d62253 100644 --- a/specifyweb/frontend/js_src/lib/components/Header/ExpressSearchHooks.tsx +++ b/specifyweb/frontend/js_src/lib/components/Header/ExpressSearchHooks.tsx @@ -52,14 +52,13 @@ export function usePrimarySearch( } async function fetchRelatedSearches(): Promise> { - return contextUnlockedPromise.then( - async (entrypoint) => - entrypoint === 'main' - ? ajax>('/context/available_related_searches.json', { - headers: { Accept: 'application/json' }, - cache: 'no-store', - }).then(({ data }) => data) - : foreverFetch>() + return contextUnlockedPromise.then(async (entrypoint) => + entrypoint === 'main' + ? ajax>('/context/available_related_searches.json', { + headers: { Accept: 'application/json' }, + cache: 'no-store', + }).then(({ data }) => data) + : foreverFetch>() ); } diff --git a/specifyweb/frontend/js_src/lib/components/Header/ExpressSearchTask.tsx b/specifyweb/frontend/js_src/lib/components/Header/ExpressSearchTask.tsx index 60686c9bccf..b392a409b6d 100644 --- a/specifyweb/frontend/js_src/lib/components/Header/ExpressSearchTask.tsx +++ b/specifyweb/frontend/js_src/lib/components/Header/ExpressSearchTask.tsx @@ -125,11 +125,7 @@ function ExpressSearchInstructions({ {headerText.documentation()} )} - +
    @@ -147,10 +143,8 @@ export function ExpressSearchView(): JSX.Element { const [pendingQuery] = value; const [isConfigOpen, setIsConfigOpen] = React.useState(false); const [configRefreshTrigger, setConfigRefreshTrigger] = React.useState(0); - const [showInstructions = true, setShowExpressSearchInstructions] = useCachedState( - 'expressSearch', - 'showSearchTips' - ); + const [showInstructions = true, setShowExpressSearchInstructions] = + useCachedState('expressSearch', 'showSearchTips'); const canEditExpressSearchConfig = hasToolPermission('resources', 'read') && hasToolPermission('resources', 'create') && @@ -176,11 +170,15 @@ export function ExpressSearchView(): JSX.Element { setShowExpressSearchInstructions((value) => !value)} + onClick={(): void => + setShowExpressSearchInstructions((value) => !value) + } /> {showInstructions && ( - setShowExpressSearchInstructions(false)} /> + setShowExpressSearchInstructions(false)} + /> )}
    setQuery(pendingQuery)}>
    diff --git a/specifyweb/frontend/js_src/lib/components/WbPlanView/navigator.ts b/specifyweb/frontend/js_src/lib/components/WbPlanView/navigator.ts index fca97e9c6be..fbc359e53b4 100644 --- a/specifyweb/frontend/js_src/lib/components/WbPlanView/navigator.ts +++ b/specifyweb/frontend/js_src/lib/components/WbPlanView/navigator.ts @@ -713,4 +713,4 @@ export function getMappingLineData({ : filtered.filter( ({ customSelectSubtype }) => customSelectSubtype !== 'tree' ); -} \ No newline at end of file +} diff --git a/specifyweb/frontend/js_src/lib/localization/common.ts b/specifyweb/frontend/js_src/lib/localization/common.ts index 6ad133cdc01..d75f8bb7f83 100644 --- a/specifyweb/frontend/js_src/lib/localization/common.ts +++ b/specifyweb/frontend/js_src/lib/localization/common.ts @@ -104,13 +104,16 @@ export const commonText = createDictionary({ 'hr-hr': 'Savjeti za pretraživanje', }, expressSearchInstructions: { - 'en-us': 'Separate multiple search terms with spaces, use % anywhere, * at the beginning or end, and wrap terms in quotes for exact multi-word matches.', + 'en-us': + 'Separate multiple search terms with spaces, use % anywhere, * at the beginning or end, and wrap terms in quotes for exact multi-word matches.', }, expressSearchDateFormats: { - 'en-us': 'Dates can be searched using either the YYYY-MM-DD or MM/DD/YYYY format.', + 'en-us': + 'Dates can be searched using either the YYYY-MM-DD or MM/DD/YYYY format.', }, expressSearchPhraseExample: { - 'en-us': 'To search a term with spaces, wrap the phrase in quotes, for example "Clinton Lake".', + 'en-us': + 'To search a term with spaces, wrap the phrase in quotes, for example "Clinton Lake".', }, apply: { 'en-us': 'Apply', diff --git a/specifyweb/frontend/js_src/lib/localization/utils/config.ts b/specifyweb/frontend/js_src/lib/localization/utils/config.ts index e358f61952f..b70b574e01a 100644 --- a/specifyweb/frontend/js_src/lib/localization/utils/config.ts +++ b/specifyweb/frontend/js_src/lib/localization/utils/config.ts @@ -24,7 +24,7 @@ export const languageCodeMapper = { 'de-ch': 'de_CH', 'pt-br': 'pt_BR', 'hr-hr': 'hr', - 'nb': 'nb_NO' + nb: 'nb_NO', } as const; export const languages = Object.keys(languageCodeMapper); diff --git a/specifyweb/frontend/js_src/lib/utils/schemaVisibility.ts b/specifyweb/frontend/js_src/lib/utils/schemaVisibility.ts index fe41c0b752e..9c483b4168b 100644 --- a/specifyweb/frontend/js_src/lib/utils/schemaVisibility.ts +++ b/specifyweb/frontend/js_src/lib/utils/schemaVisibility.ts @@ -5,4 +5,4 @@ export function isSchemaFieldVisible( defaultFieldName?: string ): boolean { return showHiddenFields || !isHidden || fieldName === defaultFieldName; -} \ No newline at end of file +}