From 8035b3f24a2c8ab82976feef40c0d1dbf30872d1 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Sun, 1 May 2016 09:38:41 +1000 Subject: [PATCH] Refactoring admin table panels infrastructure Updating enterprise index --- .../enterprise_index_row_controller.js.coffee | 49 -------- .../enterprises_controller.js.coffee | 48 +++++++ .../index_panel_controller.js.coffee | 2 +- .../services/enterprise_resource.js.coffee | 3 + .../services/enterprises.js.coffee | 5 +- .../directives/panel_row.js.coffee | 39 ++---- .../directives/panel_toggle.js.coffee | 10 +- .../directives/panel_toggle_row.js.coffee | 32 ++--- .../index_utils/services/columns.js.coffee | 10 +- .../index_utils/services/panels.js.coffee | 33 ++--- .../templates/admin/panel.html.haml | 2 +- .../stylesheets/admin/index_panels.css.scss | 18 +-- .../_enterprise_user_index.html.haml | 14 +-- .../index_panel_controller_spec.js.coffee | 2 +- .../directives/panel_row_spec.js.coffee | 18 +-- .../services/panels_spec.js.coffee | 119 ++++++++++++++---- 16 files changed, 231 insertions(+), 173 deletions(-) delete mode 100644 app/assets/javascripts/admin/enterprises/controllers/enterprise_index_row_controller.js.coffee diff --git a/app/assets/javascripts/admin/enterprises/controllers/enterprise_index_row_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/enterprise_index_row_controller.js.coffee deleted file mode 100644 index 63b8daf07c..0000000000 --- a/app/assets/javascripts/admin/enterprises/controllers/enterprise_index_row_controller.js.coffee +++ /dev/null @@ -1,49 +0,0 @@ -angular.module("admin.enterprises").controller "EnterpriseIndexRowCtrl", ($scope) -> - $scope.status = -> - if $scope.enterprise.issues.length > 0 - "issue" - else if $scope.enterprise.warnings.length > 0 - "warning" - else - "ok" - - - $scope.producerText = -> - switch $scope.enterprise.is_primary_producer - when true - "Producer" - else - "Non-Producer" - - $scope.packageText = -> - switch $scope.enterprise.is_primary_producer - when true - switch $scope.enterprise.sells - when "none" - "Profile" - when "own" - "Shop" - when "any" - "Hub" - else - "Choose" - else - switch $scope.enterprise.sells - when "none" - "Profile" - when "any" - "Hub" - else - "Choose" - - $scope.updateRowText = -> - $scope.producer = $scope.producerText() - $scope.package = $scope.packageText() - $scope.producerError = ($scope.producer == "Choose") - $scope.packageError = ($scope.package == "Choose") - - - $scope.updateRowText() - - $scope.$on "enterprise:updated", -> - $scope.updateRowText() diff --git a/app/assets/javascripts/admin/enterprises/controllers/enterprises_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/enterprises_controller.js.coffee index d6dda4a118..02553a822b 100644 --- a/app/assets/javascripts/admin/enterprises/controllers/enterprises_controller.js.coffee +++ b/app/assets/javascripts/admin/enterprises/controllers/enterprises_controller.js.coffee @@ -3,6 +3,54 @@ angular.module("admin.enterprises").controller 'enterprisesCtrl', ($scope, $q, E requests.push ($scope.allEnterprises = Enterprises.index(ams_prefix: "index")).$promise $q.all(requests).then -> + $scope.updateStaticFieldsFor(enterprise) for enterprise in $scope.allEnterprises $scope.loaded = true $scope.columns = Columns.columns + + $scope.updateStaticFieldsFor = (enterprise) -> + enterprise.producer = $scope.producerTextFor(enterprise) + enterprise.package = $scope.packageTextFor(enterprise) + enterprise.producerError = (enterprise.producer == "Choose") + enterprise.packageError = (enterprise.package == "Choose") + enterprise.status = $scope.statusFor(enterprise) + + $scope.$on "enterprise:updated", (event, enterprise) -> + $scope.updateStaticFieldsFor(enterprise) + + $scope.statusFor = (enterprise) -> + if enterprise.issues.length > 0 + "issue" + else if enterprise.warnings.length > 0 + "warning" + else + "ok" + + + $scope.producerTextFor = (enterprise) -> + switch enterprise.is_primary_producer + when true + "Producer" + else + "Non-Producer" + + $scope.packageTextFor = (enterprise) -> + switch enterprise.is_primary_producer + when true + switch enterprise.sells + when "none" + "Profile" + when "own" + "Shop" + when "any" + "Hub" + else + "Choose" + else + switch enterprise.sells + when "none" + "Profile" + when "any" + "Hub" + else + "Choose" diff --git a/app/assets/javascripts/admin/enterprises/controllers/index_panel_controller.js.coffee b/app/assets/javascripts/admin/enterprises/controllers/index_panel_controller.js.coffee index 6f568ca5ea..1e207884d3 100644 --- a/app/assets/javascripts/admin/enterprises/controllers/index_panel_controller.js.coffee +++ b/app/assets/javascripts/admin/enterprises/controllers/index_panel_controller.js.coffee @@ -9,7 +9,7 @@ angular.module("admin.enterprises").controller 'indexPanelCtrl', ($scope, Enterp unless $scope.saved() $scope.saving = true Enterprises.save($scope.enterprise).then (data) -> - $scope.$emit("enterprise:updated") + $scope.$emit("enterprise:updated", $scope.enterprise) $scope.saving = false , (response) -> $scope.saving = false diff --git a/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee b/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee index 023f33d86c..b522f5be3b 100644 --- a/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee +++ b/app/assets/javascripts/admin/enterprises/services/enterprise_resource.js.coffee @@ -1,4 +1,7 @@ angular.module("admin.enterprises").factory 'EnterpriseResource', ($resource) -> + ignoredAttrs = -> + ["$$hashKey", "producer", "package", "producerError", "packageError", "status"] + $resource('/admin/enterprises/:id/:action.json', {}, { 'index': method: 'GET' diff --git a/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee b/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee index b159816709..80db943689 100644 --- a/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee +++ b/app/assets/javascripts/admin/enterprises/services/enterprises.js.coffee @@ -33,8 +33,11 @@ angular.module("admin.enterprises").factory 'Enterprises', ($q, EnterpriseResour diff: (enterprise) -> changed = [] for attr, value of enterprise when not angular.equals(value, @pristineByID[enterprise.id][attr]) - changed.push attr unless attr is "$$hashKey" + changed.push attr unless attr in @ignoredAttrs() changed + ignoredAttrs: -> + ["$$hashKey", "producer", "package", "producerError", "packageError", "status"] + resetAttribute: (enterprise, attribute) -> enterprise[attribute] = @pristineByID[enterprise.id][attribute] diff --git a/app/assets/javascripts/admin/index_utils/directives/panel_row.js.coffee b/app/assets/javascripts/admin/index_utils/directives/panel_row.js.coffee index eb5a4171f4..474ec5664d 100644 --- a/app/assets/javascripts/admin/index_utils/directives/panel_row.js.coffee +++ b/app/assets/javascripts/admin/index_utils/directives/panel_row.js.coffee @@ -1,37 +1,24 @@ angular.module("admin.indexUtils").directive "panelRow", (Panels, Columns) -> restrict: "C" + require: "^^panelToggleRow" templateUrl: "admin/panel.html" scope: object: "=" panels: "=" - link: (scope, element, attrs) -> - scope.template = "" - selected = null - scope.columnCount = Columns.visibleCount + colspan: "=?" + locals: '@?' + link: (scope, element, attrs, ctrl) -> + scope.template = null + scope.columnCount = (scope.colspan || Columns.visibleCount) + + if scope.locals + scope[local] = scope.$parent.$eval(local.trim()) for local in scope.locals.split(',') scope.$on "columnCount:changed", (event, count) -> scope.columnCount = count - setTemplate = -> - if selected? - scope.template = 'admin/panels/' + scope.panels[selected] + '.html' + ctrl.registerSelectionListener (selection) -> + if selection? + scope.template = "admin/panels/#{scope.panels[selection]}.html" else - scope.template = "" - - scope.getSelected = -> - selected - - scope.setSelected = (name) -> - scope.$apply -> - selected = name - setTemplate() - - scope.open = (name) -> - element.show 0, -> - scope.setSelected name - - scope.close = -> - element.hide 0, -> - scope.setSelected null - - Panels.register(scope.object.id, scope) + scope.template = null diff --git a/app/assets/javascripts/admin/index_utils/directives/panel_toggle.js.coffee b/app/assets/javascripts/admin/index_utils/directives/panel_toggle.js.coffee index df81328905..56d80d88b9 100644 --- a/app/assets/javascripts/admin/index_utils/directives/panel_toggle.js.coffee +++ b/app/assets/javascripts/admin/index_utils/directives/panel_toggle.js.coffee @@ -2,11 +2,13 @@ angular.module("admin.indexUtils").directive "panelToggle", -> restrict: "C" transclude: true template: '
' - require: "^panelToggleRow" + require: "^^panelToggleRow" scope: name: "@" link: (scope, element, attrs, ctrl) -> - scope.selected = ctrl.register(scope.name, element) - element.on "click", -> - scope.selected = ctrl.select(scope.name) + scope.$apply -> + ctrl.toggle(scope.name) + + ctrl.registerSelectionListener (selection) -> + element.toggleClass('selected', selection == scope.name) diff --git a/app/assets/javascripts/admin/index_utils/directives/panel_toggle_row.js.coffee b/app/assets/javascripts/admin/index_utils/directives/panel_toggle_row.js.coffee index d2d9c90ff8..ec6cb6d5ed 100644 --- a/app/assets/javascripts/admin/index_utils/directives/panel_toggle_row.js.coffee +++ b/app/assets/javascripts/admin/index_utils/directives/panel_toggle_row.js.coffee @@ -3,27 +3,19 @@ angular.module("admin.indexUtils").directive "panelToggleRow", (Panels) -> scope: object: "=" selected: "@?" - controller: ($scope) -> - panelToggles = {} + controller: ($scope, $element) -> + this.toggle = (name) -> + Panels.toggle($scope.object, name) - this.register = (name, element) -> - panelToggles[name] = element - panelToggles[name].addClass("selected") if $scope.selected == name - $scope.selected == name + this.select = (selection) -> + $scope.$broadcast("selection:changed", selection) + $element.toggleClass("expanded", selection?) - this.select = (name) -> - panelToggle.removeClass("selected") for panelName, panelToggle of panelToggles - - switch $scope.selected = Panels.toggle($scope.object.id, name) - when null - panelToggles[name].parent(".panel-toggle-row").removeClass("expanded") - else - panelToggles[$scope.selected].addClass("selected") - panelToggles[$scope.selected].parent(".panel-toggle-row").addClass("expanded") - - $scope.selected == name + this.registerSelectionListener = (callback) -> + $scope.$on "selection:changed", (event, selection) -> + callback(selection) this - # - # link: (scope, element, attrs) -> - # Panels.registerInitialSelection(scope.object.id, scope.selected) + + link: (scope, element, attrs, ctrl) -> + Panels.register(ctrl, scope.object, scope.selected) diff --git a/app/assets/javascripts/admin/index_utils/services/columns.js.coffee b/app/assets/javascripts/admin/index_utils/services/columns.js.coffee index 45bea7c680..fbc5149a3f 100644 --- a/app/assets/javascripts/admin/index_utils/services/columns.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/columns.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.indexUtils").factory 'Columns', ($rootScope, $http, columns) -> +angular.module("admin.indexUtils").factory 'Columns', ($rootScope, $http, $injector) -> new class Columns savedColumns: {} columns: {} @@ -6,11 +6,17 @@ angular.module("admin.indexUtils").factory 'Columns', ($rootScope, $http, column constructor: -> @columns = {} - for column in columns + for column in @injectColumns() @columns[column.column_name] = column @savedColumns[column.column_name] = angular.copy(column) @calculateVisibleCount() + injectColumns: -> + if $injector.has('columns') + $injector.get('columns') + else + [] + toggleColumn: (column) => column.visible = !column.visible @calculateVisibleCount() diff --git a/app/assets/javascripts/admin/index_utils/services/panels.js.coffee b/app/assets/javascripts/admin/index_utils/services/panels.js.coffee index 27852bed12..d020b88264 100644 --- a/app/assets/javascripts/admin/index_utils/services/panels.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/panels.js.coffee @@ -1,19 +1,22 @@ angular.module("admin.indexUtils").factory 'Panels', -> new class Panels - panels: {} + panels: [] - register: (id, scope) -> - if id? && scope? - @panels[id] = scope + register: (ctrl, object, selected=null) -> + if ctrl? && object? + @panels.push { ctrl: ctrl, object: object, selected: selected } + ctrl.select(selected) if selected? - toggle: (id, name) -> - scope = @panels[id] - selected = scope.getSelected() - switch selected - when name - scope.close() - when null - scope.open(name) - else - scope.setSelected(name) - scope.getSelected() + toggle: (object, name, state=null) -> + panel = @findPanelByObject(object) + if panel.selected == name + @select(panel, null) unless state == "open" + else + @select(panel, name) unless state == "closed" + + select: (panel, name) -> + panel.selected = name + panel.ctrl.select(name) + + findPanelByObject: (object) -> + (panel for panel in @panels when panel.object == object)[0] diff --git a/app/assets/javascripts/templates/admin/panel.html.haml b/app/assets/javascripts/templates/admin/panel.html.haml index be0c98109f..4d3780aed0 100644 --- a/app/assets/javascripts/templates/admin/panel.html.haml +++ b/app/assets/javascripts/templates/admin/panel.html.haml @@ -1,2 +1,2 @@ -%td{ colspan: "{{columnCount}}" } +%td{ colspan: "{{columnCount}}", ng: { if: "template" } } .panel{ ng: { include: "template" } } diff --git a/app/assets/stylesheets/admin/index_panels.css.scss b/app/assets/stylesheets/admin/index_panels.css.scss index a910e41d14..ca8464ab26 100644 --- a/app/assets/stylesheets/admin/index_panels.css.scss +++ b/app/assets/stylesheets/admin/index_panels.css.scss @@ -1,4 +1,4 @@ -tr.panel-toggle-row { +tbody.panel-toggle-row { td.panel-toggle{ -webkit-touch-callout: none; -webkit-user-select: none; @@ -66,13 +66,13 @@ tr.panel-toggle-row { &.expanded{ td { - border-bottom: 2px solid #444444; + border-bottom: 1px solid #6788a2; &.selected { background-color: #ffffff; - border-left: 2px solid #444444; - border-right: 2px solid #444444; - border-top: 2px solid #444444; + border-left: 1px solid #6788a2; + border-right: 1px solid #6788a2; + border-top: 1px solid #6788a2; border-bottom: none; &:hover { @@ -96,8 +96,6 @@ tr.panel-toggle-row { } tr.panel-row { - display: none; - &:hover { td { background-color: #ffffff; @@ -105,13 +103,9 @@ tr.panel-row { } >td { - border-color: #444444; + border-color: #6788a2; padding: 0; .panel { - border-left: 1px solid #444444; - border-right: 1px solid #444444; - border-bottom: 1px solid #444444; - .row{ margin: 0px -4px; diff --git a/app/views/admin/enterprises/_enterprise_user_index.html.haml b/app/views/admin/enterprises/_enterprise_user_index.html.haml index 75dbf98f17..3c976185d5 100644 --- a/app/views/admin/enterprises/_enterprise_user_index.html.haml +++ b/app/views/admin/enterprises/_enterprise_user_index.html.haml @@ -29,16 +29,16 @@ %th.package{ ng: { show: 'columns.package.visible' } }=t('.package') %th.status{ ng: { show: 'columns.status.visible' } }=t('.status') %th.manage{ ng: { show: 'columns.manage.visible' } }=t('.manage') - %tbody{ :id => "e_{{enterprise.id}}", ng: { repeat: "enterprise in filteredEnterprises = ( allEnterprises | filter:{ name: quickSearch } )", controller: 'EnterpriseIndexRowCtrl' } } - %tr.enterprise.panel-toggle-row{ object: "enterprise", ng: { class: { even: "'even'", odd: "'odd'"} } } + %tbody.panel-toggle-row{ :id => "e_{{enterprise.id}}", object: "enterprise", ng: { repeat: "enterprise in filteredEnterprises = ( allEnterprises | filter:{ name: quickSearch } )" } } + %tr.enterprise{ ng: { class: { even: "'even'", odd: "'odd'"} } } %td.name{ ng: { show: 'columns.name.visible' } } %span{ ng: { bind: "::enterprise.name" } } - %td.producer.panel-toggle.text-center{ ng: { show: 'columns.producer.visible', class: "{error: producerError}" }, name: "producer" } - %h5{ ng: { bind: "producer" } } - %td.package.panel-toggle.text-center{ ng: { show: 'columns.package.visible', class: "{error: packageError}" }, name: "package" } - %h5{ ng: { bind: "package" } } + %td.producer.panel-toggle.text-center{ ng: { show: 'columns.producer.visible', class: "{error: enterprise.producerError}" }, name: "producer" } + %h5{ ng: { bind: "enterprise.producer" } } + %td.package.panel-toggle.text-center{ ng: { show: 'columns.package.visible', class: "{error: enterprise.packageError}" }, name: "package" } + %h5{ ng: { bind: "enterprise.package" } } %td.status.panel-toggle.text-center{ ng: { show: 'columns.status.visible' }, name: "status" } - %i.icon-status{ ng: { class: "::status()" } } + %i.icon-status{ ng: { class: "enterprise.status" } } %td.manage{ ng: { show: 'columns.manage.visible' } } %a.button.fullwidth{ ng: { href: '{{::enterprise.edit_path}}' } } Manage diff --git a/spec/javascripts/unit/admin/enterprises/controllers/index_panel_controller_spec.js.coffee b/spec/javascripts/unit/admin/enterprises/controllers/index_panel_controller_spec.js.coffee index 8fca1c6ab5..1ade26f19e 100644 --- a/spec/javascripts/unit/admin/enterprises/controllers/index_panel_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/enterprises/controllers/index_panel_controller_spec.js.coffee @@ -38,7 +38,7 @@ describe "indexPanelCtrl", -> expect(scope.saving).toBe false it "emits an 'enterprise:updated' event", -> - expect(scope.$emit).toHaveBeenCalledWith("enterprise:updated") + expect(scope.$emit).toHaveBeenCalledWith("enterprise:updated", scope.enterprise) describe "when the save is unsuccessful", -> beforeEach inject ($rootScope) -> diff --git a/spec/javascripts/unit/admin/index_utils/directives/panel_row_spec.js.coffee b/spec/javascripts/unit/admin/index_utils/directives/panel_row_spec.js.coffee index 92eba790c3..f4f0ac4ce3 100644 --- a/spec/javascripts/unit/admin/index_utils/directives/panel_row_spec.js.coffee +++ b/spec/javascripts/unit/admin/index_utils/directives/panel_row_spec.js.coffee @@ -1,7 +1,8 @@ describe "PanelRow directive", -> Panels = null element = null - directiveScope = null + panelScope = null + rowScope = null beforeEach -> module 'admin.indexUtils' @@ -13,24 +14,27 @@ describe "PanelRow directive", -> Panels = _Panels_ $templateCache.put 'admin/panel.html', '{{ template }}' # Declare the directive HTML. - element = angular.element('
') + element = angular.element('
') # Define the root scope. scope = $rootScope # Compile and digest the directive. $compile(element) scope scope.$digest() - directiveScope = element.find('span').scope() + rowScope = element.find('tbody').isolateScope() + panelScope = element.find('tr').isolateScope() return describe "initialisation", -> - it "registers the scope with the panels service", -> - expect(Panels.panels[12]).toEqual directiveScope + it "registers a listener on the row scope", -> + expect(rowScope.$$listeners["selection:changed"].length).toEqual 1 - describe "setting the selected panel", -> + describe "when a select event is triggered on the row scope", -> beforeEach -> - directiveScope.setSelected('panel1') + rowScope.$broadcast('selection:changed', 'panel1') it 'updates the active template on the scope', -> + panelScope.$digest() + expect(panelScope.template).toEqual "admin/panels/template.html" expect(element.find('span').html()).toEqual "admin/panels/template.html" return diff --git a/spec/javascripts/unit/admin/index_utils/services/panels_spec.js.coffee b/spec/javascripts/unit/admin/index_utils/services/panels_spec.js.coffee index 7ee69cf88e..8a659df984 100644 --- a/spec/javascripts/unit/admin/index_utils/services/panels_spec.js.coffee +++ b/spec/javascripts/unit/admin/index_utils/services/panels_spec.js.coffee @@ -8,45 +8,110 @@ describe "Panels service", -> Panels = _Panels_ describe "registering panels", -> - it "adds the panel provided scope to @panelsm indexed by the provided id", -> - Panels.register(23, { some: 'scope'} ) - expect(Panels.panels[23]).toEqual { some: 'scope' } + ctrl1 = ctrl2 = null + beforeEach -> + ctrl1 = jasmine.createSpyObj('ctrl', ['select']) + ctrl2 = jasmine.createSpyObj('ctrl', ['select']) - it "ignores the input if id or scope are null", -> - Panels.register(null, { some: 'scope'} ) - Panels.register(23, null) - expect(Panels.panels).toEqual { } + it "adds the panels controller, object and selection to @panels", -> + Panels.register(ctrl1, { name: "obj1"}, "panel1") + Panels.register(ctrl2, { name: "obj2"}) + expect(Panels.panels).toEqual [ + { ctrl: ctrl1, object: { name: "obj1"}, selected: "panel1" }, + { ctrl: ctrl2, object: { name: "obj2"}, selected: null } + ] + + it "call select on the controller if a selection is provided", -> + Panels.register(ctrl1, { name: "obj1"}, "panel1") + Panels.register(ctrl2, { name: "obj2"}) + expect(ctrl1.select.calls.count()).toEqual 1 + expect(ctrl2.select.calls.count()).toEqual 0 + + it "ignores the input if object or ctrl are null", -> + Panels.register(ctrl1, null) + Panels.register(null, { name: "obj2"}) + expect(Panels.panels).toEqual [] describe "toggling a panel", -> - scopeMock = null + panelMock = ctrlMock = objMock = null beforeEach -> - scopeMock = - open: jasmine.createSpy('open') - close: jasmine.createSpy('close') - setSelected: jasmine.createSpy('setSelected') - Panels.panels = { '12': scopeMock } + ctrlMock = jasmine.createSpyObj('ctrl', ['select']) + panelMock = { ctrl: ctrlMock } + spyOn(Panels, "findPanelByObject").and.returnValue(panelMock) describe "when no panel is currently selected", -> beforeEach -> - scopeMock.getSelected = jasmine.createSpy('getSelected').and.returnValue(null) - Panels.toggle(12, 'panel_name') + panelMock.selected = null - it "calls #open on the scope", -> - expect(scopeMock.open).toHaveBeenCalledWith('panel_name') + describe "when no state is provided", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name') - describe "when #toggle is called for the currently selected panel", -> + it "selects the named panel", -> + expect(panelMock.selected).toEqual 'panel_name' + expect(ctrlMock.select).toHaveBeenCalledWith('panel_name') + + describe "when the state given is 'open'", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name', "open") + + it "selects the named panel", -> + expect(panelMock.selected).toEqual 'panel_name' + expect(ctrlMock.select).toHaveBeenCalledWith('panel_name') + + describe "when the state given is 'closed'", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name', "closed") + + it "does not select the named panel", -> + expect(panelMock.selected).toEqual null + expect(ctrlMock.select).not.toHaveBeenCalledWith('panel_name') + + describe "when the currently selected panel matches the named panel", -> beforeEach -> - scopeMock.getSelected = jasmine.createSpy('getSelected').and.returnValue('panel_name') - Panels.toggle(12, 'panel_name') + panelMock.selected = 'panel_name' - it "calls #close on the scope", -> - expect(scopeMock.close).toHaveBeenCalled() + describe "when no state is provided", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name') - describe "when #toggle is called for a different panel", -> + it "de-selects the named panel", -> + expect(panelMock.selected).toEqual null + expect(ctrlMock.select).toHaveBeenCalledWith(null) + + describe "when the state given is 'open'", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name', "open") + + it "keeps the the named panel selected, but does not call select on the controller", -> + expect(panelMock.selected).toEqual 'panel_name' + expect(ctrlMock.select).not.toHaveBeenCalledWith('panel_name') + + describe "when the state given is 'closed'", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name', "closed") + + it "de-selects the named panel", -> + expect(panelMock.selected).toEqual null + expect(ctrlMock.select).not.toHaveBeenCalledWith('panel_name') + + describe "when the currently selected panel does not match the requested panel", -> beforeEach -> - scopeMock.getSelected = jasmine.createSpy('getSelected').and.returnValue('some_other_panel_name') - Panels.toggle(12, 'panel_name') + panelMock.selected = 'some_other_panel' - it "calls #setSelected on the scope", -> - expect(scopeMock.setSelected).toHaveBeenCalledWith('panel_name') + describe "when no state is provided", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name') + + it "selects the named panel", -> + expect(panelMock.selected).toEqual 'panel_name' + expect(ctrlMock.select).toHaveBeenCalledWith('panel_name') + + describe "when the state given is 'open'", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name', "open") + + it "selects the named panel", -> + expect(panelMock.selected).toEqual 'panel_name' + expect(ctrlMock.select).toHaveBeenCalledWith('panel_name') + + describe "when the state given is 'closed'", -> + beforeEach -> Panels.toggle({some: "object"}, 'panel_name', "closed") + + it "keeps the currently selected panel selected, ie. does nothing", -> + expect(panelMock.selected).toEqual "some_other_panel" + expect(ctrlMock.select).not.toHaveBeenCalledWith('panel_name') + expect(ctrlMock.select).not.toHaveBeenCalledWith('some_other_panel')