You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2013/04/16 04:45:26 UTC

svn commit: r1468293 - in /incubator/ambari/trunk: ./ ambari-web/app/ ambari-web/app/controllers/main/mirroring/ ambari-web/app/controllers/wizard/ ambari-web/app/routes/ ambari-web/app/styles/ ambari-web/app/templates/main/admin/security/ ambari-web/a...

Author: yusaku
Date: Tue Apr 16 02:45:25 2013
New Revision: 1468293

URL: http://svn.apache.org/r1468293
Log:
AMBARI-1908. HDFS Mirroring: Add Bread Crumbs and Validation. (Arun Kandregula via yusaku)

Added:
    incubator/ambari/trunk/ambari-web/app/templates/main/admin/security/disable.hbs
Modified:
    incubator/ambari/trunk/CHANGES.txt
    incubator/ambari/trunk/ambari-web/app/config.js
    incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/dataset_controller.js
    incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/targetClusterController.js
    incubator/ambari/trunk/ambari-web/app/controllers/wizard/step6_controller.js
    incubator/ambari/trunk/ambari-web/app/messages.js
    incubator/ambari/trunk/ambari-web/app/routes/main.js
    incubator/ambari/trunk/ambari-web/app/styles/application.less
    incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dataset.hbs
    incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/datasets.hbs
    incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dropdown.hbs
    incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/jobs.hbs
    incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnection.hbs
    incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnectionResults.hbs
    incubator/ambari/trunk/ambari-web/app/utils/config.js

Modified: incubator/ambari/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Tue Apr 16 02:45:25 2013
@@ -12,9 +12,14 @@ Trunk (unreleased changes):
 
  NEW FEATURES
 
- AMBARI-1558. Script to add host components to existing hosts. (yusaku via jaimin)
+ AMBARI-1908. HDFS Mirroring: Add Bread Crumbs and Validation. (Arun Kandregula
+ via yusaku)
+
+ AMBARI-1558. Script to add host components to existing hosts.
+ (yusaku via jaimi)
 
- AMBARI-1936. Support for installing on mixed OS versions install + mgmt. (swagle)
+ AMBARI-1936. Support for installing on mixed OS versions install + mgmt.
+ (swagle)
 
  AMBARI-1924. Allow for users to customize Ganglia gmetad + gmond user 
  accounts. (Sumit Mohanty via swagle)
@@ -33,7 +38,8 @@ Trunk (unreleased changes):
 
  AMBARI-1847. Make single PUT call for multiple host overrides. (srimanth)
 
- AMBARI-1857. Capacity Scheduler: field order for Add/Edit popup. (yusaku via srimanth)
+ AMBARI-1857. Capacity Scheduler: field order for Add/Edit popup. (yusaku via
+ srimanth)
 
  AMBARI-1855. Capacity Scheduler: when adding a new queue, populate 
  fields. (yusaku via srimanth)

Modified: incubator/ambari/trunk/ambari-web/app/config.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/config.js?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/config.js (original)
+++ incubator/ambari/trunk/ambari-web/app/config.js Tue Apr 16 02:45:25 2013
@@ -66,4 +66,3 @@ $.ajaxSetup({
  * Test Mode values
  */
 App.test_hostname = 'hostname';
-

Modified: incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/dataset_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/dataset_controller.js?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/dataset_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/dataset_controller.js Tue Apr 16 02:45:25 2013
@@ -33,11 +33,260 @@ App.MainMirroringDataSetController = Emb
         return listOfClusterNames;
       }.property('newDataSet.targetCluster'),  // this property will be set when someone clicks the save button
 
-      originalRecord: null
-    }
+      originalRecord: null,
+
+      isNameError: function (key, value) {
+        if (value) {
+          return value;
+        }
+        var controller = App.router.get('mainMirroringDataSetController');
+        var isNameError = controller.checkNameErrors();
+        return isNameError;
+      }.property('newDataSet.name', 'model.newDataSet.name'),
+
+      isSourceDirError: function (key, value) {
+        if (value) {
+          return value;
+        }
+        var controller = App.router.get('mainMirroringDataSetController');
+        var isSourceDirError = controller.checkSourceDirErrors();
+        return isSourceDirError;
+      }.property('newDataSet.sourceDir', 'model.newDataSet.sourceDir'),
+
+
+      isTargetClusterError: function (key, value) {
+        if (value) {
+          return value;
+        }
+        var controller = App.router.get('mainMirroringDataSetController');
+        var isTargetClusterError = controller.checkTargetClusterErrors();
+        return isTargetClusterError;
+      }.property('newDataSet.targetCluster', 'model.newDataSet.targetCluster'),
+
+      isTargetDirError: function (key, value) {
+        if (value) {
+          return value;
+        }
+        var controller = App.router.get('mainMirroringDataSetController');
+        var isTargetDirError = controller.checkTargetDirErrors();
+        return isTargetDirError;
+      }.property('newDataSet.targetDir', 'model.newDataSet.targetDir'),
+
+      isStartDateError: function (key, value) {
+        if (value) {
+          return value;
+        }
+        var controller = App.router.get('mainMirroringDataSetController');
+        var isStartDateError = controller.checkStartDateErrors();
+        return isStartDateError;
+      }.property('newDataSet.schedule.startDate', 'model.newDataSet.schedule.startDate'),
+
+      isEndDateError: function (key, value) {
+        if (value) {
+          return value;
+        }
+        var controller = App.router.get('mainMirroringDataSetController');
+        var isEndDateError = controller.checkEndDateErrors();
+        return isEndDateError;
+      }.property('newDataSet.schedule.endDate', 'model.newDataSet.schedule.endDate'),
+
+      isFrequencyError: function (key, value) {
+        if (value) {
+          return value;
+        }
+        var controller = App.router.get('mainMirroringDataSetController');
+        var isFrequencyError = controller.checkFrequencyErrors();
+        return isFrequencyError;
+      }.property('newDataSet.schedule.frequency', 'model.newDataSet.schedule.frequency')
 
+
+    }
   ),
 
+  isSubmitted: null,
+
+  validate: function () {
+    var isNameError = this.checkNameErrors();
+    var isSourceDirError = this.checkSourceDirErrors();
+    var isTargetClusterError = this.checkTargetClusterErrors();
+    var isTargetDirError = this.checkTargetDirErrors();
+    var isStartDateError = this.checkStartDateErrors();
+    var isEndDateError = this.checkEndDateErrors();
+    var isFrequencyError = this.checkFrequencyErrors();
+
+    if (isNameError || isSourceDirError || isTargetClusterError || isTargetDirError || isStartDateError || isEndDateError || isFrequencyError) {
+      return false;
+    }
+    return true;
+  },
+
+  checkNameErrors: function () {
+    if (!this.get('isSubmitted')){
+      this.set('nameErrorMessage', "");
+      return false;
+    }
+    var name = this.get('model.newDataSet.name');
+    if (!name || name.trim() === "") {
+      this.set('model.isNameError', true);
+      this.set('nameErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('nameErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  checkSourceDirErrors: function () {
+    if (!this.get('isSubmitted')){
+      this.set('sourceDirErrorMessage', "");
+      return false;
+    }
+    var sourceDir = this.get('model.newDataSet.sourceDir');
+    if (!sourceDir || sourceDir.trim() === "") {
+      this.set('model.isSourceDirError', true);
+      this.set('sourceDirErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('sourceDirErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  checkTargetClusterErrors: function () {
+    if (!this.get('isSubmitted')){
+      this.set('targetClusterErrorMessage', "");
+      return false;
+    }
+    var targetCluster = this.get('model.newDataSet.targetCluster.clusterName');
+    if (!targetCluster || targetCluster.trim() === "") {
+      this.set('model.isTargetClusterError', true);
+      this.set('targetClusterErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('targetClusterErrorMessage', "");
+      return false;
+    }
+
+
+  },
+  checkTargetDirErrors: function () {
+    if (!this.get('isSubmitted')){
+      this.set('targetDirErrorMessage', "");
+      return false;
+    }
+    var targetDir = this.get('model.newDataSet.targetDir');
+    if (!targetDir || targetDir.trim() === "") {
+      this.set('model.isTargetDirError', true);
+      this.set('targetDirErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('targetDirErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  checkStartDateErrors: function () {
+    if (!this.get('isSubmitted')){
+      this.set('startDateErrorMessage', "");
+      return false;
+    }
+    var startDate = this.get('model.newDataSet.schedule.startDate');
+    if (!startDate || startDate.trim() === "") {
+      this.set('model.isStartDateError', true);
+      this.set('startDateErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('startDateErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  checkEndDateErrors: function () {
+    if (!this.get('isSubmitted')){
+      this.set('endDateErrorMessage', "");
+      return false;
+    }
+    var startDate = this.get('model.newDataSet.schedule.startDate');
+    var endDate = this.get('model.newDataSet.schedule.endDate');
+    if (!endDate || endDate.trim() === "") {
+      this.set('model.isEndDateError', true);
+      this.set('endDateErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+
+      var sDate = new Date(this.get('model.newDataSet.schedule.startDate'));
+      var eDate = new Date(this.get('model.newDataSet.schedule.endDate'));
+      if(sDate > eDate){
+        this.set('model.isEndDateError', true);
+        this.set('endDateErrorMessage', Em.I18n.t('mirroring.dateOrder.error'));
+        return true;
+      }
+
+
+      this.set('endDateErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  checkFrequencyErrors: function () {
+    if (!this.get('isSubmitted')){
+      this.set('frequencyErrorMessage', "");
+      return false;
+    }
+    var frequency = this.get('model.newDataSet.schedule.frequency');
+
+    if (!frequency || frequency.trim() === "") {
+      this.set('model.isFrequencyError', true);
+      this.set('frequencyErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+
+      var startParenthesisindex = frequency.indexOf('(');
+      var endParenthesisindex = frequency.indexOf(')');
+
+      if (endParenthesisindex - startParenthesisindex == 1) {
+        this.set('model.isFrequencyError', true);
+        this.set('frequencyErrorMessage', Em.I18n.t('mirroring.required.error'));
+        return true;
+      }
+      else {
+        var frequencyNum = frequency.substring(startParenthesisindex + 1, endParenthesisindex);
+
+        frequencyNum = parseInt(frequencyNum);
+
+        if (isNaN(frequencyNum)) {
+          this.set('model.isFrequencyError', true);
+          this.set('frequencyErrorMessage', Em.I18n.t('mirroring.required.invalidNumberError'));
+          return true;
+        }
+
+      }
+
+      this.set('frequencyErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  nameErrorMessage: null,
+  sourceDirErrorMessage: null,
+  targetClusterErrorMessage: null,
+  targetDirErrorMessage: null,
+  startDateErrorMessage: null,
+  endDateErrorMessage: null,
+  frequencyErrorMessage: null,
   /**
    * Popup with add/edit form
    */
@@ -55,6 +304,7 @@ App.MainMirroringDataSetController = Emb
       sourceDir: null,
       targetCluster: Ember.Object.create(),
       targetDir: null,
+      status : 'SCHEDULED',
       schedule: Ember.Object.create()
     });
     this.set('model.newDataSet', newDataSet);
@@ -67,7 +317,9 @@ App.MainMirroringDataSetController = Emb
       sourceDir: dataset.get('sourceDir'),
       targetCluster: dataset.get('targetCluster'),
       targetDir: dataset.get('targetDir'),
-      schedule: dataset.get('schedule')
+      schedule: dataset.get('schedule'),
+      status: dataset.get('status')
+
     });
     this.set('model.newDataSet', newDataSet);
   },

Modified: incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/targetClusterController.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/targetClusterController.js?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/targetClusterController.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main/mirroring/targetClusterController.js Tue Apr 16 02:45:25 2013
@@ -19,11 +19,146 @@
 App.MainMirroringTargetClusterController = Ember.Controller.extend({
   name: 'mainMirroringTargetClusterController',
   model: Ember.Object.create({
-    targetCluster : null,
-    originalRecord : null,
-    isPopupForEdit : false // set the default to add scenario
+    targetCluster: null,
+    originalRecord: null,
+    isPopupForEdit: false, // set the default to add scenario
+    isNameNodeWebUrlError: function (key, value) {
+      if (value) {
+        return value;
+      }
+      var controller = App.router.get('mainMirroringTargetClusterController');
+      var isNameNodeWebUrlError = controller.checkNameNodeWebUrlErrors();
+      return isNameNodeWebUrlError;
+    }.property('targetCluster.nameNodeWebUrl', 'model.targetCluster.nameNodeWebUrl'),
+    isNameNodeRpcUrlError: function (key, value) {
+      if (value) {
+        return value;
+      }
+      var controller = App.router.get('mainMirroringTargetClusterController');
+      var isNameNodeRpcUrlError = controller.checkNameNodeRpcUrlErrors();
+      return isNameNodeRpcUrlError;
+    }.property('targetCluster.nameNodeRpcUrl', 'model.targetCluster.nameNodeRpcUrl'),
+
+    isOozieServerUrlError: function (key, value) {
+      if (value) {
+        return value;
+      }
+      var controller = App.router.get('mainMirroringTargetClusterController');
+      var isOozieServerUrlError = controller.checkOozieServerUrlErrors();
+      return isOozieServerUrlError;
+    }.property('targetCluster.oozieServerUrl', 'model.targetCluster.oozieServerUrl'),
+
+    isClusterNameError: function (key, value) {
+      if (value) {
+        return value;
+      }
+      var controller = App.router.get('mainMirroringTargetClusterController');
+      var isClusterNameError = controller.checkClusterNameErrors();
+      return isClusterNameError;
+    }.property('targetCluster.clusterName', 'model.targetCluster.clusterName'),
+
+    nameNodeWebUrlErrorMessage: null,
+    nameNodeRpcUrlErrorMessage: null,
+    oozieServerUrlErrorMessage: null,
+    clusterNameErrorMessage: null
   }),
-  setOriginalRecord : function(targetClusterRecord){
+
+  isSubmitted1: null,
+  isSubmitted2: null,
+
+  validate1: function () {
+    var isNameNodeWebUrlError = this.checkNameNodeWebUrlErrors();
+    var isNameNodeRpcUrlError = this.checkNameNodeRpcUrlErrors();
+    var isOozieServerUrlError = this.checkOozieServerUrlErrors();
+
+    if (isNameNodeWebUrlError || isNameNodeRpcUrlError || isOozieServerUrlError) {
+      return false;
+    }
+    return true;
+  },
+
+  validate2: function () {
+    var isClusterNameError = this.checkClusterNameErrors();
+
+    if (isClusterNameError) {
+      return false;
+    }
+    return true;
+  },
+
+  checkNameNodeWebUrlErrors: function () {
+    if (!this.get('isSubmitted1')){
+      this.set('model.nameNodeWebUrlErrorMessage', "");
+      return false;
+    }
+    var nameNodeWebUrl = this.get('model.targetCluster.nameNodeWebUrl');
+    if (!nameNodeWebUrl || nameNodeWebUrl.trim() === "") {
+      this.set('model.isNameNodeWebUrlError', true);
+      this.set('model.nameNodeWebUrlErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('model.nameNodeWebUrlErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  checkNameNodeRpcUrlErrors: function () {
+    if (!this.get('isSubmitted1')){
+      this.set('model.nameNodeRpcUrlErrorMessage', "");
+      return false;
+    }
+    var nameNodeRpcUrl = this.get('model.targetCluster.nameNodeRpcUrl');
+    if (!nameNodeRpcUrl || nameNodeRpcUrl.trim() === "") {
+      this.set('model.isNameNodeRpcUrlError', true);
+      this.set('model.nameNodeRpcUrlErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('model.nameNodeRpcUrlErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  checkOozieServerUrlErrors: function () {
+    if (!this.get('isSubmitted1')){
+      this.set('model.oozieServerUrlErrorMessage', "");
+      return false;
+    }
+    var oozieServerUrl = this.get('model.targetCluster.oozieServerUrl');
+    if (!oozieServerUrl || oozieServerUrl.trim() === "") {
+      this.set('model.isOozieServerUrlError', true);
+      this.set('model.oozieServerUrlErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('model.oozieServerUrlErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  checkClusterNameErrors: function () {
+    if (!this.get('isSubmitted1')){
+      this.set('model.clusterNameErrorMessage', "");
+      return false;
+    }
+    var clusterName = this.get('model.targetCluster.clusterName');
+    if (!clusterName || clusterName.trim() === "") {
+      this.set('model.isClusterNameError', true);
+      this.set('model.clusterNameErrorMessage', Em.I18n.t('mirroring.required.error'));
+      return true;
+    }
+    else {
+      this.set('model.clusterNameErrorMessage', "");
+      return false;
+    }
+
+  },
+
+  setOriginalRecord: function (targetClusterRecord) {
     this.set('model.originalRecord', targetClusterRecord);
   },
 
@@ -67,7 +202,7 @@ App.MainMirroringTargetClusterController
     return this.get('content.targetCluster');
   },
 
-  popup : null,
+  popup: null,
 
   /**
    * "Delete" button handler.

Modified: incubator/ambari/trunk/ambari-web/app/controllers/wizard/step6_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/wizard/step6_controller.js?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/wizard/step6_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/wizard/step6_controller.js Tue Apr 16 02:45:25 2013
@@ -276,7 +276,7 @@ App.WizardStep6Controller = Em.Controlle
         obj.checkboxes.pushObject(Em.Object.create({
           title: header.label,
           checked: false,
-          installed: false
+          isInstalled: false
         }));
       });
 

Modified: incubator/ambari/trunk/ambari-web/app/messages.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/messages.js?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/messages.js (original)
+++ incubator/ambari/trunk/ambari-web/app/messages.js Tue Apr 16 02:45:25 2013
@@ -1041,6 +1041,7 @@ Em.I18n.translations = {
   'apps.isRunning.popup.title':'Is running',
   'apps.isRunning.popup.content':'Job is running now',
 
+  'mirroring.dataset.AllDataSets':'All Datasets',
   'mirroring.dataset.createNewDataset':'Create New Dataset',
   'mirroring.dataset.newDataset':'New Dataset',
   'mirroring.dataset.editDataset':'Edit Dataset',
@@ -1048,7 +1049,7 @@ Em.I18n.translations = {
   'mirroring.dataset.name':'Name',
   'mirroring.dataset.save': 'Save & Run',
   'mirroring.dataset.sourceDir':'Source Cluster Directory',
-  'mirroring.dataset.target':'Target',
+  'mirroring.dataset.target':'Target Cluster',
   'mirroring.dataset.source':'Source',
   'mirroring.dataset.avgData':'Avg. Data',
   'mirroring.dataset.dateCreated':'Date Created',
@@ -1060,6 +1061,9 @@ Em.I18n.translations = {
   'mirroring.dataset.toggle.active':'Activate',
   'mirroring.dataset.toggle.suspended':'Suspend',
 
+  'mirroring.targetcluster.nameNodeWebUrl':'NameNode Web UI',
+  'mirroring.targetcluster.nameNodeRpcUrl':'NameNode RPC',
+  'mirroring.targetcluster.oozieServerUrl':'Oozie Server',
   'mirroring.targetcluster.addCluster':'Add Cluster',
   'mirroring.targetcluster.testConnection':'Test Connection',
   'mirroring.targetcluster.enterClusterName':'Name of the Target Cluster',
@@ -1082,6 +1086,10 @@ Em.I18n.translations = {
   'mirroring.sidebar.popup.clusters.header': 'Cluster management',
   'mirroring.sidebar.popup.clusters.body': 'Here will be some content',
 
+  'mirroring.required.error': 'This field is required',
+  'mirroring.dateOrder.error': 'End Date must be after Start Date',
+  'mirroring.required.invalidNumberError' : 'Enter valid number',
+
 
   'menu.item.dashboard':'Dashboard',
   'menu.item.heatmaps':'Heatmaps',

Modified: incubator/ambari/trunk/ambari-web/app/routes/main.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/routes/main.js?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/routes/main.js (original)
+++ incubator/ambari/trunk/ambari-web/app/routes/main.js Tue Apr 16 02:45:25 2013
@@ -121,6 +121,9 @@ module.exports = Em.Route.extend({
       }
     }),
 
+    gotoMirroringHome : function(router){
+      router.transitionTo('mirroring/index');
+    },
     addNewDataset: function (router) {
       router.transitionTo('addNewDatasetRoute');
     },
@@ -129,17 +132,6 @@ module.exports = Em.Route.extend({
       router.transitionTo('addTargetClusterRoute');
     },
 
-    gotoShowJobs: function (router, event) {
-      router.transitionTo('showDatasetJobs', event.context);
-    },
-
-    showDatasetJobs: Em.Route.extend({
-      route: '/dataset/:dataset_id',
-      connectOutlets: function (router, dataset) {
-        router.get('mainController').connectOutlet('mainJobs', dataset);
-      }
-    }),
-
     addNewDatasetRoute: Em.Route.extend({
       route: '/dataset/add',
 
@@ -158,12 +150,19 @@ module.exports = Em.Route.extend({
         this.setupController(controller);
 
         var self = this;
+        controller.set('isSubmitted', false);
         App.ModalPopup.show({
           classNames: ['sixty-percent-width-modal', 'hideCloseLink'],
           header: Em.I18n.t('mirroring.dataset.newDataset'),
           primary: Em.I18n.t('mirroring.dataset.save'),
           secondary: Em.I18n.t('common.cancel'),
           onPrimary: function () {
+            controller.set('isSubmitted', true);
+            var isValid = controller.validate();
+
+            if (!isValid) {
+              return;
+            }
             newDataSet = controller.getNewDataSet();
             var schedule = newDataSet.get('schedule');
             var targetCluster = newDataSet.get('targetCluster');
@@ -188,6 +187,17 @@ module.exports = Em.Route.extend({
       }
     }),
 
+    gotoShowJobs: function (router, event) {
+      router.transitionTo('showDatasetJobs', event.context);
+    },
+
+    showDatasetJobs: Em.Route.extend({
+      route: '/dataset/:dataset_id',
+      connectOutlets: function (router, dataset) {
+        router.get('mainController').connectOutlet('mainJobs', dataset);
+      }
+    }),
+
     editDataset: Em.Route.extend({
       route: '/dataset/:dataset_id/edit',
       setupController: function (controller, dataset) {
@@ -208,12 +218,19 @@ module.exports = Em.Route.extend({
         this.setupController(controller, dataset);
 
         var self = this;
+        controller.set('isSubmitted', false);
         controller.set('popup', App.ModalPopup.show({
           classNames: ['sixty-percent-width-modal'],
           header: Em.I18n.t('mirroring.dataset.editDataset'),
           primary: Em.I18n.t('mirroring.dataset.save'),
           secondary: Em.I18n.t('common.cancel'),
           onPrimary: function () {
+            controller.set('isSubmitted', true);
+            var isValid = controller.validate();
+
+            if (!isValid) {
+              return;
+            }
             newDataSet = controller.getNewDataSet();
 
             var originalRecord = controller.get('model.originalRecord');
@@ -259,11 +276,20 @@ module.exports = Em.Route.extend({
           var controller = App.router.get('mainMirroringTargetClusterController');
           this.setupController(controller);
 
+          controller.set('isSubmitted1', false);
+          controller.set('isSubmitted2', false);
           controller.set('popup', App.ModalPopup.show({
             classNames: ['sixty-percent-width-modal', 'hideCloseLink'],
             header: Em.I18n.t('mirroring.targetcluster.addCluster'),
             primary: Em.I18n.t('mirroring.targetcluster.testConnection'),
             onPrimary: function () {
+              controller.set('isSubmitted1', true);
+              var isValid = controller.validate1();
+
+              if (!isValid) {
+                return;
+              }
+
               App.router.transitionTo('testConnectionResultsRoute');
             },
             onSecondary: function () {
@@ -305,6 +331,14 @@ module.exports = Em.Route.extend({
           popup.set('primary', Em.I18n.t('common.save'));
           popup.set('onPrimary',
             function () {
+              var controller = App.router.get('mainMirroringTargetClusterController');
+              controller.set('isSubmitted2', true);
+              var isValid = controller.validate2();
+
+              if (!isValid) {
+                return;
+              }
+
               var controller = App.router.get('testConnectionResultsController');
               controller.saveClusterName();
             }
@@ -345,11 +379,22 @@ module.exports = Em.Route.extend({
       testConnectionRoute: Em.Route.extend({
         connectOutlets: function (router, targetCluster) {
           var controller = router.get('mainMirroringTargetClusterController');
+          controller.set('isSubmitted1', false);
+          controller.set('isSubmitted2', false);
+
           controller.set('popup', App.ModalPopup.show({
             classNames: ['sixty-percent-width-modal'],
             header: Em.I18n.t('mirroring.dataset.editDataset'),
             primary: Em.I18n.t('mirroring.targetcluster.testConnection'),
             onPrimary: function () {
+              var controller = App.router.get('mainMirroringTargetClusterController');
+              controller.set('isSubmitted1', true);
+              var isValid = controller.validate1();
+
+              if (!isValid) {
+                return;
+              }
+
               App.router.transitionTo('testConnectionResultsRoute');
             },
             secondary: Em.I18n.t('common.cancel'),
@@ -381,8 +426,15 @@ module.exports = Em.Route.extend({
           popup.set('primary', Em.I18n.t('common.save'));
           popup.set('onPrimary',
             function () {
-              var controller = App.router.get('testConnectionResultsController');
-              controller.saveClusterName();
+              var controller = App.router.get('mainMirroringTargetClusterController');
+              controller.set('isSubmitted2', true);
+              var isValid = controller.validate1();
+
+              if (!isValid) {
+                return;
+              }
+              var controller2 = App.router.get('testConnectionResultsController');
+              controller2.saveClusterName();
             }
           );
 

Modified: incubator/ambari/trunk/ambari-web/app/styles/application.less
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/styles/application.less?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/styles/application.less (original)
+++ incubator/ambari/trunk/ambari-web/app/styles/application.less Tue Apr 16 02:45:25 2013
@@ -718,9 +718,23 @@ a:focus {
         }
 
         .add-cluster-1-1{
-          width: 45%;
+          width: 100%;
           height : 100%;
           float: left;
+
+          div.error{
+            color: #b94a48;
+            .help-inline{
+              color: #b94a48;
+            }
+          }
+
+          div.error input{
+            border-color: #b94a48;
+            -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+            -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+            box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+          }
         }
         .add-cluster-1-3{
           width: 45%;
@@ -823,9 +837,22 @@ a:focus {
         }
 
           .add-cluster-1-1{
-            width: 50%;
+            width: 100%;
             height : 100%;
             float: left;
+            div.error{
+              color: #b94a48;
+              .help-inline{
+                color: #b94a48;
+              }
+            }
+
+            div.error input{
+              border-color: #b94a48;
+              -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+              -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+              box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+            }
           }
           .add-cluster-1-3{
             width: 45%;
@@ -866,7 +893,8 @@ a:focus {
 
       .add-cluster-2{
         margin : 0 auto;
-        height : 500px;
+        height : auto;
+        min-height : 350px;
         table{
           width : 60%;
           margin : 0 20%;
@@ -874,6 +902,21 @@ a:focus {
           .spacer{
             height: 20px;
           }
+
+          tr.error{
+            color: #b94a48;
+            .help-inline{
+              color: #b94a48;
+            }
+
+            input{
+              border-color: #b94a48;
+              -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+              -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+              box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+            }
+          }
+
           td {
             width : 50%;
             a.btn-success{
@@ -892,12 +935,47 @@ a:focus {
         table{
           width: 100%;
         }
+        tr.error{
+          color: #b94a48;
+          .help-inline{
+            color: #b94a48;
+          }
+        }
+
+        div.error{
+          color: #b94a48;
+          .help-inline{
+            color: #b94a48;
+          }
+        }
+
+        div.error input{
+          border-color: #b94a48;
+          -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+          -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+        }
         td.percent25 {
           width: 25%;
         }
         td.spacer{
           height: 10px;
         }
+        td{
+          .btn-group{
+            display : inline;
+            span.caret{
+              float : right;
+            }
+            ul.dropdown-menu{
+              margin-top:15px;
+            }
+          }
+          .ember-view{
+            display : inline;
+          }
+
+        }
 
         input.hyper-mini{
           width: 20px;
@@ -2773,6 +2851,32 @@ ul.filter {
   }
 }
 
+
+.jobs-sidebar{
+  width: 16%;
+  height: 100%;
+  float:left;
+  margin: 0 20px 0 0;
+  hr {
+    margin: 0;
+  }
+  ul {
+    margin: 0 0 20px 0;
+    li {
+      list-style: none;
+      margin: 8px 0;
+      a {
+        cursor: pointer;
+      }
+    }
+  }
+}
+.jobs-middleportion{
+  width: 80%;
+  height: 100%;
+  float:left;
+}
+
 /*End Mirroring*/
 
 .noDisplay {
@@ -3382,6 +3486,10 @@ i.icon-asterisks {
     margin-left: 0;
   }
 
+  .row-fluid .top-portion{
+    width : 100%;
+    height : 50px;
+  }
   .row-fluid .span12 {
     width: 100%;
     *width: 99.94680851063829%;

Added: incubator/ambari/trunk/ambari-web/app/templates/main/admin/security/disable.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/admin/security/disable.hbs?rev=1468293&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/admin/security/disable.hbs (added)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/admin/security/disable.hbs Tue Apr 16 02:45:25 2013
@@ -0,0 +1,23 @@
+{{!
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+}}
+
+{{view App.MainServiceReconfigureView}}
+<div class="btn-area">
+  <a class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}}
+    {{action done}}>{{t common.done}} </a>
+</div>
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dataset.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dataset.hbs?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dataset.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dataset.hbs Tue Apr 16 02:45:25 2013
@@ -16,86 +16,92 @@
 * limitations under the License.
 }}
 <div class="pull-left dataset-form">
-  <form class="form-horizontal">
-    <div class="add-data-set">
-      <table>
-        <tr>
-          <td class="percent25" colspan="1">
-            {{t mirroring.dataset.name}}
-          </td>
-          <td colspan="2" style="text-align: left">
-            {{view Ember.TextField valueBinding="model.newDataSet.name" class="span4"}}
-          </td>
-        </tr>
-        <tr>
-          <td class="spacer" colspan="3"></td>
-        </tr>
-        <tr>
-          <td colspan="1">
-            {{t mirroring.dataset.sourceDir}}
-          </td>
-          <td colspan="2" style="text-align: left">
-            {{view Ember.TextField valueBinding="model.newDataSet.sourceDir" class="span4"}}
-          </td>
-        </tr>
-        <tr>
-          <td class="spacer" colspan="3"></td>
-        </tr>
-        <tr>
-          <td colspan="1">
-            {{t mirroring.dataset.target}}
-          </td>
-          <td colspan="2" style="text-align: left">
-            {{view view.targetClusterSelect }}
-          </td>
-        </tr>
-        <tr>
-          <td class="spacer" colspan="3"></td>
-        </tr>
-        <tr>
-          <td class="spacer" colspan="1">
-            {{t mirroring.dataset.targetDir}}
-          </td>
-          <td colspan="2" style="text-align: left">
-            {{view Ember.TextField valueBinding="model.newDataSet.targetDir" class="span4"}}
-          </td>
-        </tr>
-        <tr>
-          <td class="spacer" colspan="3"></td>
-        </tr>
-        <tr>
-          <td colspan="1"> {{t mirroring.dataset.schedule}} </td>
-          <td colspan="2" style="text-align: left">
-            <div>
-              {{view Ember.TextField valueBinding="model.newDataSet.schedule.startDate" class="input-small datepicker"}}
-              {{view Ember.Select contentBinding="view.hourOptions.content" selectionBinding="view.hourOptions.selectedForStart" class="input-mini" optionLabelPath="content.value" optionValuePath="content.value"}}
-              {{view Ember.Select contentBinding="view.minuteOptions.content" selectionBinding="view.minuteOptions.selectedForStart" class="input-mini" optionLabelPath="content.value" optionValuePath="content.value"}}
-              {{view Ember.Select contentBinding="view.dayOrNightOptions.content" selectionBinding="view.dayOrNightOptions.selectedForStart" class="input-mini" optionLabelPath="content.name" optionValuePath="content.name"}}
-            </div>
-            <div>
-              {{t mirroring.dataset.schedule.to}}
-            </div>
-            <div>
-              {{view Ember.TextField valueBinding="model.newDataSet.schedule.endDate" class="input-small datepicker"}}
-              {{view Ember.Select contentBinding="view.hourOptions.content" selectionBinding="view.hourOptions.selectedForEnd" class="input-mini" optionLabelPath="content.value" optionValuePath="content.value"}}
-              {{view Ember.Select contentBinding="view.minuteOptions.content" selectionBinding="view.minuteOptions.selectedForEnd" class="input-mini" optionLabelPath="content.value" optionValuePath="content.value"}}
-              {{view Ember.Select contentBinding="view.dayOrNightOptions.content" selectionBinding="view.dayOrNightOptions.selectedForEnd" class="input-mini" optionLabelPath="content.name" optionValuePath="content.name"}}
+    <form class="form-horizontal">
+        <div class="add-data-set">
+            <table>
+                <tr {{bindAttr class="model.isNameError:error"}}>
+                    <td class="percent25" colspan="1">
+                      {{t mirroring.dataset.name}}
+                    </td>
+                    <td colspan="2" style="text-align: left">
+                      {{view Ember.TextField valueBinding="model.newDataSet.name" class="span4"}}
+                        <span class="help-inline">{{nameErrorMessage}}</span>
+                    </td>
+                </tr>
+                <tr>
+                    <td class="spacer" colspan="3"></td>
+                </tr>
+                <tr {{bindAttr class="model.isSourceDirError:error"}}>
+                    <td colspan="1">
+                      {{t mirroring.dataset.sourceDir}}
+                    </td>
+                    <td colspan="2" style="text-align: left">
+                      {{view Ember.TextField valueBinding="model.newDataSet.sourceDir" class="span4"}}
+                        <span class="help-inline">{{sourceDirErrorMessage}}</span>
+                    </td>
+                </tr>
+                <tr>
+                    <td class="spacer" colspan="3"></td>
+                </tr>
+                <tr {{bindAttr class="model.isTargetClusterError:error"}}>
+                    <td colspan="1">
+                      {{t mirroring.dataset.target}}
+                    </td>
+                    <td colspan="2" style="text-align: left">
+                      {{view view.targetClusterSelect }}
+                        <span class="help-inline">{{targetClusterErrorMessage}}</span>
+                    </td>
+                </tr>
+                <tr>
+                    <td class="spacer" colspan="3"></td>
+                </tr>
+                <tr {{bindAttr class="model.isTargetDirError:error"}}>
+                    <td class="spacer" colspan="1">
+                      {{t mirroring.dataset.targetDir}}
+                    </td>
+                    <td colspan="2" style="text-align: left">
+                      {{view Ember.TextField valueBinding="model.newDataSet.targetDir" class="span4"}}
+                        <span class="help-inline">{{targetDirErrorMessage}}</span>
+                    </td>
+                </tr>
+                <tr>
+                    <td class="spacer" colspan="3"></td>
+                </tr>
+                <tr>
+                    <td colspan="1"> {{t mirroring.dataset.schedule}} </td>
+                    <td colspan="2" style="text-align: left">
+                        <div {{bindAttr class="model.isStartDateError:error"}}>
+                          {{view Ember.TextField valueBinding="model.newDataSet.schedule.startDate" class="input-small datepicker"}}
+                          {{view Ember.Select contentBinding="view.hourOptions.content" selectionBinding="view.hourOptions.selectedForStart" class="input-mini" optionLabelPath="content.value" optionValuePath="content.value"}}
+                          {{view Ember.Select contentBinding="view.minuteOptions.content" selectionBinding="view.minuteOptions.selectedForStart" class="input-mini" optionLabelPath="content.value" optionValuePath="content.value"}}
+                          {{view Ember.Select contentBinding="view.dayOrNightOptions.content" selectionBinding="view.dayOrNightOptions.selectedForStart" class="input-mini" optionLabelPath="content.name" optionValuePath="content.name"}}
+                            <span class="help-inline">{{startDateErrorMessage}}</span>
+                        </div>
+                        <div>
+                          {{t mirroring.dataset.schedule.to}}
+                        </div>
+                        <div {{bindAttr class="model.isEndDateError:error"}}>
+                          {{view Ember.TextField valueBinding="model.newDataSet.schedule.endDate" class="input-small datepicker"}}
+                          {{view Ember.Select contentBinding="view.hourOptions.content" selectionBinding="view.hourOptions.selectedForEnd" class="input-mini" optionLabelPath="content.value" optionValuePath="content.value"}}
+                          {{view Ember.Select contentBinding="view.minuteOptions.content" selectionBinding="view.minuteOptions.selectedForEnd" class="input-mini" optionLabelPath="content.value" optionValuePath="content.value"}}
+                          {{view Ember.Select contentBinding="view.dayOrNightOptions.content" selectionBinding="view.dayOrNightOptions.selectedForEnd" class="input-mini" optionLabelPath="content.name" optionValuePath="content.name"}}
+                            <span class="help-inline">{{endDateErrorMessage}}</span>
+                        </div>
 
-            </div>
-
-            <div class="each-row">
-              {{t mirroring.dataset.schedule.repeatEvery}}
-              {{view Ember.TextField valueBinding="view.repeatNumberSelected" class="input-mini"}}
-              {{view Ember.Select contentBinding="view.repeatOptions.content" selectionBinding="view.repeatOptions.repeatOptionSelected" class="input-small" optionLabelPath="content.value" optionValuePath="content.value"}}
-            </div>
-          </td>
-        </tr>
-      </table>
-    </div>
-  </form>
+                        <div {{bindAttr class=" :each-row model.isFrequencyError:error"}}>
+                          {{t mirroring.dataset.schedule.repeatEvery}}
+                          {{view Ember.TextField valueBinding="view.repeatNumberSelected" class="input-mini"}}
+                          {{view Ember.Select contentBinding="view.repeatOptions.content" selectionBinding="view.repeatOptions.repeatOptionSelected" class="input-small" optionLabelPath="content.value" optionValuePath="content.value"}}
+                            <span class="help-inline">{{frequencyErrorMessage}}</span>
+                        </div>
+                    </td>
+                </tr>
+            </table>
+        </div>
+    </form>
 </div>
 {{#if isPopupForEdit}}
-  <div class="pull-right dataset-delete">
-    <a {{action deleteDatasetClick target="controller"}} class="btn btn-danger">{{t common.delete}}</a>
-  </div>
+    <div class="pull-right dataset-delete">
+        <a {{action deleteDatasetClick target="controller"}} class="btn btn-danger">{{t common.delete}}</a>
+    </div>
 {{/if}}
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/datasets.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/datasets.hbs?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/datasets.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/datasets.hbs Tue Apr 16 02:45:25 2013
@@ -16,6 +16,11 @@
 * limitations under the License.
 }}
 <div>
+    <div class="top-portion">
+        <ul class="breadcrumb">
+            <li><a href="#/main/mirroring">{{t mirroring.dataset.AllDataSets}}</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}}>

Modified: incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dropdown.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dropdown.hbs?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dropdown.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/dropdown.hbs Tue Apr 16 02:45:25 2013
@@ -15,14 +15,15 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 }}
-<div class="btn-group" >
-  <button class="btn targetClusterDD">{{view.selected.title}}</button>
-  <button class="btn dropdown-toggle" data-toggle="dropdown" {{!action "dropdownToggle" target="view" on="click"}}>
-    <span class="caret"></span>
-  </button>
-  <ul class="dropdown-menu">
-    {{#each view.listOfOptions}}
-      <li {{!bindAttr class="view.isActive:active"   use this to hide the selected one in the drop down }}><a href="#" {{action "select" this target="view" on="click"}}>{{title}}</a></li>
-    {{/each}}
-   </ul>
+<div class="btn-group">
+    <a class="btn dropdown-toggle targetClusterDD" data-toggle="dropdown" href="#">
+      {{view.selected.title}}
+        <span class="caret"></span>
+    </a>
+    <ul class="dropdown-menu">
+      {{#each view.listOfOptions}}
+          <li {{!bindAttr class="view.isActive:active"   use this to hide the selected one in the drop down }}><a
+                  href="#" {{action "select" this target="view" on="click"}}>{{title}}</a></li>
+      {{/each}}
+    </ul>
 </div>
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/jobs.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/jobs.hbs?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/jobs.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/jobs.hbs Tue Apr 16 02:45:25 2013
@@ -16,122 +16,137 @@
 * limitations under the License.
 }}
 <div class="row-fluid">
-    <div class="span2 mirroring-sidebar">
-      <h5>{{t common.details}} <span class="pull-right"><a href="#" {{action gotoEditDataset view.dataset}}>{{t common.edit}}</a></span></h5>
-      <hr />
-      <p>{{t mirroring.dataset.source}}: <span class="pull-right">{{view.dataset.sourceClusterName}}</span></p>
-      <p>{{t mirroring.dataset.target}}: <span class="pull-right">{{view.dataset.targetClusterName}}</span></p>
-      <h5>{{t common.stats}}</h5>
-      <hr />
-      <p>{{t mirroring.dataset.avgData}}: <span class="pull-right">{{view.dataset.avgData}}</span></p>
-      <p>{{t mirroring.dataset.dateCreated}}: <span class="pull-right">{{view.dataset.createdDate}}</span></p>
-    </div>
-    <div class="span10">
+    <div class="top-portion">
+        <ul class="breadcrumb">
+            <li><a href="#/main/mirroring">{{t mirroring.dataset.AllDataSets}}</a> <span class="divider">/</span></li>
+            <li class="active">{{view.dataset.name}}</li>
+        </ul>
       {{#if App.isAdmin}}
           <div class="mirroring-top-nav button-section pull-right">
             {{#if isScheduled}}
                 <span class="label label-success">{{content.status}}</span>
-              <a href="javascript:void(null)" data-toggle="modal" class="btn btn-danger" {{action "suspend" target="controller"}}>
-                <i class="icon-pause"></i>
-                {{actionDesc}}
-              </a>
+                <a href="javascript:void(null)" data-toggle="modal"
+                   class="btn btn-danger" {{action "suspend" target="controller"}}>
+                    <i class="icon-pause"></i>
+                  {{actionDesc}}
+                </a>
             {{else}}
                 <span class="label label-important">{{content.status}}</span>
-                <a href="javascript:void(null)" data-toggle="modal" class="btn btn-success" {{action "schedule" target="controller"}}>
+                <a href="javascript:void(null)" data-toggle="modal"
+                   class="btn btn-success" {{action "schedule" target="controller"}}>
                     <i class="icon-play"></i>
                   {{actionDesc}}
                 </a>
             {{/if}}
           </div>
       {{/if}}
-    <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.idSort}}
-              {{view view.parentView.startSort}}
-              {{view view.parentView.endSort}}
-              {{view view.parentView.durationSort}}
-              {{view view.parentView.dataSort}}
-              <th>
-                  {{t common.status}}
-              </th>
-
-            {{/view}}
-        </tr>
-        <tr>
-          <th class="first"> </th>
-          <th>{{view view.idFilterView}}</th>
-          <th>{{view view.startFilterView}}</th>
-          <th>{{view view.endFilterView}}</th>
-          <th>{{view view.durationFilterView}}</th>
-          <th>{{view view.dataFilterView}}</th>
-        </tr>
-        </thead>
-        <tbody>
-        {{#if view.pageContent}}
-          {{#each job in view.pageContent}}
-            {{#view view.JobView contentBinding="job"}}
-
-              <td class="first">
-              </td>
-
-              <td>{{unbound job.id}}</td>
-              <td>{{view.startFormatted}}</td>
-              <td>{{view.endFormatted}}</td>
-
-              <td>
-                {{view.durationFormatted}}
-              </td>
-
-              <td>{{job.data}}</td>
-              <td>
-
-                {{#if view.canActionBeTaken}}
-                    <div class="btn-group">
-                        <a {{bindAttr class="view.statusClass"}} data-toggle="dropdown" href="#">
-                            {{view.content.status}}
-                            <span class="caret"></span>
-                        </a>
-                        <ul class="dropdown-menu">
-                          {{#each view.listOfOptions}}
-                              <li><a href="#" {{action "changeStatus" this target="view" on="click"}}>{{title}}</a></li>
-                          {{/each}}
-                        </ul>
-                    </div>
-                 {{else}}
-                    {{#if view.isKilled}}
-                      <span class="label label-important">{{view.content.status}}</span>
-                    {{else}}
-                      <span class="label label-info">{{view.content.status}}</span>
-                    {{/if}}
-                {{/if}}
-              </td>
-            {{/view}}
-          {{/each}}
-        {{else}}
-          <tr>
-              <td class="first"></td>
-              <td colspan="6">
-                  {{t mirroring.table.noJobs}}
-              </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 class="jobs-sidebar">
+        <h5>{{t common.details}} <span class="pull-right"><a
+                href="#" {{action gotoEditDataset view.dataset}}>{{t common.edit}}</a></span></h5>
+        <hr/>
+        <p>{{t mirroring.dataset.source}}: <span class="pull-right">{{view.dataset.sourceClusterName}}</span></p>
+
+        <p>{{t mirroring.dataset.target}}: <span class="pull-right">{{view.dataset.targetClusterName}}</span></p>
+        <h5>{{t common.stats}}</h5>
+        <hr/>
+        <p>{{t mirroring.dataset.avgData}}: <span class="pull-right">{{view.dataset.avgData}}</span></p>
+
+        <p>{{t mirroring.dataset.dateCreated}}: <span class="pull-right">{{view.dataset.createdDate}}</span></p>
+    </div>
+    <div class="jobs-middleportion">
+        <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.idSort}}
+                    {{view view.parentView.startSort}}
+                    {{view view.parentView.endSort}}
+                    {{view view.parentView.durationSort}}
+                    {{view view.parentView.dataSort}}
+                      <th>
+                        {{t common.status}}
+                      </th>
+
+                  {{/view}}
+                </tr>
+                <tr>
+                    <th class="first"></th>
+                    <th>{{view view.idFilterView}}</th>
+                    <th>{{view view.startFilterView}}</th>
+                    <th>{{view view.endFilterView}}</th>
+                    <th>{{view view.durationFilterView}}</th>
+                    <th>{{view view.dataFilterView}}</th>
+                </tr>
+                </thead>
+                <tbody>
+                  {{#if view.pageContent}}
+                    {{#each job in view.pageContent}}
+                      {{#view view.JobView contentBinding="job"}}
+
+                      <td class="first">
+                      </td>
+
+                      <td>{{unbound job.id}}</td>
+                      <td>{{view.startFormatted}}</td>
+                      <td>{{view.endFormatted}}</td>
+
+                      <td>
+                        {{view.durationFormatted}}
+                      </td>
+
+                      <td>{{job.data}}</td>
+                      <td>
+
+                        {{#if view.canActionBeTaken}}
+                            <div class="btn-group">
+                                <a {{bindAttr class="view.statusClass"}} data-toggle="dropdown" href="#">
+                                  {{view.content.status}}
+                                    <span class="caret"></span>
+                                </a>
+                                <ul class="dropdown-menu">
+                                  {{#each view.listOfOptions}}
+                                      <li>
+                                          <a href="#" {{action "changeStatus" this target="view" on="click"}}>{{title}}</a>
+                                      </li>
+                                  {{/each}}
+                                </ul>
+                            </div>
+                        {{else}}
+                          {{#if view.isKilled}}
+                              <span class="label label-important">{{view.content.status}}</span>
+                          {{else}}
+                              <span class="label label-info">{{view.content.status}}</span>
+                          {{/if}}
+                        {{/if}}
+                      </td>
+                      {{/view}}
+                    {{/each}}
+                  {{else}}
+                  <tr>
+                      <td class="first"></td>
+                      <td colspan="6">
+                        {{t mirroring.table.noJobs}}
+                      </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>
-      </div>
     </div>
-  </div>
 </div>
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnection.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnection.hbs?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnection.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnection.hbs Tue Apr 16 02:45:25 2013
@@ -20,33 +20,38 @@
     <div class="add-cluster-1">
         <div class="add-cluster-1-1">
             <h4>Enter the URLs for the following</h4>
-            <div class="each-row">
-                NameNode Web UI
-            </div>
-            <div class="each-row">
-              {{view Ember.TextField valueBinding="content.targetCluster.nameNodeWebUrl" class="span4"}}
-            </div>
 
-            <div class="each-row">
-                NameNode RPC
-            </div>
-            <div class="each-row">
-              {{view Ember.TextField valueBinding="content.targetCluster.nameNodeRpcUrl" class="span4"}}
+            <div {{bindAttr class=" :each-row content.isNameNodeWebUrlError:error"}}>
+              {{t mirroring.targetcluster.nameNodeWebUrl}}
             </div>
-            <div class="each-row">
-                Oozie Server
+            <div {{bindAttr class=" :each-row content.isNameNodeWebUrlError:error"}}>
+              {{view Ember.TextField valueBinding="content.targetCluster.nameNodeWebUrl" class="span4" placeholder="http://[NameNode Web UI Server]:50070"}}
+                <span class="help-inline">{{content.nameNodeWebUrlErrorMessage}}</span>
             </div>
-            <div class="each-row">
-              {{view Ember.TextField valueBinding="content.targetCluster.oozieServerUrl" class="span4"}}
+
+            <div {{bindAttr class=" :each-row content.isNameNodeRpcUrlError:error"}}>
+              {{t mirroring.targetcluster.nameNodeRpcUrl}}
             </div>
-        </div>
-        {{#if view.parentView.parentView.controller.model.isPopupForEdit}}
-        <div class="add-cluster-1-3">
-            <div class="each-row pull-right">
-              <a {{action deleteTargetCluster target="view.parentView.parentView.controller"}} class="btn btn-danger">{{t common.delete}}</a>
+            <div {{bindAttr class=" :each-row content.isNameNodeRpcUrlError:error"}}>
+              {{view Ember.TextField valueBinding="content.targetCluster.nameNodeRpcUrl" class="span4" placeholder="http://[NameNode RPC Server]:8020"}}
+                <span class="help-inline">{{content.nameNodeRpcUrlErrorMessage}}</span>
+            </div>
+            <div {{bindAttr class=" :each-row content.isOozieServerUrlError:error"}}>
+              {{t mirroring.targetcluster.oozieServerUrl}}
+            </div>
+            <div {{bindAttr class=" :each-row content.isOozieServerUrlError:error"}}>
+              {{view Ember.TextField valueBinding="content.targetCluster.oozieServerUrl" class="span4" placeholder="http://[Oozie server]:11000"}}
+                <span class="help-inline">{{content.oozieServerUrlErrorMessage}}</span>
             </div>
         </div>
-        {{/if}}
+      {{#if view.parentView.parentView.controller.model.isPopupForEdit}}
+          <div class="add-cluster-1-3">
+              <div class="each-row pull-right">
+                  <a {{action deleteTargetCluster target="view.parentView.parentView.controller"}}
+                          class="btn btn-danger">{{t common.delete}}</a>
+              </div>
+          </div>
+      {{/if}}
 
     </div>
 </form>
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnectionResults.hbs
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnectionResults.hbs?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnectionResults.hbs (original)
+++ incubator/ambari/trunk/ambari-web/app/templates/main/mirroring/testConnectionResults.hbs Tue Apr 16 02:45:25 2013
@@ -17,56 +17,58 @@
 }}
 
 <form class="form-horizontal">
-  <div class="add-cluster-2">
+    <div class="add-cluster-2">
 
-   <table>
-       <tr>
-           <td>NameNode Web UI..50070</td>
-           <td>
-             {{#if isNameNodeWebUIConnected}}
-             <i class="icon-ok"></i>
-             {{else}}
-                 Connecting...
-             {{/if}}
-           </td>
-       </tr>
-       <tr class="spacer">
-           <td colspan="2"/>
-       </tr>
-       <tr>
-           <td>NameNode RPC..8020</td>
-           <td>
-             {{#if isNameNodeRpcConnected}}
-                 <i class="icon-ok"></i>
-             {{else}}
-                 Connecting...
-             {{/if}}
-           </td>
-       </tr>
-       <tr class="spacer">
-           <td colspan="2"/>
-       </tr>
-       <tr>
-           <td>Oozie server..11000</td>
-           <td>
-             {{#if isOozieServerConnected}}
-                 <i class="icon-ok"></i>
-             {{else}}
-                 Connecting...
-             {{/if}}
-           </td>
-       </tr>
-       <tr class="spacer">
-           <td colspan="2"/>
-       </tr>
-       <tr>
-              <td>{{t mirroring.targetcluster.enterClusterName}}</td>
-              <td>{{view Ember.TextField valueBinding="content.targetCluster.clusterName" disabledBinding="shouldBeDisabled" }} </td>
-          </tr>
-       <tr class="spacer">
-           <td colspan="2" ></td>
-       </tr>
-   </table>
-  </div>
+        <table>
+            <tr>
+                <td>NameNode Web UI..50070</td>
+                <td>
+                  {{#if isNameNodeWebUIConnected}}
+                      <i class="icon-ok"></i>
+                  {{else}}
+                      Connecting...
+                  {{/if}}
+                </td>
+            </tr>
+            <tr class="spacer">
+                <td colspan="2"/>
+            </tr>
+            <tr>
+                <td>NameNode RPC..8020</td>
+                <td>
+                  {{#if isNameNodeRpcConnected}}
+                      <i class="icon-ok"></i>
+                  {{else}}
+                      Connecting...
+                  {{/if}}
+                </td>
+            </tr>
+            <tr class="spacer">
+                <td colspan="2"/>
+            </tr>
+            <tr>
+                <td>Oozie server..11000</td>
+                <td>
+                  {{#if isOozieServerConnected}}
+                      <i class="icon-ok"></i>
+                  {{else}}
+                      Connecting...
+                  {{/if}}
+                </td>
+            </tr>
+            <tr class="spacer">
+                <td colspan="2"/>
+            </tr>
+            <tr {{bindAttr class="content.isClusterNameError:error"}}>
+                <td>{{t mirroring.targetcluster.enterClusterName}}</td>
+                <td>{{view Ember.TextField valueBinding="content.targetCluster.clusterName" disabledBinding="shouldBeDisabled" }}
+                    <span class="help-inline">{{content.clusterNameErrorMessage}}</span>
+                </td>
+            </tr>
+            <tr class="spacer">
+                <td colspan="2"></td>
+            </tr>
+        </table>
+    </div>
 
 </form>
\ No newline at end of file

Modified: incubator/ambari/trunk/ambari-web/app/utils/config.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/utils/config.js?rev=1468293&r1=1468292&r2=1468293&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/utils/config.js (original)
+++ incubator/ambari/trunk/ambari-web/app/utils/config.js Tue Apr 16 02:45:25 2013
@@ -51,6 +51,7 @@ App.config = Em.Object.create({
    * }
    */
   loadedConfigurationsCache: {},
+
   /**
    * Array of global "service/desired_tag/actual_tag" strings which
    * indicate different configurations. We cache these so that 
@@ -623,7 +624,7 @@ App.config = Em.Object.create({
       }
     }
     var params = urlParams.join('|');
-    if(urlParams.length){
+    if (urlParams.length) {
       App.ajax.send({
         name: 'config.host_overrides',
         sender: this,