From fe76ca4c2326fbbd04cd4d98187108c7a286b7c7 Mon Sep 17 00:00:00 2001 From: aditya1010-max Date: Mon, 2 Mar 2026 01:24:26 +0530 Subject: [PATCH 1/5] Add relation selection indicator --- modules/ui/sections/raw_membership_editor.js | 48 ++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/modules/ui/sections/raw_membership_editor.js b/modules/ui/sections/raw_membership_editor.js index 4efda067c26..d1e07152334 100644 --- a/modules/ui/sections/raw_membership_editor.js +++ b/modules/ui/sections/raw_membership_editor.js @@ -283,12 +283,43 @@ export function uiSectionRawMembershipEditor(context) { var graph = context.graph(); - function baseDisplayLabel(entity) { + //select entities + var selectedEntities = _entityIDs + .map(function(id) { + return graph.hasEntity(id); + }) + .filter(function(entity) { + return entity; + }); + + // Map relationID -> number of selected entities in that relation + var relationCounts = new Map(); + + selectedEntities.forEach(function(ent) { + graph.parentRelations(ent).forEach(function (rel) { + relationCounts.set(rel.id, (relationCounts.get(rel.id) || 0) + 1); + }); + }); + + function baseDisplayLabel(entity, flags) { + flags = flags || {}; + var matched = presetManager.match(entity, graph); var presetName = (matched && matched.name()) || t('inspector.relation'); var entityName = utilDisplayName(entity) || ''; - return selection => { + return function(selection) { + if (flags.isCommon) { + selection.append('span') + .attr('class', 'green') + .text('(Applied)'); + } else if (flags.isPartial) { + selection.append('span') + .attr('class', 'orange') + .text('(Partially Applied)'); + + } + selection .append('b') .text(presetName + ' '); @@ -310,6 +341,7 @@ export function uiSectionRawMembershipEditor(context) { result.push({ relation: explicitRelation, value: baseDisplayValue(explicitRelation) + ' ' + explicitRelation.id, + title: baseDisplayValue(explicitRelation), display: baseDisplayLabel(explicitRelation) }); } else { @@ -320,10 +352,20 @@ export function uiSectionRawMembershipEditor(context) { var value = baseDisplayValue(entity); if (q && (value + ' ' + entity.id).toLowerCase().indexOf(q.toLowerCase()) === -1) return; + var count = relationCounts.get(entity.id) || 0; + var flags = { + isCommon: count === selectedEntities.length, + isPartial: count > 0 && count < selectedEntities.length + }; + + result.push({ relation: entity, value, - display: baseDisplayLabel(entity) + display: baseDisplayLabel(entity, flags), + title: value, + isCommon: flags.isCommon, + isPartial: flags.isPartial }); }); From 3d8af606f81fd6119fbf7017c221f90b528b26bc Mon Sep 17 00:00:00 2001 From: aditya1010-max Date: Tue, 3 Mar 2026 16:31:28 +0530 Subject: [PATCH 2/5] Inline relation state logic and use const for new variables --- modules/ui/sections/raw_membership_editor.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/modules/ui/sections/raw_membership_editor.js b/modules/ui/sections/raw_membership_editor.js index d1e07152334..6fb442989f9 100644 --- a/modules/ui/sections/raw_membership_editor.js +++ b/modules/ui/sections/raw_membership_editor.js @@ -284,7 +284,7 @@ export function uiSectionRawMembershipEditor(context) { var graph = context.graph(); //select entities - var selectedEntities = _entityIDs + const selectedEntities = _entityIDs .map(function(id) { return graph.hasEntity(id); }) @@ -293,7 +293,7 @@ export function uiSectionRawMembershipEditor(context) { }); // Map relationID -> number of selected entities in that relation - var relationCounts = new Map(); + const relationCounts = new Map(); selectedEntities.forEach(function(ent) { graph.parentRelations(ent).forEach(function (rel) { @@ -352,20 +352,18 @@ export function uiSectionRawMembershipEditor(context) { var value = baseDisplayValue(entity); if (q && (value + ' ' + entity.id).toLowerCase().indexOf(q.toLowerCase()) === -1) return; - var count = relationCounts.get(entity.id) || 0; - var flags = { - isCommon: count === selectedEntities.length, - isPartial: count > 0 && count < selectedEntities.length - }; + const count = relationCounts.get(entity.id) || 0; + const isCommon = count === selectedEntities.length; + const isPartial = count > 0 && count < selectedEntities.length; result.push({ relation: entity, value, - display: baseDisplayLabel(entity, flags), + display: baseDisplayLabel(entity, { isCommon, isPartial }), title: value, - isCommon: flags.isCommon, - isPartial: flags.isPartial + isCommon, + isPartial }); }); From 5f8f7725a0ab4eca4a970376b22162cd9636de4b Mon Sep 17 00:00:00 2001 From: aditya1010-max Date: Tue, 3 Mar 2026 16:49:52 +0530 Subject: [PATCH 3/5] Replace inline relation state label with badge element --- modules/ui/sections/raw_membership_editor.js | 23 ++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/ui/sections/raw_membership_editor.js b/modules/ui/sections/raw_membership_editor.js index 6fb442989f9..a7e34ea05e4 100644 --- a/modules/ui/sections/raw_membership_editor.js +++ b/modules/ui/sections/raw_membership_editor.js @@ -309,17 +309,6 @@ export function uiSectionRawMembershipEditor(context) { var entityName = utilDisplayName(entity) || ''; return function(selection) { - if (flags.isCommon) { - selection.append('span') - .attr('class', 'green') - .text('(Applied)'); - } else if (flags.isPartial) { - selection.append('span') - .attr('class', 'orange') - .text('(Partially Applied)'); - - } - selection .append('b') .text(presetName + ' '); @@ -328,6 +317,18 @@ export function uiSectionRawMembershipEditor(context) { .classed('has-colour', entity.tags.colour && isColourValid(entity.tags.colour)) .style('border-color', entity.tags.colour) .text(entityName); + + if (flags.isCommon) { + selection.append('span') + .attr('class', 'relation-badge') + .text('Already Applied'); + } else if (flags.isPartial) { + selection.append('span') + .attr('class', 'relation-badge') + .text('Partially Applied'); + + } + }; } From 88f6be531869e0487fa5ddcb6289ff057d058197 Mon Sep 17 00:00:00 2001 From: aditya1010-max Date: Tue, 3 Mar 2026 16:53:59 +0530 Subject: [PATCH 4/5] Add styling for relation state badge --- css/80_app.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/css/80_app.css b/css/80_app.css index 7b50ddabe0b..90b9eb81c23 100644 --- a/css/80_app.css +++ b/css/80_app.css @@ -6087,3 +6087,16 @@ textarea:focus:dir(rtl)::-webkit-resizer { width: 100px; color: var(--link-color); } + +.relation-badge { + display: inline-block; + margin-left: 4px; + padding: 2px 6px; + font-size: 11px; + line-height: 1.4; + border-radius: 999px; + border: 1px solid #363e4d; + background-color: #1d2635; + color: #949caa; + font-weight: 500; +} From c513618c9adf7c356ee5bc52c61a3cfc6c91871b Mon Sep 17 00:00:00 2001 From: aditya1010-max Date: Thu, 5 Mar 2026 20:47:15 +0530 Subject: [PATCH 5/5] Guard relation state logic when no entities are selected --- modules/ui/sections/raw_membership_editor.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/ui/sections/raw_membership_editor.js b/modules/ui/sections/raw_membership_editor.js index a7e34ea05e4..268e3405730 100644 --- a/modules/ui/sections/raw_membership_editor.js +++ b/modules/ui/sections/raw_membership_editor.js @@ -354,9 +354,8 @@ export function uiSectionRawMembershipEditor(context) { if (q && (value + ' ' + entity.id).toLowerCase().indexOf(q.toLowerCase()) === -1) return; const count = relationCounts.get(entity.id) || 0; - const isCommon = count === selectedEntities.length; - const isPartial = count > 0 && count < selectedEntities.length; - + const isCommon = selectedEntities.length > 0 && count === selectedEntities.length; + const isPartial = selectedEntities.length > 0 && count > 0 && count < selectedEntities.length; result.push({ relation: entity,