Skip to content

Commit f553044

Browse files
authored
implement show parents only (focus mode) (#2655)
1 parent 170cd9f commit f553044

File tree

5 files changed

+97
-0
lines changed

5 files changed

+97
-0
lines changed

app/components/component-tree-toolbar.hbs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,18 @@
3434
@value={{@query}}
3535
data-test-filter-views
3636
/>
37+
38+
<Ui::ToolbarDivider />
39+
40+
{{#if @pinned}}
41+
<button
42+
class="{{if @showParentsOnly "active"}} toolbar-icon-button"
43+
type="button"
44+
title="toggle focus mode"
45+
data-test-toggle-focus
46+
{{on "click" @toggleParentsOnly}}
47+
>
48+
{{svg-jar "focus-point-round" width="16px" height="16px"}}
49+
</button>
50+
{{/if}}
3751
</div>

app/controllers/component-tree.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export default class ComponentTreeController extends Controller {
1919

2020
@tracked query = '';
2121
@tracked isInspecting = false;
22+
@tracked showParentsOnly = false;
2223
@tracked renderItems = [];
2324

2425
@tracked _pinned = undefined;
@@ -269,6 +270,10 @@ export default class ComponentTreeController extends Controller {
269270
@action arrowKeysTeardown() {
270271
document.removeEventListener('keydown', this.handleKeyDown);
271272
}
273+
274+
@action toggleParentsOnly() {
275+
this.showParentsOnly = !this.showParentsOnly;
276+
}
272277
}
273278

274279
function isInternalRenderNode(renderNode) {
@@ -417,11 +422,24 @@ class RenderItem {
417422
get isVisible() {
418423
if (this.isRoot) {
419424
return true;
425+
} else if (this.controller.showParentsOnly) {
426+
return (
427+
this.hasPinnedChild() ||
428+
(this.hasPinnedParent() && this.parentItem.isExpanded)
429+
);
420430
} else {
421431
return this.parentItem.isVisible && this.parentItem.isExpanded;
422432
}
423433
}
424434

435+
hasPinnedParent() {
436+
return this.isPinned || this.parentItem?.hasPinnedParent();
437+
}
438+
439+
hasPinnedChild() {
440+
return this.isPinned || this.childItems.some((c) => c.hasPinnedChild());
441+
}
442+
425443
get isPinned() {
426444
return this.id === this.controller.pinned;
427445
}

app/templates/component-tree.hbs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
@expandAll={{this.expandAll}}
66
@isInspecting={{this.isInspecting}}
77
@query={{this.query}}
8+
@pinned={{this.pinned}}
9+
@toggleParentsOnly={{this.toggleParentsOnly}}
10+
@showParentsOnly={{this.showParentsOnly}}
811
@toggleInspect={{this.toggleInspect}}
912
/>
1013
{{/in-element}}
Lines changed: 9 additions & 0 deletions
Loading

tests/acceptance/component-tree-test.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,59 @@ module('Component Tab', function (hooks) {
337337
);
338338
});
339339

340+
test('it should only show parents and children of selected item in focus mode', async function (assert) {
341+
await visit('/component-tree');
342+
343+
function findTreeItem(children, id) {
344+
for (const child of children) {
345+
if (child.id.includes(`render-node:${id}`)) {
346+
return child;
347+
}
348+
const found = findTreeItem(child.children, id);
349+
if (found) {
350+
return found;
351+
}
352+
}
353+
}
354+
355+
function getCustomRenderTree() {
356+
const tree = getRenderTree({ withChildren: true });
357+
const subtask = findTreeItem(tree, 6);
358+
const todo = findTreeItem(tree, 3);
359+
subtask.children.push(Component({ id: 7, name: 'sub-task-child' }));
360+
subtask.children.push(Component({ id: 8, name: 'sub-task-child' }));
361+
todo.children.push(Component({ id: 9, name: 'todo-list-2' }));
362+
return tree;
363+
}
364+
365+
await sendMessage({
366+
type: 'view:renderTree',
367+
tree: getCustomRenderTree(),
368+
});
369+
370+
await rerender();
371+
372+
let treeNodes = findAll('.component-tree-item');
373+
assert.strictEqual(treeNodes.length, 5, 'expected all tree nodes');
374+
375+
let expanders = findAll('.component-tree-item-expand');
376+
let expanderEl = expanders[expanders.length - 1];
377+
await click(expanderEl);
378+
379+
treeNodes = findAll('.component-tree-item');
380+
const subTask = treeNodes
381+
.filter((t) => t.textContent.toLowerCase().includes('subtask'))
382+
.at(-1);
383+
384+
respondWith('view:showInspection', false, { count: 1 });
385+
await click(subTask);
386+
387+
await click('[data-test-toggle-focus]');
388+
389+
treeNodes = findAll('.component-tree-item');
390+
assert.strictEqual(treeNodes.length, 6, 'expected all tree nodes');
391+
});
392+
340393
test('It should clear the search filter when the clear button is clicked', async function (assert) {
341394
await visit('/component-tree');
342395

0 commit comments

Comments
 (0)