Files
vue3js-app-proposal-for-sdk…/static/components/PaneSubObjects.js
c0dev0id 89f46e7579 BA pane: group bars by P?L? key, render as inline chips
Bars in the BA sub-objects pane are now visually grouped by the
P\d+L\d+ fragment extracted from their opaque IDs (e.g. P1L1, P2L3).
Each group renders as a row of compact inline-block chips; groups are
separated by a line break. Fallback: if an ID contains no P?L?
pattern, trailing digits are stripped instead, yielding singleton rows.

The grouping is a display-only heuristic — no semantic meaning is
derived from the ID. Chips are clickable, highlight when focused.
2026-06-30 12:06:05 +02:00

75 lines
3.0 KiB
JavaScript

import { h } from 'vue';
import { ObjectShort } from './ObjectShort.js';
import { getKindGroups } from '../subobject-kinds.js';
// Extract the P?L? fragment as a visual grouping key.
// Falls back to stripping trailing digits if the pattern is absent,
// which yields singleton groups — not a crash, just no visual grouping.
function barGroupKey(id) {
const m = id.match(/P\d+L\d+/);
return m ? m[0] : id.replace(/\d+$/, '');
}
export const PaneSubObjects = {
props: ['store', 'kind', 'onFocusFO'],
setup(props) {
function focused() {
const fp = props.store.focusPath;
return fp.length ? fp[fp.length - 1] : props.store.scoreModel;
}
return () => {
const node = focused();
const groups = getKindGroups(node);
const group = props.kind
? groups.find(g => g.kind === props.kind)
: groups[0];
const items = group?.items ?? [];
if (!items.length) return h('div', null, h('em', null, 'No sub-objects'));
if (props.kind === 'bar') {
// Group bars by shared P?L? key; render each group as a row of inline chips.
const barGroups = [];
const seen = new Map();
for (const item of items) {
const key = barGroupKey(item.label);
if (!seen.has(key)) {
const g = { key, items: [] };
barGroups.push(g);
seen.set(key, g);
}
seen.get(key).items.push(item);
}
return h('div', { class: 'se-bar-groups' }, barGroups.map(g =>
h('div', { key: g.key, class: 'se-bar-group' },
g.items.map((item, idx) =>
h('button', {
key: idx,
class: ['se-bar-chip', props.store.focusPath.includes(item.node) ? 'focused' : null],
onClick: () => { props.store.pushFocus(item.node); props.onFocusFO?.(); },
}, item.label)
)
)
));
}
return h('div', null,
h('ul', { class: 'se-object-list' }, items.map((item, idx) =>
h(ObjectShort, {
key: idx,
label: item.label,
typeTag: item.kind,
focused: props.store.focusPath.includes(item.node),
hasChildren: item.hasChildren,
readOnly: item.readOnly ?? false,
onFocus: () => { props.store.pushFocus(item.node); props.onFocusFO?.(); },
onDrillDown: () => { props.store.pushFocus(item.node); props.onFocusFO?.(); },
})
))
);
};
},
};