From d7d5e22928caa0de5492531bfc9023859c7f23c8 Mon Sep 17 00:00:00 2001 From: Martin Sikora Date: Fri, 28 Feb 2020 08:01:11 +0100 Subject: [PATCH] =?UTF-8?q?desktop-gui:=20Add=20toggle=20buttons=20to=20ro?= =?UTF-8?q?ot=20specs=20to=20expand/collaps=E2=80=A6=20(#6541)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * desktop-gui: add toggle buttons to expand/collapse all sub folders. #6282 * lint code changes * hide collapse/expand buttons when root spec has no folders * fix indentation * fix lint issue and refactor a bit * Move collapse/expand links to right side of folder header Co-authored-by: Chris Breiding Co-authored-by: Jennifer Shehane --- .../cypress/integration/specs_list_spec.js | 81 +++++++++++++++++++ .../desktop-gui/src/specs/folder-model.js | 4 +- packages/desktop-gui/src/specs/specs-list.jsx | 25 +++++- packages/desktop-gui/src/specs/specs-store.js | 31 ++++++- packages/desktop-gui/src/specs/specs.scss | 10 ++- 5 files changed, 146 insertions(+), 5 deletions(-) diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 24a4c1e9e7cb..65c3c72d57d5 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -279,6 +279,87 @@ describe('Specs List', function () { }) }) + context('expand/collapse root specs', function () { + describe('with folders', function () { + beforeEach(function () { + this.ipc.getSpecs.yields(null, this.specs) + + this.openProject.resolve(this.config) + }) + + it('collapsing root spec will keep root itself expanded', function () { + cy.get('.level-0 .folder-name').find('a:first').click({ multiple: true }) + cy.get('.folder.folder-collapsed').should('have.length', 3) + cy.get('.folder.folder-expanded').should('have.length', 2) + }) + + it('collapses all children folders', function () { + cy.get('.level-0 .folder-name').find('a:first').click({ multiple: true }) + + const lastCollapsedFolderSelector = '.folder-collapsed:last .folder-name' + const rootSpecCollapsedFoldersSelector = '.folder-collapsed' + + cy.get(lastCollapsedFolderSelector).click() + cy.get(rootSpecCollapsedFoldersSelector).should('have.length', 3) + + cy.get(lastCollapsedFolderSelector).click() + cy.get(rootSpecCollapsedFoldersSelector).should('have.length', 3) + + cy.get(lastCollapsedFolderSelector).click() + cy.get(rootSpecCollapsedFoldersSelector).should('have.length', 3) + + cy.get(lastCollapsedFolderSelector).click() + cy.get(rootSpecCollapsedFoldersSelector).should('have.length', 3) + + cy.get(lastCollapsedFolderSelector).click() + cy.get(rootSpecCollapsedFoldersSelector).should('have.length', 2) + + cy.get(lastCollapsedFolderSelector).click() + cy.get(rootSpecCollapsedFoldersSelector).should('have.length', 2) + + cy.get(lastCollapsedFolderSelector).click() + cy.get(rootSpecCollapsedFoldersSelector).should('have.length', 1) + + cy.get(lastCollapsedFolderSelector).click() + cy.get(rootSpecCollapsedFoldersSelector).should('have.length', 0) + }) + + it('expand all expands all sub folders', function () { + cy.get('.level-0 .folder-name').find('a:first').click({ multiple: true }) + cy.get('.folder-expanded').should('have.length', 2) + cy.get('.folder-collapsed').should('have.length', 3) + + cy.get('.level-0 .folder-name').find('a:last').click({ multiple: true }) + cy.get('.folder-expanded').should('have.length', 10) + cy.get('.folder-collapsed').should('have.length', 0) + }) + }) + + describe('without folders', function () { + beforeEach(function () { + this.ipc.getSpecs.yields(null, { + integration: [ + { + name: 'app_spec.coffee', + relative: 'app_spec.coffee', + }, + { + name: 'account_new_spec.coffee', + relative: 'account_new_spec.coffee', + }, + ], + unit: [], + }) + + this.openProject.resolve(this.config) + }) + + it('hides expand/collapse buttons when there are no folders', function () { + cy.get('.level-0 .folder-name a').should('not.exist') + }) + }) + }) + context('filtering specs', function () { it('scrolls the specs and not the filter', function () { this.ipc.getSpecs.yields(null, this.specs) diff --git a/packages/desktop-gui/src/specs/folder-model.js b/packages/desktop-gui/src/specs/folder-model.js index ddeb48d6486c..9fd27c7497c1 100644 --- a/packages/desktop-gui/src/specs/folder-model.js +++ b/packages/desktop-gui/src/specs/folder-model.js @@ -1,11 +1,13 @@ import { action, computed, observable } from 'mobx' -export default class Directory { +export default class Folder { @observable path @observable displayName @observable isExpanded = true @observable children = [] + isFolder = true + constructor ({ path, displayName }) { this.path = path this.displayName = displayName diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index 98a654708618..c30eb5f58243 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -117,10 +117,18 @@ class SpecsList extends Component { return projectsApi.runSpec(project, spec, project.chosenBrowser) } + _setExpandRootFolder (specFolderPath, isExpanded, e) { + e.preventDefault() + e.stopPropagation() + + specsStore.setExpandSpecChildren(specFolderPath, isExpanded) + specsStore.setExpandSpecFolder(specFolderPath, true) + } + _selectSpecFolder (specFolderPath, e) { e.preventDefault() - specsStore.setExpandSpecFolder(specFolderPath) + specsStore.toggleExpandSpecFolder(specFolderPath) } _folderContent (spec, nestingLevel) { @@ -132,7 +140,20 @@ class SpecsList extends Component {
- {nestingLevel === 0 ? `${spec.displayName} tests` : spec.displayName} + { + nestingLevel === 0 ? + <> + {spec.displayName} tests + {specsStore.specHasFolders(spec) ? + + collapse all{' | '} + expand all + : + null + } + : + spec.displayName + }
{ isExpanded ? diff --git a/packages/desktop-gui/src/specs/specs-store.js b/packages/desktop-gui/src/specs/specs-store.js index e83b887db38c..4e1f1ae44b63 100644 --- a/packages/desktop-gui/src/specs/specs-store.js +++ b/packages/desktop-gui/src/specs/specs-store.js @@ -58,10 +58,22 @@ export class SpecsStore { this.chosenSpecPath = relativePath } - @action setExpandSpecFolder (spec) { + @action setExpandSpecFolder (spec, isExpanded) { + spec.setExpanded(isExpanded) + } + + @action toggleExpandSpecFolder (spec) { spec.setExpanded(!spec.isExpanded) } + @action setExpandSpecChildren (spec, isExpanded) { + this._depthFirstIterateSpecs(spec, (specOrFolder) => { + if (specOrFolder.isFolder) { + specOrFolder.setExpanded(isExpanded) + } + }) + } + @action setFilter (project, filter = null) { if (!filter) return this.clearFilter(project) @@ -86,6 +98,14 @@ export class SpecsStore { return `specsFilter-${id}-${shortenedPath}` } + specHasFolders (specOrFolder) { + if (!specOrFolder.isFolder) { + return false + } + + return specOrFolder.children.some((child) => child.isFolder) + } + _tree (files) { if (this.filter) { files = _.filter(files, (spec) => { @@ -125,6 +145,15 @@ export class SpecsStore { return tree } + + _depthFirstIterateSpecs (root, func) { + _.each(root.children, (child) => { + func(child) + if (child.isFolder) { + this._depthFirstIterateSpecs(child, func) + } + }) + } } export default new SpecsStore() diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index ffdc871bd793..e74c616ec499 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -144,7 +144,7 @@ $max-nesting-level: 14; &.level-0 { >div>.folder-name { - padding: 5px 20px; + padding: 5px 10px 5px 20px; background-color: #F9F9F9; font-weight: normal; text-transform: uppercase; @@ -153,11 +153,19 @@ $max-nesting-level: 14; color: #777; line-height: 18px; font-family: $font-sans; + display: flex; + flex-direction: row; + justify-content: space-between; i { display: none; margin-right: 5px; } + + span { + font-size: 10px; + margin-left: 10px; + } } } }