This is an automated email from the ASF dual-hosted git repository. ababiichuk pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push: new 6645b45 AMBARI-24619 Horizontal scroll bar on assign slaves and clients page is not convenient for deploy with numerous hosts. (ababiichuk) 6645b45 is described below commit 6645b45e9bb680e41255671d3e742fe097018de6 Author: ababiichuk <ababiic...@hortonworks.com> AuthorDate: Tue Sep 11 16:09:53 2018 +0300 AMBARI-24619 Horizontal scroll bar on assign slaves and clients page is not convenient for deploy with numerous hosts. (ababiichuk) --- ambari-web/app/styles/common.less | 17 +++ ambari-web/app/styles/wizard.less | 136 ++++++++++++++++-------- ambari-web/app/templates/wizard/step6.hbs | 72 ++++++------- ambari-web/app/views/wizard/step6_view.js | 36 +++++-- ambari-web/test/views/wizard/step6_view_test.js | 21 ++-- 5 files changed, 176 insertions(+), 106 deletions(-) diff --git a/ambari-web/app/styles/common.less b/ambari-web/app/styles/common.less index 249321b..03e989d 100644 --- a/ambari-web/app/styles/common.less +++ b/ambari-web/app/styles/common.less @@ -227,5 +227,22 @@ @navbar-header-padding-left: 0; @navbar-header-font-size: 20px; +/************************************************************************ +* Table styles +***********************************************************************/ @table-color: @gray-text; @table-font-size: 13px; +@table-hover-background-color: #E7F6FC; +@table-hover-border-color: #A7DFF2; +@table-margin-bottom: 20px; +@table-footer-color: #999; +@table-footer-border: 2px solid #EEE; +@table-cell-padding: 8px; + +/************************************************************************ +* Checkbox styles +***********************************************************************/ +@checkbox-color: #1491C1; +@checkbox-size: 10px; +@checkbox-border-radius: 2px; +@checkbox-top: 4px; diff --git a/ambari-web/app/styles/wizard.less b/ambari-web/app/styles/wizard.less index 8341bb6..89784a8 100644 --- a/ambari-web/app/styles/wizard.less +++ b/ambari-web/app/styles/wizard.less @@ -19,6 +19,7 @@ @import 'common.less'; @wizard-side-nav-width: 250px; +@host-column-width: 210px; #enable_security { .step3 { @@ -251,57 +252,106 @@ } #step6 { .pre-scrollable { - max-height: 440px; + width: 100%; + overflow: auto; position: relative; - display: flex; - overflow-y: auto; + max-height: 440px; + border-bottom: @table-footer-border; #component_assign_table { - display: inline-block; - overflow-x: auto; - margin-left: 190px; - margin-bottom: 10px; - height: 100%; - tbody td, th { - white-space: nowrap; - } - tfoot td { - padding-bottom: 30px; - } - .trim_hostname { - .ellipsis-overflow-nowrap; - max-width: 180px; - float:left; + margin-bottom: 0; + tr { display: block; - } - .checkbox { - margin: 0; - } - .host-component-checkbox { - line-height: 17px; - font-size: 12px; - top: 0; - } - .freeze { - position: absolute; - left: 0; - width: 210px; - border-top-color: #eee; - border-bottom: 1px solid #eee; - } - td.freeze { - padding-bottom: 11px; - } - tr.last-row { - td { - border-bottom: 2px solid #eee; + padding-left: @host-column-width; + td, th { + white-space: nowrap; + } + .freeze { + width: @host-column-width; + position: absolute; + left: 0; + background-color: #fff; + border-left: 1px solid transparent; + } + .trim_hostname { + .ellipsis-overflow-nowrap; + max-width: 180px; + float: left; + display: block; + } + .checkbox { + margin: 0; + position: static; + input[type="checkbox"] { + + label.host-component-checkbox { + display: inline; + line-height: 17px; + font-size: 12px; + position: static; + padding-left: 0; + &:before { + position: static; + display: inline-block; + margin-top: @checkbox-top; + margin-right: @checkbox-size; + } + &:after { + background-color: @checkbox-color; + border-color: @checkbox-color; + position: static; + display: inline-block; + float: left; + margin-right: @checkbox-size; + width: @checkbox-size; + height: @checkbox-size; + border-radius: @checkbox-border-radius; + margin-top: -1 * (@checkbox-size + @checkbox-top); + line-height: 1.2em; + padding-left: 2px; + } + } + &:checked + label:before { + visibility: hidden; + } + &:not(:checked) + label:after { + content: ''; + visibility: hidden; + } + } + } + &:hover { + &:not(:first-of-type) { + margin-top: -1px; + } + td.freeze { + background-color: @table-hover-background-color; + border-color: @table-hover-border-color; + } + + tr { + border-top-width: 0; + } + } + &.last-row { + border-bottom-color: transparent; + td { + border-bottom-color: transparent; + } + &:hover { + border-bottom-color: @table-hover-border-color; + } } } - .static-pagination { - position: absolute; - right: 10px; + .host-messages { + margin-left: @host-column-width; + padding: @table-cell-padding; } } } + .static-pagination { + margin-bottom: @table-margin-bottom; + font-size: @table-font-size; + color: @table-footer-color; + padding: @table-cell-padding; + } .spinner-overlay { position: absolute; width: 100%; diff --git a/ambari-web/app/templates/wizard/step6.hbs b/ambari-web/app/templates/wizard/step6.hbs index 9673abd..e8e851c 100644 --- a/ambari-web/app/templates/wizard/step6.hbs +++ b/ambari-web/app/templates/wizard/step6.hbs @@ -50,25 +50,28 @@ </div> {{/if}} - <div class="pre-scrollable col-sm-12"> - <table class="table table-hover" id="component_assign_table" {{QAAttr "slave-clients-table"}}> - <thead> - <tr> - <th class="host-column freeze">{{t common.host}}</th> - {{#each header in controller.headers}} - <th {{bindAttr class="header.name"}}> - <a href="#" {{QAAttr "select-all"}} {{bindAttr class="header.allChecked:selected:deselected header.isDisabled:remove-link" id="header.allId"}} - {{action "selectAllNodes" header target="controller"}}>{{t all}}</a> | <a - {{QAAttr "deselect-all"}} href="#" {{bindAttr class="header.noChecked:selected:deselected header.isDisabled:remove-link" id="header.noneId"}} - {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a> - </th> - {{/each}} - </tr> - </thead> - <tbody> + <div class="col-sm-12"> + <div class="pre-scrollable"> + <table class="table table-hover" id="component_assign_table" {{QAAttr "slave-clients-table"}}> + <thead> + <tr> + <th class="host-column freeze">{{t common.host}}</th> + {{#each header in controller.headers}} + <th {{bindAttr class="header.name"}}> + <a + href="#" {{QAAttr "select-all"}} {{bindAttr class="header.allChecked:selected:deselected header.isDisabled:remove-link" id="header.allId"}} + {{action "selectAllNodes" header target="controller"}}>{{t all}}</a> | <a + {{QAAttr "deselect-all"}} + href="#" {{bindAttr class="header.noChecked:selected:deselected header.isDisabled:remove-link" id="header.noneId"}} + {{action "deselectAllNodes" header target="controller"}}>{{t none}}</a> + </th> + {{/each}} + </tr> + </thead> + <tbody> {{#each host in view.pageContent}} <tr {{QAAttr "host-row"}} {{bindAttr class="host.isLast:last-row"}}> - {{#view App.WizardStep6HostView hostBinding="host" }} + {{#view App.WizardStep6HostView hostBinding="host"}} <span class="trim_hostname">{{host.hostName}}</span> {{#if host.hasMaster}} <i {{QAAttr "has-masters"}} class="glyphicon glyphicon-asterisks">✵</i> @@ -77,35 +80,28 @@ {{#each checkbox in host.checkboxes}} <td {{QAAttr "toggle-component"}} {{bindAttr class="checkbox.hasErrorMessage:error checkbox.hasWarnMessage:warning checkbox.component"}}> <div class="checkbox" {{bindAttr data-qa="checkbox.dataQaAttr"}}> - <input {{bindAttr id="checkbox.uId" checked="checkbox.checked" disabled="checkbox.isDisabled"}} {{action "checkboxClick" checkbox target="view" }} - type="checkbox"/> + <input {{bindAttr id="checkbox.uId" checked="checkbox.checked" disabled="checkbox.isDisabled"}} {{action "checkboxClick" checkbox target="view"}} + type="checkbox"/> <label class="host-component-checkbox" {{bindAttr for="checkbox.uId"}}>{{checkbox.title}}</label> </div> </td> {{/each}} </tr> {{#if host.anyMessage}} - <tr> - <td {{bindAttr colspan="view.columnCount"}} class="no-borders"> - {{#each errorMsg in host.errorMessages}} - <div class="alert alert-danger">{{errorMsg}}</div> - {{/each}} - {{#each warnMsg in host.warnMessages}} - <div class="alert alert-warning">{{warnMsg}}</div> - {{/each}} - </td> - </tr> + <div class="host-messages"> + {{#each errorMsg in host.errorMessages}} + <div class="alert alert-danger">{{errorMsg}}</div> + {{/each}} + {{#each warnMsg in host.warnMessages}} + <div class="alert alert-warning">{{warnMsg}}</div> + {{/each}} + </div> {{/if}} {{/each}} - </tbody> - <tfoot> - <tr> - <td colspan="100"> - {{view App.PaginationView classNames="static-pagination"}} - </td> - </tr> - </tfoot> - </table> + </tbody> + </table> + </div> + {{view App.PaginationView classNames="static-pagination"}} </div> </div> </div> diff --git a/ambari-web/app/views/wizard/step6_view.js b/ambari-web/app/views/wizard/step6_view.js index 8810c49..c3f9d4b 100644 --- a/ambari-web/app/views/wizard/step6_view.js +++ b/ambari-web/app/views/wizard/step6_view.js @@ -50,15 +50,36 @@ App.WizardStep6View = App.TableView.extend({ didInsertElement: function () { this.setLabel(); this.get('controller').loadStep(); + this.$('.pre-scrollable').on('scroll', event => { + this.$('.pre-scrollable .freeze').css('transform', `translate(${event.target.scrollLeft}px,0)`); + }); Em.run.next(this, this.adjustColumnWidth); }, adjustColumnWidth: function() { - const table = $('#component_assign_table'); - const columnsCount = this.get('controller.headers.length'); - if (table.width() > table.find('tbody').width()) { - const columnWidth = Math.floor(table.width() / columnsCount); + const table = $('#component_assign_table'), + tableWrapper = $('.pre-scrollable').first(), + tableCells = table.find('tbody > tr:first-of-type > td'); + let cellsWidth = 0; + $.each(tableCells, (i, td) => cellsWidth += $(td).width()); + if (tableWrapper.width() > cellsWidth) { + const columnsCount = this.get('controller.headers.length'), + hostColumnWidth = 210, // from ambari-web/app/styles/wizard.less + columnWidth = Math.floor((table.width() - hostColumnWidth)/ columnsCount); table.find("th:not('.freeze'), td:not('.freeze')").width(columnWidth); + // a trick to keep checkbox abd label on the single line + table.find('.host-component-checkbox').css({ + display: 'inline-block', + width: '0' + }); + } else { + const tds = $('#component_assign_table > tbody > tr:first-of-type > td'); + $.each(tds, (i, td) => { + const element = $(td), + className = element.attr('class'), + width = element.width(); + $(`#component_assign_table th.${className}`).width(width); + }); } }, @@ -93,12 +114,7 @@ App.WizardStep6View = App.TableView.extend({ Em.set(checkbox, 'checked', !checkbox.checked); this.get('controller').checkCallback(checkbox.component); this.get('controller').callValidation(); - }, - - columnCount: function() { - var hosts = this.get('controller.hosts'); - return hosts && hosts.length > 0 ? hosts[0].get('checkboxes').length + 1 : 1; - }.property('controller.hosts.@each.checkboxes') + } }); App.WizardStep6HostView = Em.View.extend({ diff --git a/ambari-web/test/views/wizard/step6_view_test.js b/ambari-web/test/views/wizard/step6_view_test.js index 7a4dc9f..511bb11 100644 --- a/ambari-web/test/views/wizard/step6_view_test.js +++ b/ambari-web/test/views/wizard/step6_view_test.js @@ -25,7 +25,12 @@ var view; function getView() { return App.WizardStep6View.create({ - controller: App.WizardStep6Controller.create() + controller: App.WizardStep6Controller.create(), + $: function () { + return { + on: Em.K + }; + } }); } @@ -141,20 +146,6 @@ describe('App.WizardStep6View', function() { }); }); - describe("#columnCount", function() { - it("hosts present", function() { - view.set('controller.hosts', [ - Em.Object.create({checkboxes: [{}, {}, {}]}) - ]); - view.propertyDidChange('columnCount'); - expect(view.get('columnCount')).to.equal(4); - }); - it("hosts absent", function() { - view.set('controller.hosts', []); - view.propertyDidChange('columnCount'); - expect(view.get('columnCount')).to.equal(1); - }); - }); }); describe('App.WizardStep6HostView', function() {