74 lines
2.9 KiB
JavaScript
74 lines
2.9 KiB
JavaScript
import { h } from 'vue';
|
|
import { ObjectShort } from './ObjectShort.js';
|
|
import { getKindGroups } from '../subobject-kinds.js';
|
|
|
|
// Strip the final maximal run of same-class characters (all-digits or all-non-digits)
|
|
// from the ID tail. Everything before that run is the group key.
|
|
function barGroupKey(id) {
|
|
const m = id.match(/(\d+|\D+)$/);
|
|
return m ? id.slice(0, m.index) : id;
|
|
}
|
|
|
|
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?.(); },
|
|
})
|
|
))
|
|
);
|
|
};
|
|
},
|
|
};
|