You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ak...@apache.org on 2014/01/03 13:53:26 UTC

git commit: AMBARI-4217. Mirroring page redesign. (akovalenko)

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 <ak...@hortonworks.com>
Authored: Fri Jan 3 14:52:39 2014 +0200
Committer: Aleksandr Kovalenko <ak...@hortonworks.com>
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', 'datasetJobs.@each.status')
 });
 
 

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()