From e397e3725c4fcc41afdab5905c79bff65d3846ea Mon Sep 17 00:00:00 2001 From: alesan99 Date: Tue, 15 Jul 2025 09:33:08 -0500 Subject: [PATCH 01/24] Remove leading zeroes from query formatted COs if using separator --- specifyweb/stored_queries/format.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/specifyweb/stored_queries/format.py b/specifyweb/stored_queries/format.py index ffd6be20a8d..361a32e633a 100644 --- a/specifyweb/stored_queries/format.py +++ b/specifyweb/stored_queries/format.py @@ -194,6 +194,10 @@ def make_expr(self, new_expr = self.pseudo_sprintf(fieldNodeAttrib['format'], new_expr) if 'sep' in fieldNodeAttrib: + if specify_field.name == 'catalogNumber': + # Special Case: Leading zeroes are removed from catalog number if formatter has separator. + # See: https://github.com/specify/specify7/issues/7037 + new_expr = func.regexp_replace(new_expr, '^0+', '') new_expr = concat(fieldNodeAttrib['sep'], new_expr) return new_query, blank_nulls(new_expr) if do_blank_null else new_expr, formatter_field_spec From 20e1dbf97ff695538a86115317abad42c077c7b5 Mon Sep 17 00:00:00 2001 From: alesan99 Date: Tue, 15 Jul 2025 10:53:34 -0500 Subject: [PATCH 02/24] Redo fix; Restore original functionality --- specifyweb/stored_queries/format.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/specifyweb/stored_queries/format.py b/specifyweb/stored_queries/format.py index 361a32e633a..122c86e6f8f 100644 --- a/specifyweb/stored_queries/format.py +++ b/specifyweb/stored_queries/format.py @@ -188,16 +188,13 @@ def make_expr(self, else: new_query, table, model, specify_field = query.build_join( specify_model, orm_table, formatter_field_spec.join_path) - new_expr = getattr(table, specify_field.name) + new_expr = self._fieldformat(table, formatter_field_spec.get_field(), + getattr(table, specify_field.name)) if 'format' in fieldNodeAttrib: new_expr = self.pseudo_sprintf(fieldNodeAttrib['format'], new_expr) if 'sep' in fieldNodeAttrib: - if specify_field.name == 'catalogNumber': - # Special Case: Leading zeroes are removed from catalog number if formatter has separator. - # See: https://github.com/specify/specify7/issues/7037 - new_expr = func.regexp_replace(new_expr, '^0+', '') new_expr = concat(fieldNodeAttrib['sep'], new_expr) return new_query, blank_nulls(new_expr) if do_blank_null else new_expr, formatter_field_spec From 1b5d243f99d32f8db1266b16e5cd3b956e52d872 Mon Sep 17 00:00:00 2001 From: alesan99 Date: Wed, 16 Jul 2025 10:31:36 -0500 Subject: [PATCH 03/24] Fix batch edit crash --- specifyweb/stored_queries/format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specifyweb/stored_queries/format.py b/specifyweb/stored_queries/format.py index 122c86e6f8f..e96a0f66fc4 100644 --- a/specifyweb/stored_queries/format.py +++ b/specifyweb/stored_queries/format.py @@ -188,7 +188,7 @@ def make_expr(self, else: new_query, table, model, specify_field = query.build_join( specify_model, orm_table, formatter_field_spec.join_path) - new_expr = self._fieldformat(table, formatter_field_spec.get_field(), + new_expr = self._fieldformat(formatter_field_spec.table, formatter_field_spec.get_field(), getattr(table, specify_field.name)) if 'format' in fieldNodeAttrib: From 9412fd0fd990db9a70bb5f8930d6f89a58fbf949 Mon Sep 17 00:00:00 2001 From: alesan99 Date: Wed, 16 Jul 2025 13:52:46 -0500 Subject: [PATCH 04/24] Add exceptions for batch_edit --- specifyweb/stored_queries/batch_edit.py | 3 +++ specifyweb/stored_queries/execution.py | 12 ++++++++++++ specifyweb/stored_queries/format.py | 21 ++++++++++++++------- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/specifyweb/stored_queries/batch_edit.py b/specifyweb/stored_queries/batch_edit.py index 6363c7e11c1..93d2d711bb3 100644 --- a/specifyweb/stored_queries/batch_edit.py +++ b/specifyweb/stored_queries/batch_edit.py @@ -1140,6 +1140,9 @@ def run_batch_edit_query(props: BatchEditProps): recordsetid=recordsetid, formatauditobjs=False, format_picklist=True, + format_types=False, + numeric_catalog_number=False, + format_expr=False, ) to_many_planner = indexed.to_many_planner() diff --git a/specifyweb/stored_queries/execution.py b/specifyweb/stored_queries/execution.py index 0c9e16c80db..23a711391f8 100644 --- a/specifyweb/stored_queries/execution.py +++ b/specifyweb/stored_queries/execution.py @@ -64,6 +64,9 @@ class BuildQueryProps(NamedTuple): implicit_or: bool = True format_agent_type: bool = False format_picklist: bool = False + format_types: bool = True + numeric_catalog_number: bool = True + format_expr: bool = True def set_group_concat_max_len(connection): @@ -787,6 +790,9 @@ def execute( recordsetid=None, formatauditobjs=False, format_picklist=False, + format_types=True, + numeric_catalog_number=True, + format_expr=True, ): "Build and execute a query, returning the results as a data structure for json serialization" @@ -804,6 +810,9 @@ def execute( series=series, format_agent_type=format_agent_type, format_picklist=format_picklist, + format_types=format_types, + numeric_catalog_number=numeric_catalog_number, + format_expr=format_expr, ), ) @@ -920,6 +929,9 @@ def build_query( props.replace_nulls, format_agent_type=props.format_agent_type, format_picklist=props.format_picklist, + format_types=props.format_types, + numeric_catalog_number=props.numeric_catalog_number, + format_expr=props.format_expr, ), query=query_construct_query ) diff --git a/specifyweb/stored_queries/format.py b/specifyweb/stored_queries/format.py index e96a0f66fc4..2429d36e1b5 100644 --- a/specifyweb/stored_queries/format.py +++ b/specifyweb/stored_queries/format.py @@ -41,7 +41,7 @@ class ObjectFormatter: - def __init__(self, collection, user, replace_nulls, format_agent_type=False, format_picklist=False): + def __init__(self, collection, user, replace_nulls, format_agent_type=False, format_picklist=False, format_types=True, numeric_catalog_number=True, format_expr=True): formattersXML, _, __ = app_resource.get_app_resource(collection, user, 'DataObjFormatters') self.formattersDom = ElementTree.fromstring(formattersXML) @@ -53,6 +53,11 @@ def __init__(self, collection, user, replace_nulls, format_agent_type=False, for self.aggregator_count = 0 self.format_agent_type = format_agent_type self.format_picklist = format_picklist + self.format_types = format_types + self.numeric_catalog_number = numeric_catalog_number + # format_expr determines if make_expr should call _fieldformat. + # Batch edit expects it to be false to correctly handle some edge cases. + self.format_expr = format_expr def getFormatterDef(self, specify_model: Table, formatter_name) -> Optional[Element]: def lookup(attr: str, val: str) -> Optional[Element]: @@ -188,8 +193,10 @@ def make_expr(self, else: new_query, table, model, specify_field = query.build_join( specify_model, orm_table, formatter_field_spec.join_path) - new_expr = self._fieldformat(formatter_field_spec.table, formatter_field_spec.get_field(), - getattr(table, specify_field.name)) + new_expr = getattr(table, specify_field.name) + + if self.format_expr: + new_expr = self._fieldformat(formatter_field_spec.table, formatter_field_spec.get_field(), new_expr) if 'format' in fieldNodeAttrib: new_expr = self.pseudo_sprintf(fieldNodeAttrib['format'], new_expr) @@ -386,13 +393,13 @@ def _fieldformat(self, table: Table, specify_field: Field, return blank_nulls(_case) if self.replace_nulls else _case - if specify_field.type == "java.lang.Boolean": + if self.format_types and specify_field.type == "java.lang.Boolean": return field != 0 - if specify_field.type in ("java.lang.Integer", "java.lang.Short"): + if self.format_types and specify_field.type in ("java.lang.Integer", "java.lang.Short"): return field - if specify_field is CollectionObject_model.get_field('catalogNumber') \ + if self.numeric_catalog_number and specify_field is CollectionObject_model.get_field('catalogNumber') \ and all_numeric_catnum_formats(self.collection): # While the frontend can format the catalogNumber if needed, # processes like reports, labels, and query exports generally @@ -400,7 +407,7 @@ def _fieldformat(self, table: Table, specify_field: Field, # See https://github.com/specify/specify7/issues/6464 return cast(field, types.Numeric(65)) - if specify_field.type == 'json' and isinstance(field.comparator.type, types.JSON): + if self.format_types and specify_field.type == 'json' and isinstance(field.comparator.type, types.JSON): return cast(field, types.Text) return field From 02f670f7716faf65d141d9fede57ee6684d7fdb8 Mon Sep 17 00:00:00 2001 From: alesan99 Date: Mon, 4 Aug 2025 19:46:36 +0000 Subject: [PATCH 05/24] Lint code with ESLint and Prettier Triggered by 8fa66d8e38500f138b96e969c6c178c199127023 on branch refs/heads/issue-7037 --- .../lib/components/AppResources/Aside.tsx | 29 +- .../lib/components/AppResources/Tabs.tsx | 56 +- .../AppResources/__tests__/Tabs.test.tsx | 60 +- .../__tests__/AttachmentCell.test.tsx | 258 +- .../js_src/lib/localization/attachments.ts | 1054 +++--- .../js_src/lib/localization/backEnd.ts | 790 ++-- .../js_src/lib/localization/batchEdit.ts | 704 ++-- .../js_src/lib/localization/common.ts | 1282 +++---- .../js_src/lib/localization/development.ts | 44 +- .../frontend/js_src/lib/localization/forms.ts | 1968 +++++----- .../js_src/lib/localization/header.ts | 688 ++-- .../js_src/lib/localization/interactions.ts | 624 ++-- .../js_src/lib/localization/locality.ts | 908 ++--- .../frontend/js_src/lib/localization/main.ts | 424 +-- .../js_src/lib/localization/merging.ts | 382 +- .../js_src/lib/localization/notifications.ts | 200 +- .../js_src/lib/localization/preferences.ts | 3260 ++++++++--------- .../frontend/js_src/lib/localization/query.ts | 1500 ++++---- .../js_src/lib/localization/report.ts | 274 +- .../js_src/lib/localization/resources.ts | 1456 ++++---- .../js_src/lib/localization/schema.ts | 842 ++--- .../js_src/lib/localization/specifyNetwork.ts | 300 +- .../frontend/js_src/lib/localization/tree.ts | 1040 +++--- .../frontend/js_src/lib/localization/user.ts | 1710 ++++----- .../js_src/lib/localization/wbPlan.ts | 1038 +++--- .../js_src/lib/localization/welcome.ts | 310 +- .../js_src/lib/localization/workbench.ts | 2398 ++++++------ 27 files changed, 11804 insertions(+), 11795 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/AppResources/Aside.tsx b/specifyweb/frontend/js_src/lib/components/AppResources/Aside.tsx index 28188fe280f..371c50ab03f 100644 --- a/specifyweb/frontend/js_src/lib/components/AppResources/Aside.tsx +++ b/specifyweb/frontend/js_src/lib/components/AppResources/Aside.tsx @@ -71,7 +71,8 @@ export function AppResourcesAside({