Skip to content

Show label hierarchy paths in label previews#379

Open
apodacaduron wants to merge 14 commits into
mainfrom
label-path-improvements
Open

Show label hierarchy paths in label previews#379
apodacaduron wants to merge 14 commits into
mainfrom
label-path-improvements

Conversation

@apodacaduron

@apodacaduron apodacaduron commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Labels can be nested, but pickers and chips only showed the leaf title, so same-named or generic labels (e.g. "Other") under different parents were indistinguishable. This adds path-aware label display:

  • New LabelSearchField (extends SearchField) — labels-only autocomplete using the compact mode=2 payload, showing parent path as a subtitle and a collapsed path on selected chips when the leaf is ambiguous.
  • New LabelPath.js — path utils + LabelPathChip/LabelPathTrail/LabelPathList, replacing flat label chips on bulletin/incident/actor cards and profiles. RTL-aware.
  • Swapped search-fieldlabel-search-field everywhere labels/ver_labels are picked (bulletins, actors, incidents, review dialog, media import).

Note: card/profile views need a path field added to their serializers to actually show hierarchy — landing in a separate follow-up PR. Until then those views keep showing flat leaf chips.

Also: closes the incident drawer when editing an incident, to match bulletins/actors.

How to Test

  1. Create a nested label (e.g. parent "Weapons", child "Firearms").
  2. In a labels picker (bulletin/actor/incident), search for the child — confirm the dropdown shows it with the parent as a subtitle.
  3. Select two same-named/generic labels under different parents — confirm the chip shows the parent path, not just the leaf.
  4. Save and reopen the entity — confirm labels persist.
  5. Switch UI to Arabic and repeat 2–3 — confirm path direction/order flips correctly.
  6. Open an incident from the list — confirm the edit drawer closes.
  7. Check console for errors on touched pages.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. 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: ea23f51e-4769-471b-8c22-284e329b5154

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 label-path-improvements

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.

@apodacaduron apodacaduron self-assigned this Jul 23, 2026
@apodacaduron apodacaduron changed the title Label path improvements Show label hierarchy paths in label pickers Jul 23, 2026
@apodacaduron
apodacaduron marked this pull request as ready for review July 23, 2026 16:11
@apodacaduron
apodacaduron requested a review from level09 as a code owner July 23, 2026 16:11
@apodacaduron apodacaduron changed the title Show label hierarchy paths in label pickers Show label hierarchy paths in label previews Jul 23, 2026

@level09 level09 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice work, the new picker and the path chips are a good direction. Two things break real pages, and one ordering note:

  1. The cards (bulletin / incident / actor profiles) are also used on the export dashboard, deduplication and import log pages. Those pages don't load LabelPath.js or register LabelPathList, so labels will show empty there.
  2. Same problem on the activity page with label-search-field (details inline).
  3. Merge order: the Arabic data (title_ar / path_ar in mode 2) comes from PR #369, so that one should go in first, then re-test Arabic here.

{{ label.title }}
</v-chip>
</div>
<label-path-list :labels="bulletin.labels"></label-path-list>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This card is also used on pages not touched by this PR (export dashboard, deduplication, import log). They don't register LabelPathList, so labels there render empty. Registering it inside the card itself (components: { LabelPathList }) protects every page, then those 3 pages just need the script tag.

app.component('ActivitySearchBox', ActivitySearchBox);

app.component('SearchField', SearchField);
app.component('LabelPathList', LabelPathList);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This page also renders the bulletin/actor/incident search boxes, which now use label-search-field, but it's not loaded or registered here, so the label filters on this page will be empty.

}
return window.LabelPathUtils.chipParts(item, this.selectedDuplicateLeaves);
},
debouncedSearch: debounce(function (search) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think you can delete this override and labelQueryParams: every caller already sends mode: 2, so a default value for the api prop is enough and the base SearchField does the rest.

return this.parentSegments(label, segments, 'ar');
},

parentSegments(label, segments = [], lang = this.primaryLang()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The backend path never includes the label itself, so this trimming never triggers on real data. Except one bad case: a child label with the same title as its parent (that's allowed) would lose its path. Safer to remove it.

const english = this.splitPath(label.path);
if (lang !== 'ar') return this.parentSegments(label, english, 'en');

const arabic = this.splitPath(label.path_ar || label.path_tr);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

title_tr / path_tr don't exist on labels (that's the lookups model), these fallbacks can go.

@@ -0,0 +1,343 @@
const LabelPathUtils = {
genericLeaves: new Set(['other', 'unknown', 'أخرى', 'آخر', 'غير معروف', 'غير معروفة']),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This word list will drift from real data ("misc", "N/A", other Arabic words...). The duplicate-leaf check already covers the ambiguous case, I'd drop the list.

>
<v-card-text class="pa-3">
<div class="text-overline font-weight-bold text-medium-emphasis mb-2">
LABEL PATH

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hardcoded English, same for "+N more" below. Should go through translations.

@apodacaduron
apodacaduron requested a review from level09 July 23, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants