Skip to content
24 changes: 6 additions & 18 deletions QualityControl/public/object/ObjectTree.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,31 +56,19 @@ export default class ObjectTree extends Observable {
}

/**
* Open all or close all nodes of the tree
* @returns {undefined}
*/
toggleAll() {
this.open ? this.closeAll() : this.openAll();
}

/**
* Open all nodes of the tree
* @returns {undefined}
* Close all nodes of the tree
*/
openAll() {
this.open = true;
this.children.forEach((child) => child.openAll());
closeAll() {
this._closeAllRecursive();
this.notify();
}

/**
* Close all nodes of the tree
* @returns {undefined}
* Recursively close all nodes without notifying.
*/
closeAll() {
_closeAllRecursive() {
this.open = false;
this.children.forEach((child) => child.closeAll());
this.notify();
this.children.forEach((child) => child._closeAllRecursive());
}

/**
Expand Down
113 changes: 59 additions & 54 deletions QualityControl/public/object/objectTreePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ const treeRows = (model) => !model.object.tree ?

model.object.tree.children.length === 0
? h('.w-100.text-center', 'No objects found')
: model.object.tree.children.map((children) => treeRow(model, children, 0));
: model.object.tree.children.map((children) => treeRow(model, children));

/**
* Shows a line <tr> of object represented by parent node `tree`, also shows
Expand All @@ -190,68 +190,73 @@ const treeRows = (model) => !model.object.tree ?
* @param {Model} model - root model of the application
* @param {ObjectTree} tree - data-structure containing an object per node
* @param {number} level - used for indentation within recursive call of treeRow
* @returns {vnode} - virtual node element
* @returns {vnode[]} - virtual node element
*/
function treeRow(model, tree, level) {
const padding = `${level}em`;
const levelDeeper = level + 1;
const children = tree.open ? tree.children.map((children) => treeRow(model, children, levelDeeper)) : [];
const path = tree.name;
const className = tree.object && tree.object === model.object.selected ? 'table-primary' : '';
function treeRow(model, tree, level = 0) {
const { pathString, open, children, object, name } = tree;

if (model.object.searchInput) {
return [];
} else {
if (tree.object && tree.children.length === 0) {
return [leafRow(path, () => model.object.select(tree.object), className, padding, tree.name)];
} else if (tree.object && tree.children.length > 0) {
return [
leafRow(path, () => model.object.select(tree.object), className, padding, tree.name),
branchRow(path, tree, padding),
children,
];
}
return [
branchRow(path, tree, padding),
children,
];
const childRow = open
? children.flatMap((children) => treeRow(model, children, level + 1))
: [];

const rows = [];

if (object) {
// Add a leaf row (final element; cannot be expanded further)
const className = object === model.object.selected ? 'table-primary' : '';
const leaf = treeRowElement(
pathString,
name,
() => model.object.select(object),
iconBarChart,
className,
{
paddingLeft: `${level + 0.25}em`,
},
);
rows.push(leaf);
}
if (children.length > 0) {
// Add a branch row (expandable / collapsible element)
const branch = treeRowElement(
pathString,
name,
() => tree.toggle(),
open ? iconCaretBottom : iconCaretRight,
'',
{
paddingLeft: `${level + 0.25}em`,
Copy link
Member

Choose a reason for hiding this comment

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

You do not need the padding at all now after the refactor.
You also removed the span element, so the default padding of 0.3 from table element is now applied.

Remove the paddingLeft from the call of treeRowElement both places and you will see it looks like before which is what we want

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As discussed, paddingLeft controls the tree indentation and is therefore required.

},
);
rows.push(branch);
}

return [...rows, ...childRow];
}

/**
* Creates a row containing specific visuals for leaf object and on selection
* it will plot the object with JSRoot
* @param {string} path - full name of the object
* @param {Action} selectItem - action for plotting the object
* @param {string} className - name of the row class
* @param {number} padding - space needed to be displayed so that leaf is within its parent
* @param {string} leafName - name of the object
* Creates a row containing specific visuals for either a branch or a leaf object
* and on click it will expand/collapse the branch or plot the leaf object with JSRoot
* @param {string} key - An unique identifier for this branch row element (table row)
* @param {string} name - The name of this tree object element
* @param {() => void} onclick - The action (callback) to perform upon clicking this branch row element (table row)
* @param {() => vnode} icon - Icon renderer for the row
* @param {string} className - Optional CSS class name(s) for the outer branch row element (table row)
* @param {object} styling - Optional CSS styling for the inner branch row element (table data)
* @returns {vnode} - virtual node element
*/
const leafRow = (path, selectItem, className, padding, leafName) =>
const treeRowElement = (key, name, onclick, icon, className = '', styling = {}) =>
h('tr.object-selectable', {
key: path, title: path, onclick: selectItem, class: className, id: path,
key,
id: key,
title: name,
Copy link
Member

Choose a reason for hiding this comment

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

Same here title vs name

onclick,
class: className,
}, [
h('td.highlight', [
h('span', { style: { paddingLeft: padding } }, iconBarChart()),
' ',
leafName,
]),
]);

/**
* Creates a row containing specific visuals for branch object and on selection
* it will open its children
* @param {string} path - full name of the object
* @param {ObjectTree} tree - current selected tree
* @param {number} padding - space needed to be displayed so that branch is within its parent
* @returns {vnode} - virtual node element
*/
const branchRow = (path, tree, padding) =>
h('tr.object-selectable', { key: path, title: path, onclick: () => tree.toggle() }, [
h('td.highlight', [
h('span', { style: { paddingLeft: padding } }, tree.open ? iconCaretBottom() : iconCaretRight()),
' ',
tree.name,
h('td.highlight.flex-row.items-center.g1', {
style: styling,
Copy link
Member

Choose a reason for hiding this comment

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

Given that you are not applying any chances, why not naming the variable style and use the short version { style }?

}, [
icon(),
name,
]),
]);
Loading