chore: create new details page BED-6837
Description
The foundation for a redesigned details page is created. PZ path navigation is consolidated.
Motivation and Context
Resolves BED-6837
Why is this change required? What problem does it solve?
How Has This Been Tested?
There are no material changes until the page gets swapped.
Screenshots (optional):
Types of changes
- Chore (a change that does not modify the application functionality)
Checklist:
- [x] I have met the contributing prerequisites
- Assigned myself to this PR
- Added the appropriate labels
- Associated an issue: https://github.com/SpecterOps/BloodHound/issues/672
- Read the Contributing guide: https://github.com/SpecterOps/BloodHound/wiki/Contributing
- [x] I have ensured that related documentation is up-to-date
- Open API docs
- Code comments (GoDocs / JSDocs)
- [x] I have followed proper test practices
- Added/updated tests to cover my changes
- All new and existing tests passed
Summary by CodeRabbit
- Refactor
- Routes unified on a "rules" segment and navigation now uses centralized dynamic link helpers.
- New Features
- New Details view variant added.
- "Create Rule" becomes a dynamic link when a tag is selected; shown as plain text otherwise.
- Breadcrumbs, create/edit flows and member navigation use the new link helpers.
- New Options
- SearchBar adds an optional showTags toggle.
- UI wording
- Terminology changed from "selector" to "rule" across lists, forms, buttons and labels.
- Tests
- Tests and mocks updated to use rule-based paths and extended tag test data.
βοΈ Tip: You can customize this high-level summary in your review settings.
[!NOTE] Currently processing new changes in this PR. This may take a few minutes, please wait...
π₯ Commits
Reviewing files that changed from the base of the PR and between 4b0748f76df1bf27b691960953fd470f506efc66 and 7823dd5cfce3ef90aae90f91e7f8cba8e7c48d17.
π Files selected for processing (47)
cmd/ui/src/views/PrivilegeZones/InfoHeader.tsx(2 hunks)packages/javascript/bh-shared-ui/src/components/EntityInfo/EntityInfoDataTableList.test.tsx(2 hunks)packages/javascript/bh-shared-ui/src/hooks/useAssetGroupTags/useAssetGroupTags.test.tsx(2 hunks)packages/javascript/bh-shared-ui/src/hooks/useAssetGroupTags/useAssetGroupTags.tsx(9 hunks)packages/javascript/bh-shared-ui/src/hooks/usePZParams/usePZPathParams.tsx(3 hunks)packages/javascript/bh-shared-ui/src/mocks/factories/privilegeZones.ts(5 hunks)packages/javascript/bh-shared-ui/src/mocks/handlers/zoneHandlers.ts(1 hunks)packages/javascript/bh-shared-ui/src/routes/index.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/Explore/ExploreSearch/SavedQueries/TagToZoneLabelDialog.tsx(3 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Cypher/Cypher.test.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Cypher/Cypher.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/Details.test.tsx(5 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/Details.tsx(7 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/DynamicDetails.test.tsx(4 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/DynamicDetails.tsx(3 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/EntityRulesInformation.tsx(5 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/NewDetails.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/RulesList.test.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/RulesList.tsx(6 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/SearchBar.tsx(3 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/SelectedDetails.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/SelectedHighlight.test.tsx(4 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/SelectedHighlight.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/index.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/utils.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/PZEditButton/EditInfoPanelButton.test.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/PZEditButton/PZEditButton.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/PrivilegeZones.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/PrivilegeZonesContext.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/BasicInfo.tsx(10 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/DeleteRuleButton/DeleteRuleButton.test.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/DeleteRuleButton/DeleteRuleButton.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/DeleteRuleButton/index.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/ObjectSelect.test.tsx(3 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/ObjectSelect.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/RuleForm.test.tsx(13 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/RuleForm.tsx(9 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/RuleFormContext.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/SeedSelection.tsx(4 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/index.tsx(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/types.ts(1 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/Save.test.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/Save.tsx(3 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/TagForm/TagForm.tsx(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/TagForm/utils.ts(2 hunks)packages/javascript/bh-shared-ui/src/views/PrivilegeZones/index.tsx(1 hunks)packages/javascript/js-client-library/src/client.ts(3 hunks)_______________________________________________ < Dyson of code review: I suck up all the bugs. > ----------------------------------------------- \ \ \ \ /\ ( ) .( o ).
[!TIP]
You can validate your CodeRabbit configuration file in your editor.
If your editor has YAML language server, you can enable auto-completion and validation by adding
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.jsonat the top of your CodeRabbit configuration file.
Walkthrough
Renames "selector" concepts to "rule" across the Privilege Zones UI and API surface, replaces manual path construction with link helper functions from usePZPathParams, and updates routing constants, hooks, components, mocks, and tests to the rule-centric naming and navigation helpers.
Changes
| Cohort / File(s) | Summary |
|---|---|
Route constants & path helpers packages/javascript/bh-shared-ui/src/routes/index.tsx |
selectorsPath β rulesPath; many route constants renamed from *_SELECTOR_* β *_RULE_* (paths still use selectors segment but identifiers moved to ruleId). |
Path params hook packages/javascript/bh-shared-ui/src/hooks/usePZParams/usePZPathParams.tsx |
Replaced selectorId with ruleId; extended return shape to expose link helpers (e.g., ruleCreateLink, ruleEditLink, tagDetailsLink, ruleDetailsLink, objectDetailsLink, etc.) and page-type flags. |
Client API & query hooks packages/javascript/js-client-library/src/client.ts, packages/javascript/bh-shared-ui/src/hooks/useAssetGroupTags/useAssetGroupTags.tsx |
Parameter and API method renames from selectorId β ruleId; hook and helper renames: selectors β rules (getAssetGroupTagSelectors β getAssetGroupTagRules, useSelectorsInfiniteQuery β useRulesInfiniteQuery, useSelectorMembersInfiniteQuery β useRuleMembersInfiniteQuery, create/patch/deleteSelector β create/patch/deleteRule). |
Details & lists (components + tests) packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/* (e.g., Details.tsx, SelectedDetails.tsx, DynamicDetails.tsx, SelectedHighlight.tsx, RulesList.tsx, RulesList.test.tsx, RulesList.*, Details.test.tsx, SelectedHighlight.test.tsx, DynamicDetails.test.tsx) |
Replaced selector-oriented queries/components with rule equivalents; SelectorsList β RulesList, SelectorDetails β RuleDetails; selectorId β ruleId usage; updated tests and data-testids to rules naming. |
Entity information & tables packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/EntityRulesInformation.tsx, components/EntityInfo/EntityInfoDataTableList.test.tsx |
EntitySelectorsInformation β EntityRulesInformation; navigation switched to ruleDetailsLink / ruleEditLink; underlying data mapping renamed to rule variables. |
Save / Form refactor (SelectorForm β RuleForm) packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/* (e.g., RuleForm.tsx, RuleFormContext.tsx, types.ts, BasicInfo.tsx, SeedSelection.tsx, DeleteRuleButton/*, tests) |
Comprehensive rename and wiring: SelectorForm β RuleForm, SelectorFormInputs β RuleFormInputs, context and action types renamed, hooks switched to create/patch/deleteRule, navigation uses new link helpers; tests updated to RuleForm. |
Save page & TagForm utils packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/Save.tsx, TagForm/TagForm.tsx, TagForm/utils.ts |
Save UI now imports RuleForm; navigation and breadcrumbs use tagDetailsLink, tagEditLink, ruleCreateLink; added guard in TagForm update handler and adjusted handleUpdateNavigate signature to accept tagId. |
Edit button & breadcrumbs packages/javascript/bh-shared-ui/src/views/PrivilegeZones/PZEditButton/PZEditButton.tsx |
TitleSuffix enum: Selector β Rule; getSavePath / suffix functions now accept ruleId and use rulesPath; usages updated to route via ruleId. |
InfoHeader & miscellaneous navigations cmd/ui/src/views/PrivilegeZones/InfoHeader.tsx, Explore/ExploreSearch/SavedQueries/TagToZoneLabelDialog.tsx |
Replaced manual path construction with ruleCreateLink (usePZPathParams); conditional rendering of create-link now uses ruleCreateLink(tagId) when tagId is present. |
Utilities & type guards packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/utils.tsx |
isSelector β isRule; getSelectorSeedType β getRuleSeedType with parameter renames. |
Mocks & handlers packages/javascript/bh-shared-ui/src/mocks/factories/privilegeZones.ts, packages/javascript/bh-shared-ui/src/mocks/handlers/zoneHandlers.ts |
Test/mock factories and handlers renamed from selector* β rule* (createSelector β createRule, createSelectors β createRules, etc.) and corresponding ID fields renamed ruleId. |
Context, routing and index exports packages/javascript/bh-shared-ui/src/views/PrivilegeZones/{PrivilegeZones.tsx,PrivilegeZonesContext.tsx,index.tsx}, Details/index.tsx |
Route constant imports updated to *_RULE_*; re-exports changed from EntitySelectorsInformation β EntityRulesInformation; NewDetails added (commented export kept in index). |
Cypher & RuleForm contexts packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Cypher/{Cypher.tsx,Cypher.test.tsx} |
Switched context from SelectorFormContext β RuleFormContext and updated tests/providers accordingly. |
New component packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/NewDetails.tsx |
Added a new Details component that resolves active tagId via useHighestPrivilegeTagId/usePZPathParams and renders a two-column responsive layout with InfoHeader, search, lists, and SelectedDetails. |
| Tests across codebase multiple *.test.tsx files under views/PrivilegeZones and hooks |
Updated mocks, parameter names, API endpoint patterns, data-testids and expectations to reflect selectorβrule renames and new link helper usage. |
Estimated code review effort
π― 4 (Complex) | β±οΈ ~70 minutes
Areas requiring extra attention:
- packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Save/RuleForm/RuleForm.tsx β reducer, action types, create/patch/delete flows and navigation.
- packages/javascript/bh-shared-ui/src/hooks/usePZParams/usePZPathParams.tsx β correctness of generated link helpers and edge-case handling (missing tagId / type).
- packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/Details.tsx β multiple query replacements, getEditButtonState signature change, and guard logic.
- packages/javascript/bh-shared-ui/src/views/PrivilegeZones/Details/EntityRulesInformation.tsx β navigation callbacks updated to use link helpers.
- tests updating API endpoint patterns and mocked keys (ensure all privilegeZonesKeys.selectorDetail β ruleDetail changes are consistent).
Possibly related PRs
- SpecterOps/BloodHound#2012 β closely related refactor altering PZ path params and Details navigation helper usage.
- SpecterOps/BloodHound#2103 β modifies usePZPathParams return shape and link helpers; strongly related to the hook changes here.
- SpecterOps/BloodHound#1851 β earlier routing/path-params refactor that this PR continues; overlaps in route constant renames.
Suggested reviewers
- Holocraft
- specter-flq
Poem
π I hopped through code, changed "selector" to "rule",
I stitched links together, tidy and cool.
Breadcrumbs now point where helpers belong,
Tests all updated β the refactor's a song.
Hop, hop, hooray β the paths all move on!
Pre-merge checks and finishing touches
β Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | β Passed | The title 'chore: create new details page BED-6837' clearly describes the main changeβcreating a new details page as part of the BED-6837 ticket. |
| Description check | β Passed | The description follows the template with key sections completed: Description, Motivation/Context with ticket reference (BED-6837), testing approach, change type marked as Chore, and checklist items marked complete. However, the 'How Has This Been Tested?' section lacks substantive detail about specific tests or scenarios. |
| Docstring Coverage | β Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
Comment @coderabbitai help to get the list of available commands and usage tips.