Updated Branches: refs/heads/trunk 0872ee698 -> e833a7243
AMBARI-4217. Mirroring page redesign. (akovalenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e833a724 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e833a724 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e833a724 Branch: refs/heads/trunk Commit: e833a724321054292826269afedf856a8a06edef Parents: 0872ee6 Author: Aleksandr Kovalenko <[email protected]> Authored: Fri Jan 3 14:52:39 2014 +0200 Committer: Aleksandr Kovalenko <[email protected]> Committed: Fri Jan 3 14:52:39 2014 +0200 ---------------------------------------------------------------------- .../app/assets/data/mirroring/all_datasets.json | 2 +- ambari-web/app/messages.js | 9 +- ambari-web/app/models/dataset.js | 22 ++- ambari-web/app/styles/application.less | 14 ++ ambari-web/app/templates/main/host/summary.hbs | 2 +- .../app/templates/main/mirroring/datasets.hbs | 174 ++++++++----------- .../app/views/main/mirroring/datasets_view.js | 79 +++++---- 7 files changed, 166 insertions(+), 136 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/e833a724/ambari-web/app/assets/data/mirroring/all_datasets.json ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/data/mirroring/all_datasets.json b/ambari-web/app/assets/data/mirroring/all_datasets.json index 65c3d57..76d387c 100644 --- a/ambari-web/app/assets/data/mirroring/all_datasets.json +++ b/ambari-web/app/assets/data/mirroring/all_datasets.json @@ -106,7 +106,7 @@ "id":"90", "cluster":"drtarget1", "sourceCluster":"drsource", - "status":"SUCCESSFUL", + "status":"FAILED", "start":"2012-03-06T03:17Z", "end":"2012-03-06T03:19Z", "details":"", http://git-wip-us.apache.org/repos/asf/ambari/blob/e833a724/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index 78e1192..532a1eb 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -163,6 +163,7 @@ Em.I18n.translations = { 'common.ignore': 'Ignore', 'common.restart': 'Restart', 'common.discard': 'Discard', + 'common.actions': 'Actions', 'requestInfo.installComponents':'Install Components', 'requestInfo.installServices':'Install Services', @@ -1343,7 +1344,6 @@ Em.I18n.translations = { 'hosts.host.summary.hostname':'Hostname', 'hosts.host.summary.agentHeartbeat':'Agent <br/> Heartbeat', 'hosts.host.summary.hostMetrics':'Host Metrics', - 'hosts.host.summary.action':'Actions', 'hosts.host.summary.addComponent':'Add Component', 'hosts.host.details.hostActions':'Host Actions', @@ -1667,7 +1667,8 @@ Em.I18n.translations = { 'apps.isRunning.popup.content':'Job is running now', 'mirroring.dataset.AllDataSets':'All Datasets', - 'mirroring.dataset.createNewDataset':'Create New Dataset', + 'mirroring.dataset.createDataset':'Create Dataset', + 'mirroring.dataset.manageClusters':'Manage Clusters', 'mirroring.dataset.newDataset':'New Dataset', 'mirroring.dataset.editDataset':'Edit Dataset', 'mirroring.dataset.selectTargetClusters':'Select Target Cluster...', @@ -1694,7 +1695,8 @@ Em.I18n.translations = { 'mirroring.targetcluster.enterClusterName':'Name of the Target Cluster', 'mirroring.table.noDatasets':'No datasets to display', - 'mirroring.table.datasetSource':'Dataset Source', + 'mirroring.table.datasetSource':'Source', + 'mirroring.table.datasetTarget':'Target', 'mirroring.table.lastSuccess':'Last Success', 'mirroring.table.lastFail':'Last Fail', 'mirroring.table.lastDuration':'Last Duration', @@ -1705,6 +1707,7 @@ Em.I18n.translations = { 'mirroring.table.end':'End', 'mirroring.table.duration':'Duration', 'mirroring.table.data':'Data', + 'mirroring.table.nextInstance':'Next Instance', 'mirroring.sidebar.header.history': 'History', 'mirroring.sidebar.header.clusters': 'Target Clusters', http://git-wip-us.apache.org/repos/asf/ambari/blob/e833a724/ambari-web/app/models/dataset.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/dataset.js b/ambari-web/app/models/dataset.js index 913e41d..a48c77e 100644 --- a/ambari-web/app/models/dataset.js +++ b/ambari-web/app/models/dataset.js @@ -33,7 +33,27 @@ App.Dataset = DS.Model.extend({ lastDuration: DS.attr('number'), avgData: DS.attr('string'), createdDate: DS.attr('string'), - datasetJobs: DS.hasMany('App.DataSetJob') + datasetJobs: DS.hasMany('App.DataSetJob'), + + //Next instance to run. Will be calculated later. + nextInstance: function () { + return ''; + }.property(), + + //Name of target cluster related to dataset + cluster: function () { + return this.get('targetCluster.clusterName'); + }.property('targetCluster.clusterName'), + + //Class name for dataset health status indicator + healthClass: function () { + var jobs = this.get('datasetJobs').toArray(); + jobs = jobs.filterProperty('status', 'FAILED').concat(jobs.filterProperty('status', 'SUCCESSFUL')); + jobs.sort(function (a, b) { + return a.get('endDate') - b.get('endDate'); + }); + return jobs.length && jobs[0].get('status') === 'FAILED' ? 'health-status-DEAD-RED' : 'health-status-LIVE'; + }.property('datasetJobs', '[email protected]') }); http://git-wip-us.apache.org/repos/asf/ambari/blob/e833a724/ambari-web/app/styles/application.less ---------------------------------------------------------------------- diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less index c274bac..425a6d0 100644 --- a/ambari-web/app/styles/application.less +++ b/ambari-web/app/styles/application.less @@ -3780,6 +3780,20 @@ ul.filter { visibility: hidden; } } + .status-dot-position { + background-position: center; + background-repeat: no-repeat; + height: 20px; + width: 13px; + } + .health-status-LIVE { + background-image: @status-live-marker; + .status-dot-position; + } + .health-status-DEAD-RED { + background-image: @status-dead-red-marker; + .status-dot-position; + } } .box-footer .footer-pagination { http://git-wip-us.apache.org/repos/asf/ambari/blob/e833a724/ambari-web/app/templates/main/host/summary.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/host/summary.hbs b/ambari-web/app/templates/main/host/summary.hbs index 3fda928..f8de8cf 100644 --- a/ambari-web/app/templates/main/host/summary.hbs +++ b/ambari-web/app/templates/main/host/summary.hbs @@ -70,7 +70,7 @@ {{#if App.isAdmin}} <div class="btn-group pull-right"> <a {{ bindAttr class="view.disabled :btn :dropdown-toggle"}} data-toggle="dropdown"> - {{t hosts.host.summary.action}} + {{t common.actions}} <span class="caret pull-right"></span> </a> <ul class="dropdown-menu"> http://git-wip-us.apache.org/repos/asf/ambari/blob/e833a724/ambari-web/app/templates/main/mirroring/datasets.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/mirroring/datasets.hbs b/ambari-web/app/templates/main/mirroring/datasets.hbs index e60f16c..d421344 100644 --- a/ambari-web/app/templates/main/mirroring/datasets.hbs +++ b/ambari-web/app/templates/main/mirroring/datasets.hbs @@ -16,107 +16,87 @@ * limitations under the License. }} <div> - <div class="top-portion"> - <ul class="breadcrumb"> - <li><a href="#/main/mirroring">{{t mirroring.dataset.AllDataSets}}</a> </li> - </ul> + {{#if App.isAdmin}} + <div class="mirroring-top-nav pull-right btn-group"> + <button class="btn">{{t common.actions}}</button> + <button class="btn dropdown-toggle" data-toggle="dropdown"> + <span class="caret"></span> + </button> + <ul class="dropdown-menu pull-left"> + <li> + <a href="javascript:void(null);"> + <i class="icon-plus"></i>{{t mirroring.dataset.createDataset}} + </a> + </li> + <li> + <a href="javascript:void(null);"> + <i class="icon-cog"></i>{{t mirroring.dataset.manageClusters}}... + </a> + </li> + </ul> </div> -{{#if App.isAdmin}} - <div class="mirroring-top-nav button-section pull-right"> - <button class="btn btn-inverse add-host-button" {{action addNewDataset}}> - <i class="icon-plus icon-white"></i> - {{t mirroring.dataset.createNewDataset}} - </button> - </div> -{{/if}} + {{/if}} </div> - -<div class="row-fluid"> - <div class="span2 mirroring-sidebar"> - <h5>{{t mirroring.sidebar.header.history}}</h5> - <hr /> - <ul> - {{#each job in view.jobs}} - <li><a href="#" {{action "gotoShowJobs" job.dataset}}>{{job.dataset.name}}</a><br />{{job.startDateFormatted}}</li> - {{/each}} - </ul> - <h5>{{t mirroring.sidebar.header.clusters}} <span class="pull-right"><a {{action addTargetCluster controller.name}} href="#">{{t add}}</a></span></h5> - <hr /> - <ul> - {{#each cluster in view.targetClusters}} - <li><a {{action "editTargetCluster" cluster}}>{{cluster.clusterName}}</a></li> +<div id="mirroring"> + <table class="table table-bordered table-striped"> + <thead> + <tr> + {{#view view.sortView contentBinding="view.filteredContent"}} + <th class="first"> </th> + {{view view.parentView.nameSort}} + {{view view.parentView.sourceSort}} + {{view view.parentView.targetSort}} + {{view view.parentView.clusterSort}} + {{view view.parentView.lastSuccessSort}} + {{view view.parentView.nextInstanceSort}} + {{/view}} + </tr> + <tr> + <th class="first"> </th> + <th>{{view view.nameFilterView}}</th> + <th>{{view view.datasetSourceFilterView}}</th> + <th>{{view view.datasetTargetFilterView}}</th> + <th>{{view view.clusterFilterView}}</th> + <th>{{view view.lastSuccessFilterView}}</th> + <th>{{view view.nextInstanceFilterView}}</th> + </tr> + </thead> + <tbody> + {{#if view.pageContent}} + {{#each dataset in view.pageContent}} + {{#view view.DatasetView contentBinding="dataset"}} + <td class="first"> + <span {{bindAttr class="dataset.healthClass"}}></span> + </td> + <td class="name"> + <a title="{{unbound dataset.name}}" href="#" {{action "gotoShowJobs" dataset}}>{{unbound dataset.name}}</a> + </td> + <td>{{dataset.sourceDir}}</td> + <td>{{dataset.targetDir}}</td> + <td>{{dataset.cluster}}</td> + <td>{{view.lastSucceededDateFormatted}}</td> + <td>{{dataset.nextInstance}}</td> + {{/view}} {{/each}} - </ul> - </div> - <div class="span10"> - <div id="mirroring"> - <table class="table table-bordered table-striped"> - <thead> - <tr> - {{#view view.sortView contentBinding="view.filteredContent"}} - <th class="first"> </th> - {{view view.parentView.nameSort}} - {{view view.parentView.dataSetSourceSort}} - {{view view.parentView.lastSuccessSort}} - {{view view.parentView.lastFailSort}} - {{view view.parentView.lastDurationSort}} - {{view view.parentView.avgDataSort}} - {{/view}} - </tr> - <tr> - <th class="first"> </th> - <th>{{view view.nameFilterView}}</th> - <th>{{view view.datasetSourceFilterView}}</th> - <th>{{view view.lastSuccessFilterView}}</th> - <th>{{view view.lastFailFilterView}}</th> - <th>{{view view.lastDurationFilterView}}</th> - <th>{{view view.avgDataFilterView}}</th> - </tr> - </thead> - <tbody> - {{#if view.pageContent}} - {{!#each dataset in view.pageContent}} - {{#each dataset in datasets}} - {{#view view.DatasetView contentBinding="dataset"}} - - <td class="first"> - </td> + {{else}} + <tr> + <td class="first"></td> + <td colspan="6"> + {{t mirroring.table.noDatasets}} + </td> + </tr> + {{/if}} + </tbody> + </table> - <td class="name"> - <a title="{{unbound dataset.name}}" href="#" {{action "gotoShowJobs" dataset}}>{{unbound dataset.name}}</a> - </td> - <td>{{dataset.sourceDir}}</td> - <td>{{view.lastSucceededDateFormatted}}</td> - <td>{{view.lastFailedDateFormatted}}</td> - - <td> - {{view.lastDurationFormatted}} - </td> - - <td>{{dataset.avgData}}</td> - {{/view}} - {{/each}} - {{else}} - <tr> - <td class="first"></td> - <td colspan="6"> - {{t mirroring.table.noDatasets}} - </td> - </tr> - {{/if}} - </tbody> - </table> - - <div class="page-bar"> - <div class="items-on-page"> - <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label> - </div> - <div class="info">{{view.paginationInfo}}</div> - <div class="paging_two_button"> - {{view view.paginationLeft}} - {{view view.paginationRight}} - </div> - </div> + <div class="page-bar"> + <div class="items-on-page"> + <label>{{t common.show}}: {{view view.rowsPerPageSelectView selectionBinding="view.displayLength"}}</label> + </div> + <div class="info">{{view.paginationInfo}}</div> + <div class="paging_two_button"> + {{view view.paginationLeft}} + {{view view.paginationRight}} </div> </div> </div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/e833a724/ambari-web/app/views/main/mirroring/datasets_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/mirroring/datasets_view.js b/ambari-web/app/views/main/mirroring/datasets_view.js index b290c29..02165c7 100644 --- a/ambari-web/app/views/main/mirroring/datasets_view.js +++ b/ambari-web/app/views/main/mirroring/datasets_view.js @@ -49,29 +49,31 @@ App.MainDatasetsView = App.TableView.extend({ name: 'name', displayName: Em.I18n.t('common.name') }), - dataSetSourceSort: sort.fieldView.extend({ - name: 'sourceDir', + + sourceSort: sort.fieldView.extend({ + name: 'source', displayName: Em.I18n.t('mirroring.table.datasetSource') }), + + targetSort: sort.fieldView.extend({ + name: 'target', + displayName: Em.I18n.t('mirroring.table.datasetTarget') + }), + + clusterSort: sort.fieldView.extend({ + name: 'cluster', + displayName: Em.I18n.t('common.cluster') + }), + lastSuccessSort: sort.fieldView.extend({ name: 'lastSucceededDate', displayName: Em.I18n.t('mirroring.table.lastSuccess'), type: 'number' }), - lastFailSort: sort.fieldView.extend({ - name: 'lastFailedDate', - displayName: Em.I18n.t('mirroring.table.lastFail'), - type: 'number' - }), - lastDurationSort: sort.fieldView.extend({ - name: 'lastDuration', - displayName: Em.I18n.t('mirroring.table.lastDuration'), - type: 'number' - }), - avgDataSort: sort.fieldView.extend({ - name: 'avgData', - displayName: Em.I18n.t('mirroring.table.avgData'), - type: 'number' + + nextInstanceSort: sort.fieldView.extend({ + name: 'nextInstance', + displayName: Em.I18n.t('mirroring.table.nextInstance') }), /** @@ -87,44 +89,55 @@ App.MainDatasetsView = App.TableView.extend({ }), datasetSourceFilterView: filters.createTextView({ - fieldType: 'input-small', + fieldType: 'input-medium', column: 2, onChangeValue: function () { this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string'); } }), - lastSuccessFilterView: filters.createSelectView({ + datasetTargetFilterView: filters.createTextView({ fieldType: 'input-medium', column: 3, - content: ['Any', 'Past 1 Day', 'Past 2 Days', 'Past 7 Days', 'Past 14 Days', 'Past 30 Days'], onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'date'); + this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string'); } }), - lastFailFilterView: filters.createSelectView({ + clusterFilterView: filters.createSelectView({ fieldType: 'input-medium', column: 4, - content: ['Any', 'Past 1 Day', 'Past 2 Days', 'Past 7 Days', 'Past 14 Days', 'Past 30 Days'], + content: function () { + return ['Any'].concat(this.get('parentView.content').mapProperty('targetCluster.clusterName')); + }.property('this.parentView.content'), + onClearValue: function () { + if (this.get('value') === '') { + this.set('value', 'Any'); + } + }.observes('value'), onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'date'); + var value = this.get('value'); + if (value === 'Any') { + value = ''; + } + this.get('parentView').updateFilter(this.get('column'), value, 'string'); } }), - lastDurationFilterView: filters.createTextView({ - fieldType: 'input-small', + lastSuccessFilterView: filters.createSelectView({ + fieldType: 'input-medium', column: 5, + content: ['Any', 'Past 1 Day', 'Past 2 Days', 'Past 7 Days', 'Past 14 Days', 'Past 30 Days'], onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'duration'); + this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'date'); } }), - avgDataFilterView: filters.createTextView({ + nextInstanceFilterView: filters.createTextView({ fieldType: 'input-small', column: 6, onChangeValue: function () { - this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'ambari-bandwidth'); + this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string'); } }), @@ -159,11 +172,11 @@ App.MainDatasetsView = App.TableView.extend({ colPropAssoc: function () { var associations = []; associations[1] = 'name'; - associations[2] = 'sourceDir'; - associations[3] = 'lastSucceededDate'; - associations[4] = 'lastFailedDate'; - associations[5] = 'lastDuration'; - associations[6] = 'avgData'; + associations[2] = 'source'; + associations[3] = 'target'; + associations[4] = 'cluster'; + associations[5] = 'lastSucceededDate'; + associations[6] = 'nextInstance'; return associations; }.property()
