diff --git a/changes.d/1973.feat.md b/changes.d/1973.feat.md
new file mode 100644
index 000000000..d6c039080
--- /dev/null
+++ b/changes.d/1973.feat.md
@@ -0,0 +1 @@
+Add a button to toggle families on and off in the tree view.
diff --git a/src/components/cylc/tree/Tree.vue b/src/components/cylc/tree/Tree.vue
index 0febfadb3..1b47f5920 100644
--- a/src/components/cylc/tree/Tree.vue
+++ b/src/components/cylc/tree/Tree.vue
@@ -25,7 +25,7 @@ along with this program. If not, see .
v-for="child of rootChildren"
:key="child.id"
:node="child"
- v-bind="{ hoverable, cyclePointsOrderDesc, expandAll, filteredOutNodesCache }"
+ v-bind="{ hoverable, cyclePointsOrderDesc, expandAll, filteredOutNodesCache, flat }"
/>
@@ -82,6 +82,11 @@ export default {
required: false,
default: () => []
},
+ flat: {
+ type: Boolean,
+ required: false,
+ default: true,
+ }
},
components: {
diff --git a/src/components/cylc/tree/TreeItem.vue b/src/components/cylc/tree/TreeItem.vue
index b9dd8ec4b..8a7ecad70 100644
--- a/src/components/cylc/tree/TreeItem.vue
+++ b/src/components/cylc/tree/TreeItem.vue
@@ -233,6 +233,11 @@ export default {
type: Number,
required: false,
},
+ flat: {
+ type: Boolean,
+ requried: false,
+ default: false,
+ },
},
data () {
@@ -268,7 +273,7 @@ export default {
nodeChildren () {
return this.node.type === 'job'
? null
- : getNodeChildren(this.node, this.cyclePointsOrderDesc)
+ : getNodeChildren(this.node, this.cyclePointsOrderDesc, this.flat)
},
nodeStyle () {
return {
diff --git a/src/components/cylc/tree/util.js b/src/components/cylc/tree/util.js
index 3352298a7..4f5a02b5f 100644
--- a/src/components/cylc/tree/util.js
+++ b/src/components/cylc/tree/util.js
@@ -14,13 +14,13 @@
* along with this program. If not, see .
*/
-export function getNodeChildren (node, cyclePointsOrderDesc) {
+export function getNodeChildren (node, cyclePointsOrderDesc, flat) {
// returns child nodes folling the family tree and following sort order
if (node.type === 'workflow' && !cyclePointsOrderDesc) {
// a user configuration has configured the sort order for cycle points to
// be reversed
return [...node.children].reverse()
- } else if (node.type === 'cycle') {
+ } else if (node.type === 'cycle' && !flat) {
// display tasks in the inheritance tree
if (node.familyTree?.length) {
const rootFamily = node.familyTree[0]
diff --git a/src/views/Tree.vue b/src/views/Tree.vue
index a411713c8..d6a029c45 100644
--- a/src/views/Tree.vue
+++ b/src/views/Tree.vue
@@ -36,6 +36,20 @@ along with this program. If not, see .
+
+
+ {{ flat? $options.icons.mdiFormatAlignRight : $options.icons.mdiFormatAlignJustify }}
+
+
+ {{ flat ? "Show Families" : "Hide Families" }}
+
+
.
:hoverable="false"
:autoStripTypes="['workflow']"
:node-filter-func="filterNode"
+ :flat="flat"
v-bind="{ expandAll, filterState }"
ref="treeComponent"
/>
@@ -83,7 +98,7 @@ along with this program. If not, see .
diff --git a/tests/e2e/specs/tree.cy.js b/tests/e2e/specs/tree.cy.js
index 99174a096..f84bc7410 100644
--- a/tests/e2e/specs/tree.cy.js
+++ b/tests/e2e/specs/tree.cy.js
@@ -355,4 +355,13 @@ describe('Tree view', () => {
cy.get('[data-cy="filter task state"]')
.contains('.v-select__selection', '(+')
})
+
+ describe('Toggle families', () => {
+ it('Toggles between flat and hierarchical modes', () => {
+ cy.visit('/#/tree/one')
+ cy.get('.node-data-family').should('have.length', 3)
+ cy.get('[data-cy=toggle-families]').click()
+ cy.get('.node-data-family').should('have.length', 0)
+ })
+ })
})