You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2014/07/28 13:59:18 UTC

git commit: AMBARI-6633 Config History: Implement Compare View (with mock data). (atkach)

Repository: ambari
Updated Branches:
  refs/heads/trunk 46fb9d7eb -> 0ab80fdeb


AMBARI-6633 Config History: Implement Compare View (with mock data). (atkach)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0ab80fde
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0ab80fde
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0ab80fde

Branch: refs/heads/trunk
Commit: 0ab80fdeb4a9d2b193f2babb8e2c43e4a6ad0252
Parents: 46fb9d7
Author: atkach <at...@hortonworks.com>
Authored: Mon Jul 28 14:56:58 2014 +0300
Committer: atkach <at...@hortonworks.com>
Committed: Mon Jul 28 14:56:58 2014 +0300

----------------------------------------------------------------------
 .../data/configurations/service_version.json    |  28 +++++
 ambari-web/app/config.js                        |   2 +-
 .../controllers/main/service/info/configs.js    |  73 ++++++++++++-
 ambari-web/app/messages.js                      |   1 +
 ambari-web/app/styles/application.less          |   5 +-
 .../common/configs/compare_property.hbs         |  26 +++++
 .../common/configs/config_history_flow.hbs      |  24 ++--
 .../templates/common/configs/service_config.hbs |   5 +-
 ambari-web/app/utils/ajax/ajax.js               |  10 ++
 ambari-web/app/utils/config.js                  |  38 ++++---
 ambari-web/app/views.js                         |   1 +
 .../common/configs/compare_property_view.js     |  24 ++++
 .../views/common/configs/config_history_flow.js | 109 ++++++++++++++-----
 13 files changed, 285 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/assets/data/configurations/service_version.json
----------------------------------------------------------------------
diff --git a/ambari-web/app/assets/data/configurations/service_version.json b/ambari-web/app/assets/data/configurations/service_version.json
new file mode 100644
index 0000000..dc02514
--- /dev/null
+++ b/ambari-web/app/assets/data/configurations/service_version.json
@@ -0,0 +1,28 @@
+{
+  "items": [
+    {
+      "serviceconfigversion": "1",
+      "servicename": "HDFS",
+      "createtime": "43800000000",
+      "appliedtime": "58600000000",
+      "author": "admin",
+      "notes": "Notes should be here",
+      "configurations": [
+        {
+          "type": "hdfs-site",
+          "tag": "1",
+          "version": "1",
+          "Config": {
+            "cluster_name": "c1"
+          },
+          "properties": {
+            "dfs.namenode.checkpoint.dir" : "/hadoop/hdfs/namesecondary",
+            "dfs.namenode.name.dir" : "/hadoop/hdfs/namenode",
+            "dfs.replication" : "3",
+            "dfs.permissions.enabled" : "true"
+          }
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/config.js b/ambari-web/app/config.js
index ebd9372..31d085d 100644
--- a/ambari-web/app/config.js
+++ b/ambari-web/app/config.js
@@ -80,7 +80,7 @@ App.supports = {
   views: false,
   flume: true,
   databaseConnection: true,
-  configHistory: true
+  configHistory: false
 };
 
 if (App.enableExperimental) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/controllers/main/service/info/configs.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js
index b67de60..5a6b46f 100644
--- a/ambari-web/app/controllers/main/service/info/configs.js
+++ b/ambari-web/app/controllers/main/service/info/configs.js
@@ -43,6 +43,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   isApplyingChanges: false,
   saveConfigsFlag: true,
   putClusterConfigsCallsNumber: null,
+  compareServiceVersion: null,
   // contain Service Config Property, when user proceed from Select Config Group dialog
   overrideToAdd: null,
   serviceConfigs: function () {
@@ -357,11 +358,77 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
       self.set('allConfigs', configs);
       //STEP 8: add configs as names of host components
       self.addHostNamesToConfig();
-      //STEP 9: Load and add overriden configs of group
-      App.config.loadServiceConfigGroupOverrides(self.get('allConfigs'), self.get('loadedGroupToOverrideSiteToTagMap'), self.get('configGroups'), self.onLoadOverrides, self);
+      //STEP load configs of version being compared against
+      self.loadCompareVersionConfigs(self.get('allConfigs')).done(function () {
+        //STEP 9: Load and add overriden configs of group
+        App.config.loadServiceConfigGroupOverrides(self.get('allConfigs'), self.get('loadedGroupToOverrideSiteToTagMap'), self.get('configGroups'), self.onLoadOverrides, self);
+      });
     });
   }.observes('selectedConfigGroup'),
 
+  /**
+   * load version configs for comparison
+   * @param allConfigs
+   * @return {object}
+   */
+  loadCompareVersionConfigs: function (allConfigs) {
+    var dfd = $.Deferred();
+    var self = this;
+    var compareServiceVersion = this.get('compareServiceVersion');
+
+    if (compareServiceVersion) {
+      this.getCompareVersionConfigs(compareServiceVersion).done(function (json) {
+        var serviceVersionMap = {};
+
+        json.items[0].configurations.forEach(function (configuration) {
+          for (var prop in configuration.properties) {
+            serviceVersionMap[prop] = {
+              name: prop,
+              value: configuration.properties[prop],
+              type: configuration.type,
+              tag: configuration.tag,
+              version: configuration.version
+            }
+          }
+        });
+        allConfigs.forEach(function (serviceConfig) {
+          var compareConfig = serviceVersionMap[serviceConfig.name];
+
+          if (compareConfig) {
+            serviceConfig.compareConfig = App.ServiceConfigProperty.create(serviceConfig);
+            serviceConfig.compareConfig.set('value', compareConfig.value);
+            serviceConfig.compareConfig.set('serviceVersion', compareServiceVersion);
+            serviceConfig.isComparison = true;
+          }
+        });
+        self.set('compareServiceVersion', null)
+        dfd.resolve();
+      }).fail(function () {
+          dfd.resolve();
+        });
+    } else {
+      allConfigs.setEach('isComparison', false);
+      dfd.resolve();
+    }
+    return dfd.promise();
+  },
+
+  /**
+   * get configs of chosen version from server to compare
+   * @param compareServiceVersion
+   * @return {$.ajax}
+   */
+  getCompareVersionConfigs: function (compareServiceVersion) {
+    return App.ajax.send({
+      name: 'service.config.version.get',
+      sender: this,
+      data: {
+        serviceVersion: compareServiceVersion,
+        url: '/data/configurations/service_version.json'
+      }
+    })
+  },
+
   checkDatabaseProperties: function (serviceConfig) {
     if (!['OOZIE', 'HIVE'].contains(this.get('content.serviceName'))) return;
     var configsToHide = ['oozie_hostname', 'hive_hostname'];
@@ -669,7 +736,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend({
   setEditability: function (serviceConfigProperty, defaultGroupSelected) {
     serviceConfigProperty.set('isEditable', false);
     if (App.get('isAdmin') && defaultGroupSelected && !this.get('isHostsConfigsPage')) {
-      serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
+      serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable') && !serviceConfigProperty.get('isComparison'));
     }
   },
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 48519ee..95333fb 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1951,6 +1951,7 @@ Em.I18n.translations = {
   'dashboard.configHistory.info-bar.showMore': 'Show more',
   'dashboard.configHistory.info-bar.save.popup.title': 'Save Configuration',
   'dashboard.configHistory.info-bar.save.popup.placeholder': 'What did you change?',
+  'dashboard.configHistory.info-bar.revert.button': 'Revert to this version',
 
   'timeRange.presets.1hour':'1h',
   'timeRange.presets.12hour':'12h',

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 4ccd178..499ace7 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -4860,7 +4860,7 @@ ul.inline li {
         position: relative;
         width: 73%;
         height: 100%;
-        background-color: #dcdcdc;
+        background-color: #f1f1f1;
         border: 1px solid #000000;
         font-size: 0.9em;
         .top-right-label {
@@ -4898,6 +4898,9 @@ ul.inline li {
           line-height: 20px;
         }
       }
+      .displayed {
+        background-color: #dcdcdc;
+      }
       .arrow-box {
         width: 25%;
         height: 100%;

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/templates/common/configs/compare_property.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/compare_property.hbs b/ambari-web/app/templates/common/configs/compare_property.hbs
new file mode 100644
index 0000000..ff1ceb8
--- /dev/null
+++ b/ambari-web/app/templates/common/configs/compare_property.hbs
@@ -0,0 +1,26 @@
+{{!
+* 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.
+}}
+
+<div {{bindAttr class=":control-group :overrideField"}}>
+  {{view view.serviceConfigProperty.viewClass serviceConfigBinding="view.serviceConfigProperty.compareConfig"}}
+    <span>
+      <strong><i class="icon-asterisks">&#10037;</i>{{view.serviceConfigProperty.compareConfig.serviceVersion.author}}</strong>&nbsp;
+      {{t dashboard.configHistory.info-bar.authoredOn}}&nbsp;
+      <strong>{{view.serviceConfigProperty.compareConfig.serviceVersion.modifiedDate}}</strong>
+  </span>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/templates/common/configs/config_history_flow.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/config_history_flow.hbs b/ambari-web/app/templates/common/configs/config_history_flow.hbs
index b94cabb..7bf7b87 100644
--- a/ambari-web/app/templates/common/configs/config_history_flow.hbs
+++ b/ambari-web/app/templates/common/configs/config_history_flow.hbs
@@ -23,11 +23,11 @@
       {{#each serviceVersion in view.visibleServiceVersion}}
           <div {{bindAttr class=":flow-element :pull-left serviceVersion.first:first"}}>
               <div class="arrow-box pull-left"><div class="big-arrow-right"></div></div>
-              <div class="box pull-right">
+              <div {{bindAttr class=":box :pull-right serviceVersion.isDisplayed:displayed"}}>
                   <div class="top-right-label">{{serviceVersion.version}}</div>
-                  <p class="date">{{serviceVersion.date}}</p>
+                  <p class="date">{{serviceVersion.modifiedDate}}</p>
                   <p class="content">{{serviceVersion.author}}:&nbsp;{{serviceVersion.notes}}</p>
-                  {{#if serviceVersion.current}}
+                  {{#if serviceVersion.isCurrent}}
                     <div class="current-label label label-success">{{t common.current}}</div>
                   {{/if}}
               </div>
@@ -47,13 +47,13 @@
                   <li class="pointer dropdown-submenu">
                       <div class="row-fluid">
                           <div class="span2">{{t common.version}}:&nbsp;{{serviceVersion.version}}</div>
-                          <div class="span3">{{serviceVersion.date}}</div>
+                          <div class="span3">{{serviceVersion.modifiedDate}}</div>
                           <div class="span2">{{serviceVersion.author}}</div>
                           <div class="span4"><span class="ellipsis">{{t dashboard.configHistory.info-bar.changesToHandle}}</span></div>
                           <div class="pull-right"><i class="icon-caret-right"></i></div>
                       </div>
                       <ul class="dropdown-menu">
-                          <li><a {{action "view" serviceVersion target="view"}}>{{t common.view}}</a></li>
+                          <li><a {{action switchVersion serviceVersion target="view"}}>{{t common.view}}</a></li>
                           <li><a {{action compare serviceVersion target="view"}}>{{t common.compare}}</a></li>
                           <li><a {{action revert serviceVersion target="view"}}>{{t common.revert}}</a></li>
                       </ul>
@@ -62,7 +62,7 @@
               {{#unless view.showFullList}}
                   <li class="align-center pointer" id="show_more">
                       <a {{action openFullList target="view"}}>
-                        {{t dashboard.configHistory.info-bar.showMore}}&nbsp;{{view.currentServiceVersion.serviceName}}
+                        {{t dashboard.configHistory.info-bar.showMore}}&nbsp;{{view.serviceName}}
                           &nbsp;<span class="lowercase ellipsis">{{t dashboard.configHistory.title}}</span>
                       </a>
                   </li>
@@ -70,12 +70,16 @@
             </ul>
         </div>
         <div class="label-wrapper span8">
-            <span class="label label-success">{{t common.current}}: {{view.currentServiceVersion.version}}</span>
-            <strong>{{view.currentServiceVersion.author}}</strong>&nbsp;{{t dashboard.configHistory.info-bar.authoredOn}}&nbsp;<strong>{{view.currentServiceVersion.date}}</strong>
+            <span {{bindAttr class=":label view.displayedServiceVersion.isCurrent:label-success"}}>{{t common.current}}: {{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">
-            <button class="btn" {{action cancel target="view"}}>{{t common.cancel}}</button>
-            <button class="btn btn-success" {{action save target="view"}}>{{t common.save}}</button>
+            {{#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>
+            {{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">

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/templates/common/configs/service_config.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/common/configs/service_config.hbs b/ambari-web/app/templates/common/configs/service_config.hbs
index f566ab4..66989a4 100644
--- a/ambari-web/app/templates/common/configs/service_config.hbs
+++ b/ambari-web/app/templates/common/configs/service_config.hbs
@@ -102,7 +102,7 @@
                 <form class="form-horizontal" autocomplete="off">
 
                   {{#each view.filteredCategoryConfigs}}
-                      <div {{bindAttr class=":entry-row isOverridden:overridden-property"}}>
+                      <div {{bindAttr class=":entry-row isOverridden:overridden-property isComparison:overridden-property"}}>
                           {{#if showLabel}}
                             <span {{bindAttr class="errorMessage:error: :control-group :control-label-span"}}>
                               <label class="control-label">
@@ -152,6 +152,9 @@
                             {{#if this.isOverridden}}
                               {{view App.ServiceConfigView.SCPOverriddenRowsView serviceConfigPropertyBinding="this" isDefaultGroupSelectedBinding="controller.selectedConfigGroup.isDefault"}}
                             {{/if}}
+                            {{#if this.isComparison}}
+                              {{view App.ServiceConfigView.SCPComparisonRowsView serviceConfigPropertyBinding="this"}}
+                            {{/if}}
                           </div>
                       </div>
                     {{#if this.additionalView}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 8f41153..fe1ebdd 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -1723,6 +1723,16 @@ var urls = {
         })
       }
     }
+  },
+  'service.config.version.get': {
+    //TODO set actual url when API is ready
+    'real': '',
+    'mock': '',
+    format: function(data) {
+      return {
+        url: data.url
+      }
+    }
   }
 };
 /**

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index 068acf7..f313784 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -912,20 +912,7 @@ App.config = Em.Object.create({
       for (var prop in properties) {
         var serviceConfig = params.configKeyToConfigMap[config.type + ".xml"][prop];
         var hostOverrideValue = properties[prop];
-        if (serviceConfig && serviceConfig.displayType === 'int') {
-          if (/\d+m$/.test(hostOverrideValue)) {
-            hostOverrideValue = hostOverrideValue.slice(0, hostOverrideValue.length - 1);
-          }
-        } else if (serviceConfig && serviceConfig.displayType === 'checkbox') {
-          switch (hostOverrideValue) {
-            case 'true':
-              hostOverrideValue = true;
-              break;
-            case 'false':
-              hostOverrideValue = false;
-              break;
-          }
-        }
+        this.formatOverrideValue(serviceConfig, hostOverrideValue);
         if (serviceConfig) {
           // Value of this property is different for this host.
           var overrides = 'overrides';
@@ -939,9 +926,30 @@ App.config = Em.Object.create({
           serviceConfig.overrides.push({value: hostOverrideValue, group: group});
         }
       }
-    });
+    }, this);
     params.callback.call(params.sender, params.serviceConfigs);
   },
+  /**
+   * format value of override of config
+   * @param serviceConfig
+   * @param hostOverrideValue
+   */
+  formatOverrideValue: function (serviceConfig, hostOverrideValue) {
+    if (serviceConfig && serviceConfig.displayType === 'int') {
+      if (/\d+m$/.test(hostOverrideValue)) {
+        hostOverrideValue = hostOverrideValue.slice(0, hostOverrideValue.length - 1);
+      }
+    } else if (serviceConfig && serviceConfig.displayType === 'checkbox') {
+      switch (hostOverrideValue) {
+        case 'true':
+          hostOverrideValue = true;
+          break;
+        case 'false':
+          hostOverrideValue = false;
+          break;
+      }
+    }
+  },
 
   /**
    * Set all site property that are derived from other site-properties

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/views.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views.js b/ambari-web/app/views.js
index ee37b48..1e6d266 100644
--- a/ambari-web/app/views.js
+++ b/ambari-web/app/views.js
@@ -32,6 +32,7 @@ require('views/common/form/field');
 require('views/common/quick_view_link_view');
 require('views/common/configs/services_config');
 require('views/common/configs/overriddenProperty_view');
+require('views/common/configs/compare_property_view');
 require('views/common/configs/config_history_flow');
 require('views/common/filter_combobox');
 require('views/common/filter_combo_cleanable');

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/views/common/configs/compare_property_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/compare_property_view.js b/ambari-web/app/views/common/configs/compare_property_view.js
new file mode 100644
index 0000000..900d374
--- /dev/null
+++ b/ambari-web/app/views/common/configs/compare_property_view.js
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ */
+// SCP means ServiceConfigProperty
+
+var App = require('app');
+
+App.ServiceConfigView.SCPComparisonRowsView = Ember.View.extend({
+  templateName: require('templates/common/configs/compare_property'),
+  serviceConfigProperty: null
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/0ab80fde/ambari-web/app/views/common/configs/config_history_flow.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/config_history_flow.js b/ambari-web/app/views/common/configs/config_history_flow.js
index 882403e..027d8a5 100644
--- a/ambari-web/app/views/common/configs/config_history_flow.js
+++ b/ambari-web/app/views/common/configs/config_history_flow.js
@@ -32,9 +32,13 @@ App.ConfigHistoryFlowView = Em.View.extend({
    */
   showFullList: false,
 
-  currentServiceVersion: function () {
-    return this.get('serviceVersions').findProperty('current');
-  }.property('serviceVersions.@each.current'),
+  serviceName: function () {
+    return this.get('controller.selectedService.serviceName');
+  }.property('controller.selectedService.serviceName'),
+
+  displayedServiceVersion: function () {
+    return this.get('serviceVersions').findProperty('isDisplayed');
+  }.property('serviceVersions.@each.isDisplayed'),
   /**
    * identify whether to show link that open whole content of notes
    */
@@ -64,7 +68,7 @@ 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')).reverse();
+    var serviceVersions = this.get('serviceVersions').without(this.get('currentServiceVersion')).slice(0).reverse();
     if (this.get('showFullList')) {
       return serviceVersions;
     }
@@ -84,11 +88,40 @@ App.ConfigHistoryFlowView = Em.View.extend({
     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);
+
     if (serviceVersions.length > numberOfDisplayed) {
       startIndex = serviceVersions.length - numberOfDisplayed;
       this.set('startIndex', startIndex);
       this.adjustFlowView();
     }
+    this.keepInfoBarAtTop()
+  },
+
+  /**
+   * initialize event to keep info bar position at the top of the page
+   */
+  keepInfoBarAtTop: function () {
+    var defaultTop;
+    //reset defaultTop value in closure
+    $(window).unbind('scroll');
+
+    $(window).on('scroll', function (event) {
+      var infoBar = $('#config_history_flow>.version-info-bar');
+      var scrollTop = $(window).scrollTop();
+
+      //290 - default "top" property in px
+      defaultTop = defaultTop || (infoBar.get(0).getBoundingClientRect() && infoBar.get(0).getBoundingClientRect().top) || 290;
+
+      if (scrollTop > defaultTop) {
+        infoBar.css('top', '10px');
+      } else if (scrollTop > 0) {
+        infoBar.css('top', (defaultTop - scrollTop) + 'px');
+      } else {
+        infoBar.css('top', 'auto');
+      }
+    })
   },
   /**
    *  define the first element in viewport
@@ -107,21 +140,28 @@ App.ConfigHistoryFlowView = Em.View.extend({
   /**
    * switch configs view version to chosen
    */
-  view: function () {
-
+  switchVersion: function (event) {
+    var version = event.context.get('version');
+    this.get('serviceVersions').forEach(function (serviceVersion) {
+      serviceVersion.set('isDisplayed', serviceVersion.get('version') === version);
+    });
+    //TODO implement load configs for chosen version
   },
+
   /**
    * add config values of chosen version to view for comparison
    */
-  compare: function () {
-
+  compare: function (event) {
+    this.set('controller.compareServiceVersion', event.context);
+    this.get('controller').onConfigGroupChange();
   },
   /**
-   * revert config values to chosen version
+   * revert config values to chosen version and apply reverted configs to server
    */
   revert: function () {
-
+    //TODO implement put configs of chosen version to server
   },
+
   /**
    * cancel configuration saving
    */
@@ -162,73 +202,82 @@ App.ConfigHistoryFlowView = Em.View.extend({
     Em.Object.create({
       serviceName: 'HDFS',
       version: '1',
-      date: 'Apr 4, 2014',
+      modifiedDate: 'Apr 4, 2014',
       author: 'admin',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 1
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '2',
-      date: 'Apr 4, 2014',
+      modifiedDate: 'Apr 4, 2014',
       author: 'admin',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 2
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '3',
-      date: 'Apr 4, 2014',
+      modifiedDate: 'Apr 4, 2014',
       author: 'user',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 3
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '4',
-      date: 'Apr 4, 2014',
+      modifiedDate: 'Apr 4, 2014',
       author: 'user',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 4
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '5',
-      date: 'Apr 4, 2014',
+      modifiedDate: 'Apr 4, 2014',
       author: 'admin',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 5
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '22',
-      date: 'Apr 9, 2014',
+      modifiedDate: 'Apr 9, 2014',
       author: 'admin',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 6
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '33',
-      date: 'Apr 9, 2014',
+      modifiedDate: 'Apr 9, 2014',
       author: 'admin',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 7
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '44',
-      date: 'Apr 9, 2014',
+      modifiedDate: 'Apr 9, 2014',
       author: 'admin',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 8
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '55',
-      date: 'Apr 9, 2014',
+      modifiedDate: 'Apr 9, 2014',
       author: 'admin',
-      notes: 'notes'
+      notes: 'notes',
+      appliedTime: 9
     }),
     Em.Object.create({
       serviceName: 'HDFS',
       version: '666',
-      date: 'Apr 9, 2014',
+      modifiedDate: 'Apr 9, 2014',
       author: 'admin',
       notes: 'notes',
-      current: true
+      appliedTime: 10
     })
   ],
   /**