Skip to content

feat(trees): add biostrat filter to chronostrat#8257

Draft
grantfitzsimmons wants to merge 14 commits into
issue-6049from
issue-8256
Draft

feat(trees): add biostrat filter to chronostrat#8257
grantfitzsimmons wants to merge 14 commits into
issue-6049from
issue-8256

Conversation

@grantfitzsimmons

@grantfitzsimmons grantfitzsimmons commented Jul 4, 2026

Copy link
Copy Markdown
Member

Fixes #8256

This PR introduces a new filter for Geologic Time Period tree views and searches, allowing users to display all nodes, only chronostratigraphic nodes, or only biostratigraphic nodes.

Building on the biostrat filter dropdown and backend support from the base branch (issue-6049), this PR adds:

  • BioStrat query combo box filtering: The BioStrat field on PaleoContext forms now only shows GeologicTimePeriod nodes marked as biostratigraphy (isBioStrat = TRUE). Previously this combo box displayed all nodes because Specify 7 builds its own queries instead of using the custom SQL from the TypeSearch definition (which already contained the isBioStrat = 1 filter since Specify 6). The ChronosStrat field continues to show all GeologicTimePeriod nodes.
chronostrat_qcbx_search biostrat_qcbx_search
  • Search dialog filtering: The magnifying glass (Search) button on the BioStrat combo box also only shows biostratigraphy entries.
  • Tree viewer search filtering: The search box in the GeologicTimePeriod tree viewer respects the active biostrat filter dropdown selection (All Nodes / Biostratigraphy / Chronostratigraphy), matching the filtered tree rows.
image chronostrat biostrat allnodes

Checklist

  • Self-review the PR after opening it to make sure the changes look good and self-explanatory (or properly documented)
  • Add relevant issue to release milestone
  • Add pr to documentation list
  • Add automated tests
  • Add a reverse migration if a migration is present in the PR

Testing instructions

  • Open a PaleoContext form in any paleo/geo discipline (e.g., Invert Paleo, Vert Paleo, Geology).

  • In the BioStrat field (QueryComboBox, which will not be present by default), verify that only GeologicTimePeriod nodes with isBioStrat = TRUE appear in the results.

     			<cell type="label" labelfor="biostrat"/>
     			<cell type="field" id="biostrat" name="bioStrat" uitype="querycbx" isrequired="false"/>
  • Click the magnifying glass (search) button on the BioStrat field. The search dialog should similarly only show results where isBioStrat = TRUE.

  • Verify the ChronosStrat field (same table, different typesearch) is unaffected and still shows all GeologicTimePeriod nodes.

  • Verify other QueryComboBox fields and tree search for other trees (Taxon, Geography, Storage, etc.) still work as expected.

  • Open the GeologicTimePeriod tree viewer. Toggle between All Nodes / Biostratigraphy / Chronostratigraphy. Verify the tree search box respects the selection.

Summary by CodeRabbit

  • New Features

    • Added a Biostratigraphy filter option in tree browsing and search, with support for viewing all nodes, chronostratigraphy-only nodes, or biostratigraphy-only nodes where applicable.
    • Updated tree search and row loading to respect the selected Biostratigraphy filter.
  • Bug Fixes

    • Corrected several labels from “BioStratigraphy” to “Biostratigraphy” for clearer, consistent wording.
  • Tests

    • Added coverage for the new Biostratigraphy filtering behavior in tree and query selection flows.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0d0c0640-d1f2-4c09-b9c1-04d5352941c9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-8256

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Triggered by 7d49186 on branch refs/heads/issue-8256

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
specifyweb/frontend/js_src/lib/components/QueryComboBox/index.tsx (1)

595-609: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add test coverage for the isBioStrat extraCondition mapping.

biostratConditions.test.ts only tests getQueryComboBoxConditions; the actual fieldName === 'isBioStrat' branch in this file's Search-button handler (which builds the SearchDialog extraFilters) is untested. Given this directly drives the BioStrat search-dialog filtering behavior called out in the PR objectives, a small unit/integration test would help lock in the mapping.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@specifyweb/frontend/js_src/lib/components/QueryComboBox/index.tsx` around
lines 595 - 609, Add test coverage for the `fieldName === 'isBioStrat'` branch
in `QueryComboBox` so the Search-button handler’s `SearchDialog` extraFilters
mapping is verified. Update or add a focused unit/integration test around
`QueryComboBox` that exercises the handler and asserts the built extraCondition
for `isBioStrat` matches the expected filter shape, similar to the existing
`biostratConditions.test.ts` coverage for `getQueryComboBoxConditions`. Use the
`QueryComboBox` Search-button path and `SearchDialog` extraFilters construction
as the key symbols to locate the logic.
specifyweb/frontend/js_src/lib/components/TreeView/__tests__/biostratFilter.test.ts (1)

14-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test duplicates filter logic instead of exercising the actual Search.tsx implementation.

filterBio/filterChrono/filterAll are hand-written re-implementations of the predicates inline in Search.tsx's .filter(...) callback (Lines 97-108 there), rather than imports of an exported function. If the production filtering logic in Search.tsx changes or regresses, this test suite won't detect it since it never calls the real code path.

Consider extracting the predicate into a small exported helper (e.g., getBiostratPredicate(tableName, biostratFilter)) in Search.tsx, then importing and testing that directly here for real regression coverage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@specifyweb/frontend/js_src/lib/components/TreeView/__tests__/biostratFilter.test.ts`
around lines 14 - 36, The test file is re-implementing the biostrat filtering
logic instead of validating the real `Search.tsx` behavior. Extract the
`.filter(...)` predicate from `Search.tsx` into a small exported helper such as
`getBiostratPredicate` (or equivalent), then update `biostratFilter.test.ts` to
import and assert that helper directly so the test covers the production code
path and catches regressions.
specifyweb/backend/trees/views.py (1)

176-260: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding dedicated unit tests for the new biostrat filtering branch.

The only test coverage change (test_trees.py) exercises get_tree_rows with biostrat='all'; no test verifies the 'bio'/'chrono' SQL filtering paths or the root-exception behavior discussed above. Given this logic directly implements the PR's core requirement, dedicated tests would guard against regressions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@specifyweb/backend/trees/views.py` around lines 176 - 260, Add focused unit
tests for the biostrat branch in get_tree_rows so the new SQL filters are
covered. Update test_trees.py to exercise geologictimeperiod with biostrat set
to bio and chrono, and assert the generated rows respect the root exception plus
isBioStrat true/false/null behavior. Use get_tree_rows and the existing tree
query setup to verify the filtering paths directly, not just the biostrat='all'
case.
specifyweb/frontend/js_src/lib/components/TreeView/index.tsx (1)

427-439: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add aria-label/title to the new biostrat Select, matching sibling selects.

The treePicker Select above (Line 306) sets both aria-label and title; this new biostrat filter Select sets neither, so screen-reader users get no context for the control's purpose beyond the currently selected option text.

♻️ Proposed fix
         {tableName === 'GeologicTimePeriod' && (
           <Select
+            aria-label={treeText.biostratAll()}
             className="w-max"
+            title={treeText.biostratAll()}
             value={biostratFilter}

(Swap in a more purpose-specific label string if one is added to the dictionary, e.g. a dedicated "Filter by" key.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@specifyweb/frontend/js_src/lib/components/TreeView/index.tsx` around lines
427 - 439, Add accessibility labeling to the new biostrat filter Select in
TreeView so it matches the sibling treePicker control. Update the
GeologicTimePeriod Select to include both aria-label and title attributes with a
clear description of the filter’s purpose, using the same pattern as the
existing Select above; if a dedicated copy string exists or is added to
treeText, use that for the label.
specifyweb/backend/trees/tests/test_trees.py (1)

340-460: 🎯 Functional Correctness | 🔵 Trivial

Missing backend test coverage for actual bio/chrono filtering.

Both updated calls only pass the neutral 'all' value on a Geography tree, so the actual isBioStrat SQL filtering logic (the core server-side objective of this PR) isn't exercised here. Consider adding a test against a geologictimeperiod tree asserting that 'bio' returns only isBioStrat=TRUE rows and 'chrono' returns FALSE/NULL rows.

[medium_effort_and_high_reward]

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@specifyweb/backend/trees/tests/test_trees.py` around lines 340 - 460, The
updated test coverage in get_tree_rows only exercises the neutral 'all' branch
on a Geography tree, so the actual isBioStrat filtering paths are still
untested. Add a test case using a geologictimeperiod tree and the get_tree_rows
helper that verifies 'bio' returns only rows with isBioStrat enabled, while
'chrono' returns only rows with isBioStrat disabled or unset; use the existing
get_tree_rows calls and assertions as the place to extend coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@specifyweb/backend/trees/views.py`:
- Around line 245-260: The child_count aggregate in the tree query is not
respecting the active biostrat filter, so expand chevrons can appear for rows
that will return no children. Update the query in the tree view logic around the
node/child joins and group_by/order_by so the same bio/chrono predicate applied
to node rows is also applied to the child join condition, ensuring the counted
children match what getRows will actually return for expand actions.

---

Nitpick comments:
In `@specifyweb/backend/trees/tests/test_trees.py`:
- Around line 340-460: The updated test coverage in get_tree_rows only exercises
the neutral 'all' branch on a Geography tree, so the actual isBioStrat filtering
paths are still untested. Add a test case using a geologictimeperiod tree and
the get_tree_rows helper that verifies 'bio' returns only rows with isBioStrat
enabled, while 'chrono' returns only rows with isBioStrat disabled or unset; use
the existing get_tree_rows calls and assertions as the place to extend coverage.

In `@specifyweb/backend/trees/views.py`:
- Around line 176-260: Add focused unit tests for the biostrat branch in
get_tree_rows so the new SQL filters are covered. Update test_trees.py to
exercise geologictimeperiod with biostrat set to bio and chrono, and assert the
generated rows respect the root exception plus isBioStrat true/false/null
behavior. Use get_tree_rows and the existing tree query setup to verify the
filtering paths directly, not just the biostrat='all' case.

In `@specifyweb/frontend/js_src/lib/components/QueryComboBox/index.tsx`:
- Around line 595-609: Add test coverage for the `fieldName === 'isBioStrat'`
branch in `QueryComboBox` so the Search-button handler’s `SearchDialog`
extraFilters mapping is verified. Update or add a focused unit/integration test
around `QueryComboBox` that exercises the handler and asserts the built
extraCondition for `isBioStrat` matches the expected filter shape, similar to
the existing `biostratConditions.test.ts` coverage for
`getQueryComboBoxConditions`. Use the `QueryComboBox` Search-button path and
`SearchDialog` extraFilters construction as the key symbols to locate the logic.

In
`@specifyweb/frontend/js_src/lib/components/TreeView/__tests__/biostratFilter.test.ts`:
- Around line 14-36: The test file is re-implementing the biostrat filtering
logic instead of validating the real `Search.tsx` behavior. Extract the
`.filter(...)` predicate from `Search.tsx` into a small exported helper such as
`getBiostratPredicate` (or equivalent), then update `biostratFilter.test.ts` to
import and assert that helper directly so the test covers the production code
path and catches regressions.

In `@specifyweb/frontend/js_src/lib/components/TreeView/index.tsx`:
- Around line 427-439: Add accessibility labeling to the new biostrat filter
Select in TreeView so it matches the sibling treePicker control. Update the
GeologicTimePeriod Select to include both aria-label and title attributes with a
clear description of the filter’s purpose, using the same pattern as the
existing Select above; if a dedicated copy string exists or is added to
treeText, use that for the label.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3bc6ed65-504e-4f8f-aa82-70783040873c

📥 Commits

Reviewing files that changed from the base of the PR and between 137f7a5 and 7d49186.

📒 Files selected for processing (15)
  • config/common/schema_localization_en.json
  • specifyweb/backend/context/data/schemalocalization.json
  • specifyweb/backend/trees/tests/test_trees.py
  • specifyweb/backend/trees/views.py
  • specifyweb/frontend/js_src/lib/components/QueryComboBox/__tests__/biostratConditions.test.ts
  • specifyweb/frontend/js_src/lib/components/QueryComboBox/helpers.ts
  • specifyweb/frontend/js_src/lib/components/QueryComboBox/index.tsx
  • specifyweb/frontend/js_src/lib/components/TreeView/Row.tsx
  • specifyweb/frontend/js_src/lib/components/TreeView/Search.tsx
  • specifyweb/frontend/js_src/lib/components/TreeView/__tests__/biostratFilter.test.ts
  • specifyweb/frontend/js_src/lib/components/TreeView/index.tsx
  • specifyweb/frontend/js_src/lib/localization/tree.ts
  • specifyweb/frontend/js_src/lib/tests/ajax/static/context/schema_localization.json/lang=en.json
  • specifyweb/frontend/js_src/lib/utils/cache/definitions.ts
  • specifyweb/specify/fixtures/empty_db.json

Comment thread specifyweb/backend/trees/views.py
@github-project-automation github-project-automation Bot moved this from 📋Back Log to Dev Attention Needed in General Tester Board Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Dev Attention Needed

Development

Successfully merging this pull request may close these issues.

1 participant