Browse Source

AMBARI-6736 Config History: E2E Integration of Config Version History Flow UI. (atkach)

atkach 10 years ago
parent
commit
bb91e787a6

+ 22 - 12
ambari-web/app/controllers/global/configuration_controller.js

@@ -76,6 +76,8 @@ App.ConfigurationController = Em.Controller.extend({
   loadFromServer: function (tags) {
     var dfd = $.Deferred();
     var loadedConfigs = [];
+    var self = this;
+
     App.config.loadConfigsByTags(tags).done(function (data) {
       if (data.items) {
         data.items.forEach(function (item) {
@@ -84,20 +86,28 @@ App.ConfigurationController = Em.Controller.extend({
         });
       }
     }).complete(function () {
-        var storedConfigs = App.db.getConfigs();
-        loadedConfigs.forEach(function (loadedSite) {
-          var storedSite = storedConfigs.findProperty('type', loadedSite.type);
-          if (storedSite) {
-            storedSite.tag = loadedSite.tag;
-            storedSite.properties = loadedSite.properties;
-            storedSite.properties_attributes = loadedSite.properties_attributes;
-          } else {
-            storedConfigs.push(loadedSite);
-          }
-        });
-        App.db.setConfigs(storedConfigs);
+        self.saveToDB(loadedConfigs);
         dfd.resolve(loadedConfigs);
       });
     return dfd.promise();
+  },
+
+  /**
+   * save properties obtained from server to local DB
+   * @param loadedConfigs
+   */
+  saveToDB: function (loadedConfigs) {
+    var storedConfigs = App.db.getConfigs();
+    loadedConfigs.forEach(function (loadedSite) {
+      var storedSite = storedConfigs.findProperty('type', loadedSite.type);
+      if (storedSite) {
+        storedSite.tag = loadedSite.tag;
+        storedSite.properties = loadedSite.properties;
+        storedSite.properties_attributes = loadedSite.properties_attributes;
+      } else {
+        storedConfigs.push(loadedSite);
+      }
+    });
+    App.db.setConfigs(storedConfigs);
   }
 });

+ 113 - 21
ambari-web/app/controllers/main/service/info/configs.js

@@ -46,6 +46,8 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   compareServiceVersion: null,
   // contain Service Config Property, when user proceed from Select Config Group dialog
   overrideToAdd: null,
+  //latest version of service config versions
+  currentVersion: null,
   serviceConfigs: function () {
     return App.config.get('preDefinedServiceConfigs');
   }.property('App.config.preDefinedServiceConfigs'),
@@ -132,7 +134,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
    * clear and set properties to default value
    */
   clearStep: function () {
-    this.set("isApplyingChanges", false)
+    this.set("isApplyingChanges", false);
     this.set('isInit', true);
     this.set('hash', null);
     this.set('forceTransition', false);
@@ -211,20 +213,101 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
     App.config.loadAdvancedConfig(serviceName, function (properties) {
       advancedConfigs.pushObjects(properties);
       self.set('advancedConfigs', advancedConfigs);
-      self.loadServiceTags();
+      if (App.get('supports.configHistory')) {
+        self.loadServiceConfigVersions();
+      } else {
+        self.loadServiceTagsAndGroups();
+      }
     });
   },
 
   /**
-   * load config tags of service
+   * get service config versions of current service
+   */
+  loadServiceConfigVersions: function () {
+    var self = this;
+
+    App.ajax.send({
+      name: 'service.serviceConfigVersions.get',
+      data: {
+        serviceName: this.get('content.serviceName')
+      },
+      sender: this,
+      success: 'loadServiceConfigVersionsSuccess',
+      error: 'loadServiceConfigVersionsError'
+    }).complete(function () {
+        self.loadSelectedVersion();
+      });
+  },
+
+  /**
+   * load service config versions to model
+   * set currentVersion
+   * @param data
+   * @param opt
+   * @param params
+   */
+  loadServiceConfigVersionsSuccess: function (data, opt, params) {
+    var currentVersion = Math.max.apply(this, data.items.mapProperty('serviceconfigversion'));
+
+    this.set('currentVersion', currentVersion);
+    App.serviceConfigVersionsMapper.map(data);
+  },
+
+  /**
+   * get selected service config version
+   * In case selected version is undefined then take currentVersion
+   * @param version
    */
-  loadServiceTags: function () {
+  loadSelectedVersion: function (version) {
+    var self = this;
+
+    App.ajax.send({
+      name: 'service.serviceConfigVersion.get',
+      sender: this,
+      data: {
+        serviceName: this.get('content.serviceName'),
+        serviceConfigVersion: version || this.get('currentVersion')
+      },
+      success: 'loadSelectedVersionSuccess'
+    }).complete(function () {
+        self.loadServiceTagsAndGroups();
+      });
+  },
+
+  /**
+   * set cluster to site tag map
+   * @param data
+   * @param opt
+   * @param params
+   */
+  loadSelectedVersionSuccess: function (data, opt, params) {
+    var serviceConfigsDef = this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName'));
+    var siteToTagMap = {};
+    var configTypesRendered = Object.keys(serviceConfigsDef.get('configTypesRendered'));
+
+    configTypesRendered.forEach(function (siteName) {
+      if (data.items[0].configurations.someProperty('type', siteName)) {
+        siteToTagMap[siteName] = data.items[0].configurations.findProperty('type', siteName).tag;
+      } else {
+        siteToTagMap[siteName] = 'version1';
+      }
+    }, this);
+
+    App.router.get('configurationController').saveToDB(data.items[0].configurations);
+    this.loadedClusterSiteToTagMap = siteToTagMap;
+    this.loadServiceTagsAndGroups();
+  },
+
+  /**
+   * load config groups of service
+   */
+  loadServiceTagsAndGroups: function () {
     App.ajax.send({
       name: 'config.tags_and_groups',
       sender: this,
       data: {
         serviceName: this.get('content.serviceName'),
-        serviceConfigsDef: this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName')),
         urlParams: "&config_groups/ConfigGroup/tag=" + this.get('content.serviceName')
       },
       success: 'loadServiceConfigsSuccess'
@@ -233,26 +316,24 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
 
   loadServiceConfigsSuccess: function (data, opt, params) {
     if (data) {
-      this.setConfigGroups.apply(this, Array.prototype.slice.call(arguments, 0));
+      this.setConfigGroups(data, opt, params);
     } else {
-      App.ajax.send({
-        name: 'config.tags',
-        sender: this,
-        data: App.permit(params, ['clusterName', 'serviceConfigsDef', 'serviceName']),
-        success: 'setConfigGroups'
-      });
+      if (!App.get('supports.configHistory')) {
+        App.ajax.send({
+          name: 'config.tags',
+          sender: this,
+          data: App.permit(params, ['clusterName', 'serviceConfigsDef', 'serviceName']),
+          success: 'setConfigGroups'
+        });
+      }  else {
+        this.setConfigGroups(data, opt, params);
+      }
     }
   },
 
-  setConfigGroups: function (data, opt, params) {
-    var serviceConfigsDef = params.serviceConfigsDef;
-    var serviceName = this.get('content.serviceName');
-    var displayName = this.get('content.displayName');
-    console.debug("loadServiceConfigs(): data=", data);
-    // Create default configuration group
-    var selectedConfigGroup;
+  setConfigTags: function (data, opt, params) {
+    var serviceConfigsDef = this.get('serviceConfigs').findProperty('serviceName', this.get('content.serviceName'));
     var siteToTagMap = {};
-    var hostsLength = App.router.get('mainHostController.hostsCountMap.TOTAL');
     var configTypesRendered = Object.keys(serviceConfigsDef.get('configTypesRendered'));
     configTypesRendered.forEach(function (siteName) {
       if (data.Clusters.desired_configs[siteName]) {
@@ -262,10 +343,21 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
       }
     }, this);
     this.loadedClusterSiteToTagMap = siteToTagMap;
+  },
+
+  setConfigGroups: function (data, opt, params) {
+    if (!App.get('supports.configHistory')) {
+      this.setConfigTags(data, opt, params);
+    }
+    var serviceName = this.get('content.serviceName');
+    var displayName = this.get('content.displayName');
+    var selectedConfigGroup;
+    var hostsLength = App.router.get('mainHostController.hostsCountMap.TOTAL');
+
     //parse loaded config groups
     if (App.supports.hostOverrides) {
       var configGroups = [];
-      if (data.config_groups && data.config_groups.length) {
+      if (data && data.config_groups && data.config_groups.length) {
         data.config_groups.forEach(function (item) {
           item = item.ConfigGroup;
           if (item.tag === this.get('content.serviceName')) {

+ 9 - 2
ambari-web/app/models/service_config_version.js

@@ -30,12 +30,19 @@ App.ServiceConfigVersion = DS.Model.extend({
   notes: DS.attr('string'),
   service: DS.belongsTo('App.Service'),
   index: DS.attr('number'),
+  briefNotes: function () {
+    var length = this.get('isCurrent') ? 20 : 40;
+    return (typeof this.get('notes') === 'string') ? this.get('notes').slice(0, length) : "";
+  }.property('notes', 'isCurrent'),
   serviceVersion: function () {
     return this.get('serviceName') + ': ' + this.get('version');
   }.property('serviceName', 'version'),
   modifiedDate: function () {
     return dateUtil.dateFormat(this.get('appliedTime'));
   }.property('createTime'),
+  shortModifiedDate: function () {
+    return dateUtil.dateFormat(this.get('appliedTime'), 'MMM DD, YYYY');
+  }.property('createTime'),
   //TODO set isCurrent value from API response
   isCurrent: false,
   /**
@@ -43,8 +50,8 @@ App.ServiceConfigVersion = DS.Model.extend({
    */
   isRequested: DS.attr('boolean'),
   isRestartRequired: function () {
-    return this.get('service.isRestartRequired');
-  }.property('service.isRestartRequired')
+    return this.get('service.isRestartRequired') && this.get('isCurrent');
+  }.property('service.isRestartRequired', 'isCurrent')
 });
 
 App.ServiceConfigVersion.FIXTURES = [];

+ 1 - 1
ambari-web/app/styles/application.less

@@ -4888,7 +4888,7 @@ ul.inline li {
           text-align: center;
         }
         .date {
-          margin-left: 40px;
+          margin-left: 35px;
           line-height: 30px;
           white-space: nowrap;
         }

+ 10 - 7
ambari-web/app/templates/common/configs/config_history_flow.hbs

@@ -25,10 +25,13 @@
               <div class="arrow-box pull-left"><div class="big-arrow-right"></div></div>
               <div {{bindAttr class=":box :pull-right serviceVersion.isDisplayed:displayed"}}>
                   <div class="top-right-label">{{serviceVersion.version}}</div>
-                  <p class="date">{{serviceVersion.modifiedDate}}</p>
-                  <p class="content">{{serviceVersion.author}}:&nbsp;{{serviceVersion.notes}}</p>
+                  <p class="date">{{serviceVersion.shortModifiedDate}}</p>
+                  <p class="content">{{serviceVersion.author}}:&nbsp;{{serviceVersion.briefNotes}}</p>
                   {{#if serviceVersion.isCurrent}}
-                    <div class="current-label label label-success">{{t common.current}}</div>
+                    <div class="current-label label label-success">
+                      {{t common.latest}}
+                      <i {{bindAttr class=":icon-refresh :restart-required-service view.displayedServiceVersion.isRestartRequired::hidden"}}></i>
+                    </div>
                   {{/if}}
               </div>
           </div>
@@ -70,20 +73,20 @@
             </ul>
         </div>
         <div class="label-wrapper span8">
-            <span {{bindAttr class=":label view.displayedServiceVersion.isCurrent:label-success"}}>{{t common.current}}: {{view.displayedServiceVersion.version}}</span>
+            <span {{bindAttr class=":label view.displayedServiceVersion.isCurrent:label-success"}}>{{t common.latest}}: {{view.displayedServiceVersion.version}}</span>
             <strong>{{view.displayedServiceVersion.author}}</strong>&nbsp;{{t dashboard.configHistory.info-bar.authoredOn}}&nbsp;<strong>{{view.displayedServiceVersion.modifiedDate}}</strong>
         </div>
         <div class="pull-right">
             {{#if view.displayedServiceVersion.isCurrent}}
-                <button class="btn" {{action cancel target="view"}}>{{t common.cancel}}</button>
-                <button class="btn btn-success" {{action save target="view"}}>{{t common.save}}</button>
+                <button class="btn" {{action doCancel target="controller"}}>{{t common.cancel}}</button>
+                <button class="btn btn-success" {{bindAttr disabled="isSubmitDisabled"}} {{action save target="view"}}>{{t common.save}}</button>
             {{else}}
                 <button class="btn btn-success" {{action revert target="view"}}>{{t dashboard.configHistory.info-bar.revert.button}}</button>
             {{/if}}
         </div>
     </div>
     <div class="label-wrapper">
-      {{view.shortNotes}} {{#if view.showMoreLink}}<a class="pointer">{{t jobs.hive.more}}</a>{{/if}}
+      {{view.shortNotes}} {{#if view.showMoreLink}}<a class="pointer" {{bindAttr title="view.displayedServiceVersion.notes"}}>{{t jobs.hive.more}}</a>{{/if}}
     </div>
   </div>
 </div>

+ 8 - 6
ambari-web/app/templates/main/service/info/configs.hbs

@@ -45,12 +45,14 @@
     <div class="clearfix"></div>
     {{view App.ServiceConfigView filterBinding="controller.filter" columnsBinding="controller.filterColumns"}}
     {{#if App.isAdmin}}
-      <p class="pull-right">
-        <!--<input class="btn btn-primary" type="button" value="Save" {{!bindAttr disabled="isSubmitDisabled"}} />-->
-        <a class="btn" {{action doCancel target="controller"}}>{{t common.cancel}}</a>
-        <a class="btn btn-primary" {{bindAttr disabled="isSubmitDisabled"}}
-          {{action restartServicePopup target="controller"}}>{{t common.save}}</a>
-      </p>
+      {{#unless App.supports.configHistory}}
+          <p class="pull-right">
+              <!--<input class="btn btn-primary" type="button" value="Save" {{!bindAttr disabled="isSubmitDisabled"}} />-->
+              <a class="btn" {{action doCancel target="controller"}}>{{t common.cancel}}</a>
+              <a class="btn btn-primary" {{bindAttr disabled="isSubmitDisabled"}}
+                {{action restartServicePopup target="controller"}}>{{t common.save}}</a>
+          </p>
+      {{/unless}}
     {{/if}}
   {{else}}
     <div class="spinner"></div>

+ 8 - 0
ambari-web/app/utils/ajax/ajax.js

@@ -1765,6 +1765,14 @@ var urls = {
         url: data.url
       }
     }
+  },
+  'service.serviceConfigVersions.get': {
+    real: '/clusters/{clusterName}/configurations/serviceconfigversions?service_name={serviceName}&fields=serviceconfigversion,user,appliedtime,createtime,service_name&minimal_response=true',
+    mock: ''
+  },
+  'service.serviceConfigVersion.get': {
+    real: '/clusters/{clusterName}/configurations/serviceconfigversions?service_name={serviceName}&serviceconfigversion={serviceConfigVersion}',
+    mock: ''
   }
 };
 /**

+ 6 - 11
ambari-web/app/utils/date.js

@@ -46,25 +46,20 @@ module.exports = {
   },
 
   /**
-   * Convert timestamp to date-string 'DAY_OF_THE_WEEK, MONTH DAY, YEAR HOURS:MINUTES'
+   * Convert timestamp to date-string
+   * default format - 'DAY_OF_THE_WEEK, MONTH DAY, YEAR HOURS:MINUTES'
    *
    * @param {number} timestamp
-   * @param {bool} showSeconds should seconds be added to result string
-   * @param {bool} showMilliseconds should miliseconds be added to result string (if <code>showSeconds</code> is false, milliseconds wouldn't be added)
+   * @param {bool} format
    * @return {*} date
    * @method dateFormat
    */
-  dateFormat: function (timestamp, showSeconds, showMilliseconds) {
+  dateFormat: function (timestamp, format) {
     if (!validator.isValidInt(timestamp)) {
       return timestamp;
     }
-    var format = 'ddd, MMM DD, YYYY HH:mm';
-    if (showSeconds) {
-      format += ':ss';
-      if (showMilliseconds) {
-        format += ':SSS';
-      }
-    }
+    format = format || 'ddd, MMM DD, YYYY HH:mm';
+
     return moment((new Date(timestamp)).toISOString().replace('Z', '')).format(format);
   },
 

+ 31 - 105
ambari-web/app/views/common/configs/config_history_flow.js

@@ -25,8 +25,10 @@ App.ConfigHistoryFlowView = Em.View.extend({
    * index of the first element(service version box) in viewport
    */
   startIndex: 0,
-  showLeftArrow: true,
+  showLeftArrow: false,
   showRightArrow: false,
+  VERSIONS_IN_FLOW: 5,
+  VERSIONS_IN_DROPDOWN: 6,
   /**
    * flag identify whether to show all versions or short list of them
    */
@@ -44,23 +46,23 @@ App.ConfigHistoryFlowView = Em.View.extend({
    */
   showMoreLink: function () {
     //100 is number of symbols that fit into label
-    return (this.get('currentServiceVersion.notes.length') > 100);
-  }.property('currentServiceVersion.notes.length'),
+    return (this.get('displayedServiceVersion.notes.length') > 100);
+  }.property('displayedServiceVersion.notes.length'),
   /**
    * formatted notes ready to display
    */
   shortNotes: function () {
     //100 is number of symbols that fit into label
     if (this.get('showMoreLink')) {
-      return this.get('currentServiceVersion.notes').slice(0, 100) + '...';
+      return this.get('displayedServiceVersion.notes').slice(0, 100) + '...';
     }
-    return this.get('currentServiceVersion.notes');
-  }.property('currentServiceVersion'),
+    return this.get('displayedServiceVersion.notes');
+  }.property('displayedServiceVersion'),
   /**
    * service versions which in viewport and visible to user
    */
   visibleServiceVersion: function () {
-    return this.get('serviceVersions').slice(this.get('startIndex'), (this.get('startIndex') + 5));
+    return this.get('serviceVersions').slice(this.get('startIndex'), (this.get('startIndex') + this.VERSIONS_IN_FLOW));
   }.property('startIndex'),
 
   /**
@@ -68,31 +70,34 @@ App.ConfigHistoryFlowView = Em.View.extend({
    * by default 6 is number of items in short list
    */
   dropDownList: function () {
-    var serviceVersions = this.get('serviceVersions').without(this.get('currentServiceVersion')).slice(0).reverse();
+    var serviceVersions = this.get('serviceVersions').without(this.get('displayedServiceVersion')).slice(0).reverse();
     if (this.get('showFullList')) {
       return serviceVersions;
     }
-    return serviceVersions.slice(0, 6);
-  }.property('serviceVersions', 'showFullList'),
+    return serviceVersions.slice(0, this.VERSIONS_IN_DROPDOWN);
+  }.property('serviceVersions', 'showFullList', 'displayedServiceVersion'),
 
   openFullList: function (event) {
     event.stopPropagation();
     this.set('showFullList', true);
   },
   hideFullList: function (event) {
-    this.set('showFullList', false);
+    this.set('showFullList', !(this.get('serviceVersions.length') > this.VERSIONS_IN_DROPDOWN));
   },
 
   willInsertElement: function () {
     var serviceVersions = this.get('serviceVersions');
     var startIndex = 0;
-    var numberOfDisplayed = 5;
 
-    this.get('serviceVersions').findProperty('appliedTime', Math.max.apply(this, this.get('serviceVersions').mapProperty('appliedTime'))).set('isCurrent', true);
-    this.get('serviceVersions').findProperty('isCurrent').set('isDisplayed', true);
+    serviceVersions.setEach('isCurrent', false);
+    serviceVersions.setEach('isDisplayed', false);
+    serviceVersions.findProperty('appliedTime', Math.max.apply(this, serviceVersions.mapProperty('appliedTime'))).set('isCurrent', true);
+    serviceVersions.findProperty('isCurrent').set('isDisplayed', true);
 
-    if (serviceVersions.length > numberOfDisplayed) {
-      startIndex = serviceVersions.length - numberOfDisplayed;
+    if (serviceVersions.length > 0) {
+      if (serviceVersions.length > this.VERSIONS_IN_FLOW) {
+        startIndex = serviceVersions.length - this.VERSIONS_IN_FLOW;
+      }
       this.set('startIndex', startIndex);
       this.adjustFlowView();
     }
@@ -111,6 +116,10 @@ App.ConfigHistoryFlowView = Em.View.extend({
       var infoBar = $('#config_history_flow>.version-info-bar');
       var scrollTop = $(window).scrollTop();
 
+      if (infoBar.length === 0) {
+        $(window).unbind('scroll');
+        return;
+      }
       //290 - default "top" property in px
       defaultTop = defaultTop || (infoBar.get(0).getBoundingClientRect() && infoBar.get(0).getBoundingClientRect().top) || 290;
 
@@ -134,7 +143,7 @@ App.ConfigHistoryFlowView = Em.View.extend({
       serviceVersion.set('first', (index === startIndex));
     });
     this.set('showLeftArrow', (startIndex !== 0));
-    this.set('showRightArrow', ((startIndex + 5) !== this.get('serviceVersions.length')));
+    this.set('showRightArrow', (this.get('serviceVersions.length') > this.VERSIONS_IN_FLOW) && ((startIndex + this.VERSIONS_IN_FLOW) !== this.get('serviceVersions.length')));
   },
 
   /**
@@ -162,17 +171,12 @@ App.ConfigHistoryFlowView = Em.View.extend({
     //TODO implement put configs of chosen version to server
   },
 
-  /**
-   * cancel configuration saving
-   */
-  cancel: function () {
-
-  },
   /**
    * save configuration
    * @return {object}
    */
   save: function () {
+    var self = this;
     return App.ModalPopup.show({
       header: Em.I18n.t('dashboard.configHistory.info-bar.save.popup.title'),
       bodyClass: Em.View.extend({
@@ -188,6 +192,7 @@ App.ConfigHistoryFlowView = Em.View.extend({
       primary: Em.I18n.t('common.save'),
       secondary: Em.I18n.t('common.cancel'),
       onSave: function () {
+        self.get('controller').restartServicePopup();
         this.hide();
       },
       onDiscard: function () {
@@ -198,88 +203,9 @@ App.ConfigHistoryFlowView = Em.View.extend({
       }
     });
   },
-  serviceVersions: [
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '1',
-      modifiedDate: 'Apr 4, 2014',
-      author: 'admin',
-      notes: 'notes',
-      appliedTime: 1
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '2',
-      modifiedDate: 'Apr 4, 2014',
-      author: 'admin',
-      notes: 'notes',
-      appliedTime: 2
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '3',
-      modifiedDate: 'Apr 4, 2014',
-      author: 'user',
-      notes: 'notes',
-      appliedTime: 3
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '4',
-      modifiedDate: 'Apr 4, 2014',
-      author: 'user',
-      notes: 'notes',
-      appliedTime: 4
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '5',
-      modifiedDate: 'Apr 4, 2014',
-      author: 'admin',
-      notes: 'notes',
-      appliedTime: 5
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '22',
-      modifiedDate: 'Apr 9, 2014',
-      author: 'admin',
-      notes: 'notes',
-      appliedTime: 6
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '33',
-      modifiedDate: 'Apr 9, 2014',
-      author: 'admin',
-      notes: 'notes',
-      appliedTime: 7
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '44',
-      modifiedDate: 'Apr 9, 2014',
-      author: 'admin',
-      notes: 'notes',
-      appliedTime: 8
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '55',
-      modifiedDate: 'Apr 9, 2014',
-      author: 'admin',
-      notes: 'notes',
-      appliedTime: 9
-    }),
-    Em.Object.create({
-      serviceName: 'HDFS',
-      version: '666',
-      modifiedDate: 'Apr 9, 2014',
-      author: 'admin',
-      notes: 'notes',
-      appliedTime: 10
-    })
-  ],
+  serviceVersions: function () {
+    return App.ServiceConfigVersion.find().filterProperty('serviceName', this.get('serviceName'));
+  }.property('serviceName'),
   /**
    * move back to the previous service version
    */

+ 1 - 0
ambari-web/app/views/main/dashboard/config_history_view.js

@@ -177,6 +177,7 @@ App.MainConfigHistoryView = App.TableView.extend({
     this.get('controller').loadHistoryToModel().done(function(){
       self.set('filteringComplete', true);
       self.propertyDidChange('pageContent');
+      self.set('controller.resetStartIndex', false);
     });
   },
 

+ 2 - 2
ambari-web/app/views/main/jobs/hive_job_details_view.js

@@ -250,8 +250,8 @@ App.MainHiveJobDetailsView = Em.View.extend({
         read : v.get('recordReadCount') == null ? null : Em.I18n.t('jobs.hive.tez.records.count').format(v.get('recordReadCount')),
         write : v.get('recordWriteCount') == null ? null : Em.I18n.t('jobs.hive.tez.records.count').format(v.get('recordWriteCount'))
       },
-      started: v.get('startTime') ? dateUtils.dateFormat(v.get('startTime'), true, true) : '',
-      ended: v.get('endTime') ? dateUtils.dateFormat(v.get('endTime'), true, true) : '',
+      started: v.get('startTime') ? dateUtils.dateFormat(v.get('startTime'), 'ddd, MMM DD, YYYY HH:mm:ss:SSS') : '',
+      ended: v.get('endTime') ? dateUtils.dateFormat(v.get('endTime'), 'ddd, MMM DD, YYYY HH:mm:ss:SSS') : '',
       status: status
     };
   }.property('selectedVertex.fileReadOps', 'selectedVertex.fileWriteOps', 'selectedVertex.hdfsReadOps', 'selectedVertex.hdfdWriteOps',

+ 1 - 3
ambari-web/test/utils/date_test.js

@@ -27,9 +27,7 @@ describe('date', function () {
   var correct_tests = Em.A([
     {t: 1349752195000, e: 'Tue, Oct 09, 2012 03:09', e2: 'Tue Oct 09 2012'},
     {t: 1367752195000, e: 'Sun, May 05, 2013 11:09', e2: 'Sun May 05 2013'},
-    {t: 1369952195000, e: 'Thu, May 30, 2013 22:16', e2: 'Thu May 30 2013'},
-    {t: 1369952195000, e: 'Thu, May 30, 2013 22:16:35', e2: 'Thu May 30 2013', showSeconds: true },
-    {t: 1369952195000, e: 'Thu, May 30, 2013 22:16:35:000', e2: 'Thu May 30 2013', showSeconds: true, showMilliseconds: true }
+    {t: 1369952195000, e: 'Thu, May 30, 2013 22:16', e2: 'Thu May 30 2013'}
   ]);
 
   var incorrect_tests = Em.A([