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 2012/12/09 13:43:34 UTC

svn commit: r1418917 [4/4] - in /incubator/ambari/branches/AMBARI-666: ./ ambari-web/app/ ambari-web/app/assets/data/wizard/stack/ ambari-web/app/assets/data/wizard/stack/hdp/ ambari-web/app/assets/data/wizard/stack/hdp/version01/ ambari-web/app/contro...

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js?rev=1418917&r1=1418916&r2=1418917&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/router.js Sun Dec  9 12:43:31 2012
@@ -33,6 +33,7 @@ App.Router = Em.Router.extend({
     this.set('isFwdNavigation', newStep >= previousStep);
   },
 
+
   clearAllSteps: function() {
     this.set('installerController.content', []);
     this.set('installerController.currentStep', 0);
@@ -43,6 +44,7 @@ App.Router = Em.Router.extend({
    * Temporary fix for getting cluster name
    * @return {*}
    */
+
   getClusterName: function(){
     return App.router.get('clusterController').get('clusterName');
   },
@@ -110,7 +112,7 @@ App.Router = Em.Router.extend({
   },
 
   resetAuth: function (authenticated) {
-    if (!authenticated){
+    if (!authenticated) {
       App.db.cleanUp();
       this.set('loggedIn', false);
       this.set('loginController.loginName', '');
@@ -130,17 +132,17 @@ App.Router = Em.Router.extend({
       url : '/api/users/' + loginName,
       dataType : 'text',
       type: 'GET',
-      beforeSend: function(xhr) {
+      beforeSend: function (xhr) {
         xhr.setRequestHeader("Authorization", "Basic " + hash);
       },
       statusCode: {
-        200: function() {
+        200: function () {
           console.log('Authorization status: 200');
         },
-        401: function() {
+        401: function () {
           console.log('Authorization status: 401');
         },
-        403: function(){
+        403: function () {
           console.log('Authorization status: 403');
         }
       },
@@ -165,6 +167,42 @@ App.Router = Em.Router.extend({
     });
   },
 
+  setAmbariStacks: function () {
+    var self = this;
+    var method = 'GET';
+    var url = (App.testMode) ? '/data/wizard/stack/stacks.json' : '/api/stacks';
+    $.ajax({
+      type: method,
+      url: url,
+      async: false,
+      dataType: 'text',
+      timeout: 5000,
+      success: function (data) {
+        var jsonData = jQuery.parseJSON(data);
+        console.log("TRACE: In success function for the setAmbariStacks call");
+        console.log("TRACE: value of the url is: " + url);
+        var stacks = [];
+        jsonData.forEach(function (_stack) {
+         stacks.pushObject({
+           name:_stack.name,
+           version: _stack.version
+         });
+        }, this);
+        App.db.setAmbariStacks(stacks);
+        console.log('TRACEIINNGG: ambaristacks: ' + JSON.stringify(App.db.getAmbariStacks()));
+      },
+
+      error: function (request, ajaxOptions, error) {
+        console.log("TRACE: In error function for the setAmbariStacks call");
+        console.log("TRACE: value of the url is: " + url);
+        console.log("TRACE: error code status is: " + request.status);
+        console.log('Error message is: ' + request.responseText);
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
+
   mockLogin: function (postLogin) {
     var controller = this.get('loginController');
     var loginName = controller.get('loginName');
@@ -174,6 +212,7 @@ App.Router = Em.Router.extend({
       this.setAuthenticated(true);
       this.setLoginName(loginName);
       this.setUser(App.store.createRecord(App.User, { userName: loginName, admin: loginName === 'admin' }));
+      this.setAmbariStacks();
       this.transitionTo(this.getSection());
       postLogin(true);
     } else {

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js?rev=1418917&r1=1418916&r2=1418917&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/routes/installer.js Sun Dec  9 12:43:31 2012
@@ -178,6 +178,7 @@ module.exports = Em.Route.extend({
       router.setNavigationFlow('step5');
 
       var controller = router.get('installerController');
+      var wizardStep5Controller = router.get('wizardStep5Controller');
       controller.setCurrentStep('5', false);
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep5', controller.get('content'));
@@ -213,6 +214,7 @@ module.exports = Em.Route.extend({
         controller.saveSlaveComponentHosts(wizardStep6Controller);
         controller.get('content').set('serviceConfigProperties', null);
         App.db.setServiceConfigProperties(null);
+        controller.loadAdvancedConfigs();
         router.transitionTo('step7');
       }
     }

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js?rev=1418917&r1=1418916&r2=1418917&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/db.js Sun Dec  9 12:43:31 2012
@@ -54,7 +54,7 @@ App.db.cleanUp = function () {
   };
   console.log("In cleanup./..");
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 // called whenever user logs in
 if (localStorage.getObject('ambari') == null) {
@@ -71,7 +71,14 @@ App.db.setLoginName = function (name) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data.app.loginName = name;
   localStorage.setObject('ambari', App.db.data);
-}
+};
+
+App.db.setAmbariStacks = function (stacks) {
+  console.log('TRACE: Entering db:setAmbariStacks function');
+  App.db.data = localStorage.getObject('ambari');
+  App.db.data.app.stacks = stacks;
+  localStorage.setObject('ambari', App.db.data);
+};
 
 // that works incorrectly
 App.db.setUser = function (user) {
@@ -79,7 +86,7 @@ App.db.setUser = function (user) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data.app.user = user;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setAuthenticated = function (authenticated) {
   console.log('TRACE: Entering db:setAuthenticated function');
@@ -91,7 +98,7 @@ App.db.setAuthenticated = function (auth
   localStorage.setObject('ambari', App.db.data);
   App.db.data = localStorage.getObject('ambari');
   console.log('Now present value of authentication is: ' + App.db.data.app.authenticated);
-}
+};
 
 App.db.setSection = function (section) {
   console.log('TRACE: Entering db:setSection function');
@@ -105,7 +112,7 @@ App.db.setSection = function (section) {
   }
   App.db.data[user].section = section;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setInstallerCurrentStep = function (currentStep, completed) {
   console.log('TRACE: Entering db:setInstallerCurrentStep function');
@@ -123,7 +130,7 @@ App.db.setInstallerCurrentStep = functio
   App.db.data[user].Installer.currentStep = currentStep;
   App.db.data[user].Installer.completed = completed;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setClusterName = function (name) {
   console.log('TRACE: Entering db:setClusterName function');
@@ -142,7 +149,7 @@ App.db.setClusterName = function (name) 
   }
   App.db.data[user].Installer.ClusterName = name;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setAllHostNames = function (hostNames) {
   console.log('TRACE: Entering db:setAllHostNames function');
@@ -153,7 +160,7 @@ App.db.setAllHostNames = function (hostN
   }
   App.db.data[user].Installer.hostNames = hostNames;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setHosts = function (hostInfo) {
   console.log('TRACE: Entering db:setHosts function');
@@ -164,7 +171,7 @@ App.db.setHosts = function (hostInfo) {
   }
   App.db.data[user].Installer.hostInfo = hostInfo;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setInstallType = function (installType) {
   console.log('TRACE: Entering db:setInstallType function');
@@ -175,7 +182,7 @@ App.db.setInstallType = function (instal
   }
   App.db.data[user].Installer.installType = installType;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setSoftRepo = function (softRepo) {
   console.log('TRACE: Entering db:setSoftRepo function');
@@ -186,7 +193,7 @@ App.db.setSoftRepo = function (softRepo)
   }
   App.db.data[user].Installer.softRepo = softRepo;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setBootStatus = function (status) {
   console.log('TRACE: Entering db:setBootStatus function');
@@ -194,7 +201,7 @@ App.db.setBootStatus = function (status)
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.bootStatus = status;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.removeHosts = function (hostInfo) {
   console.log('TRACE: Entering db:setSoftRepo function');
@@ -204,7 +211,7 @@ App.db.removeHosts = function (hostInfo)
     delete hostList[host];
   });
   App.db.setHosts(hostList);
-}
+};
 
 App.db.setService = function (serviceInfo) {
   console.log('TRACE: Entering db:setService function');
@@ -212,63 +219,70 @@ App.db.setService = function (serviceInf
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.serviceInfo = serviceInfo;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setSelectedServiceNames = function (serviceNames) {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.selectedServiceNames = serviceNames;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
-App.db.setClientsForSelectedServices = function(clientInfo) {
+App.db.setClientsForSelectedServices = function (clientInfo) {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.clientInfo = clientInfo;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setMasterComponentHosts = function (masterComponentHosts) {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.masterComponentHosts = masterComponentHosts;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setHostToMasterComponent = function (hostToMasterComponent) {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.hostToMasterComponent = hostToMasterComponent;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setHostSlaveComponents = function (hostSlaveComponents) {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.hostSlaveComponents = hostSlaveComponents;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setSlaveComponentHosts = function (slaveComponentHosts) {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.slaveComponentHosts = slaveComponentHosts;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setServiceConfigs = function (serviceConfigs) {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.serviceConfigs = serviceConfigs;
   localStorage.setObject('ambari', App.db.data);
-}
+};
+
+App.db.setAdvancedServiceConfig = function(serviceConfigs) {
+  App.db.data = localStorage.getObject('ambari');
+  var user = App.db.data.app.loginName;
+  App.db.data[user].Installer.advanceServiceConfigs = serviceConfigs;
+  localStorage.setObject('ambari', App.db.data);
+};
 
 App.db.setServiceConfigProperties = function (configProperties) {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   App.db.data[user].Installer.configProperties = configProperties;
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 App.db.setClusterStatus = function (status) {
   App.db.data = localStorage.getObject('ambari');
@@ -276,7 +290,7 @@ App.db.setClusterStatus = function (stat
   App.db.data[user].clusterStatus = status;
   console.log('db.setClusterStatus called: ' + JSON.stringify(status));
   localStorage.setObject('ambari', App.db.data);
-}
+};
 
 /*
  *  getter methods
@@ -287,19 +301,19 @@ App.db.getUser = function () {
   console.log('TRACE: Entering db:getUser function');
   App.db.data = localStorage.getObject('ambari');
   return App.db.data.app.user;
-}
+};
 
 App.db.getLoginName = function () {
   console.log('Trace: Entering db:getLoginName function');
   App.db.data = localStorage.getObject('ambari');
   return App.db.data.app.loginName;
-}
+};
 
 App.db.getAuthenticated = function () {
   console.log('Trace: Entering db:getAuthenticated function');
   App.db.data = localStorage.getObject('ambari');
   return App.db.data.app.authenticated;
-}
+};
 
 App.db.getSection = function () {
   console.log('Trace: Entering db:getSection function');
@@ -317,9 +331,17 @@ App.db.getClusterName = function () {
   var user = App.db.data.app.loginName;
   if (user && App.db.data[user] && App.db.data[user].Installer) {
     return App.db.data[user].Installer.ClusterName;
+  } else {
+    return null;
   }
 };
 
+App.db.getAmbariStacks = function () {
+  console.log('TRACE: Entering db:setAmbariStacks function');
+  App.db.data = localStorage.getObject('ambari');
+  return App.db.data.app.stacks;
+};
+
 /**
  * Return current step for specified Wizard Type
  * @param wizardType
@@ -363,34 +385,34 @@ App.db.getInstallerCurrentStep = functio
     return 0;
   }
   return App.db.data[user].Installer.currentStep;
-},
+};
 
-  App.db.getAllHostNames = function () {
-    console.log('TRACE: Entering db:getHostNames function');
-    App.db.data = localStorage.getObject('ambari');
-    var user = App.db.data.app.loginName;
-    return App.db.data[user].Installer.hostNames;
-  },
-
-  App.db.getInstallType = function () {
-    console.log('TRACE: Entering db:getHostNames function');
-    App.db.data = localStorage.getObject('ambari');
-    var user = App.db.data.app.loginName;
-    return App.db.data[user].Installer.installType;
-  },
-
-  App.db.getSoftRepo = function () {
-    console.log('TRACE: Entering db:getSoftRepo function');
-    App.db.data = localStorage.getObject('ambari');
-    var user = App.db.data.app.loginName;
-    return App.db.data[user].Installer.softRepo;
-  }
+App.db.getAllHostNames = function () {
+  console.log('TRACE: Entering db:getHostNames function');
+  App.db.data = localStorage.getObject('ambari');
+  var user = App.db.data.app.loginName;
+  return App.db.data[user].Installer.hostNames;
+};
+
+App.db.getInstallType = function () {
+  console.log('TRACE: Entering db:getHostNames function');
+  App.db.data = localStorage.getObject('ambari');
+  var user = App.db.data.app.loginName;
+  return App.db.data[user].Installer.installType;
+};
+
+App.db.getSoftRepo = function () {
+  console.log('TRACE: Entering db:getSoftRepo function');
+  App.db.data = localStorage.getObject('ambari');
+  var user = App.db.data.app.loginName;
+  return App.db.data[user].Installer.softRepo;
+};
 
 App.db.isCompleted = function () {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.completed;
-}
+};
 
 App.db.getHosts = function () {
   console.log('TRACE: Entering db:getHosts function');
@@ -401,39 +423,39 @@ App.db.getHosts = function () {
     return 0;
   }
   return App.db.data[user].Installer.hostInfo;
-}
+};
 
 App.db.getBootStatus = function () {
   console.log('TRACE: Entering db:getBootStatus function');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.bootStatus;
-}
+};
 
 App.db.getService = function () {
   console.log('TRACE: Entering db:getService function');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.serviceInfo;
-}
+};
 
 App.db.getSelectedServiceNames = function () {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.selectedServiceNames;
-}
+};
 
-App.db.getClientsForSelectedServices = function() {
+App.db.getClientsForSelectedServices = function () {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.clientInfo;
-}
+};
 
 App.db.getMasterComponentHosts = function () {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.masterComponentHosts;
-}
+};
 
 App.db.getHostToMasterComponent = function () {
   App.db.data = localStorage.getObject('ambari');
@@ -445,38 +467,44 @@ App.db.getHostSlaveComponents = function
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.hostSlaveComponents;
-}
+};
 
 App.db.getSlaveComponentHosts = function () {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
-  if(App.db.data[user]&&App.db.data[user].Installer){
+  if (App.db.data[user] && App.db.data[user].Installer) {
     return App.db.data[user].Installer.slaveComponentHosts;
   }
   return null;
-}
+};
 
 App.db.getServiceConfigs = function () {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.serviceConfigs;
-}
+};
+
+App.db.getAdvancedServiceConfig = function() {
+  App.db.data = localStorage.getObject('ambari');
+  var user = App.db.data.app.loginName;
+  return App.db.data[user].Installer.advanceServiceConfigs;
+};
 
 App.db.getServiceConfigProperties = function () {
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   return App.db.data[user].Installer.configProperties;
-}
+};
 
 App.db.getClusterStatus = function () {
   console.log('TRACE: Entering db:getClusterStatus function');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
-  if(App.db.data[user] && App.db.data[user].clusterStatus){
+  if (App.db.data[user] && App.db.data[user].clusterStatus) {
     return App.db.data[user].clusterStatus;
   } else {
     return null;
   }
-}
+};
 
 module.exports = App.db;

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/helper.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/helper.js?rev=1418917&r1=1418916&r2=1418917&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/helper.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/utils/helper.js Sun Dec  9 12:43:31 2012
@@ -15,12 +15,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+String.prototype.trim = function () {
+  return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+};
+
 String.prototype.capitalize = function () {
   return this.charAt(0).toUpperCase() + this.slice(1);
 }
 
 Em.CoreObject.reopen({
-  t:function (key, attrs) {
+  t: function (key, attrs) {
     return Em.I18n.t(key, attrs)
   }
 });
@@ -89,13 +94,13 @@ Number.prototype.countPercentageRatio = 
 }
 
 /**
- * Formats the given URL template by replacing keys in 'substitutes' 
+ * Formats the given URL template by replacing keys in 'substitutes'
  * with their values. If not in App.testMode, the testUrl is used.
- * 
+ *
  * The substitution points in urlTemplate should be of format "...{key}..."
- * For example "http://apache.org/{projectName}". 
- * The substitutes can then be{projectName: "Ambari"}. 
- * 
+ * For example "http://apache.org/{projectName}".
+ * The substitutes can then be{projectName: "Ambari"}.
+ *
  * Keys which will be automatically taken care of are:
  * {
  *  hostName: App.test_hostname,
@@ -103,7 +108,7 @@ Number.prototype.countPercentageRatio = 
  *  toSeconds: ..., // now
  *  stepSeconds: ..., // 15 seconds by default
  * }
- * 
+ *
  * @param {String} urlTemplate  URL template on which substitutions are to be made
  * @param substitutes Object containing keys to be replaced with respective values
  * @param {String} testUrl  URL to be used if app is not in test mode (!App.testMode)
@@ -133,7 +138,7 @@ App.formatUrl = function (urlTemplate, s
 }
 
 App.format = {
-  role: function(role) {
+  role: function (role) {
     switch (role) {
       case 'ZOOKEEPER_SERVER':
         return 'ZooKeeper Server';
@@ -245,7 +250,7 @@ App.format = {
    * TIMEDOUT - Host did not respond in time
    * ABORTED - Operation was abandoned
    */
-  taskStatus: function(_taskStatus) {
+  taskStatus: function (_taskStatus) {
     return _taskStatus.replace('_', ' ').toLowerCase();
   }
 };
\ No newline at end of file

Modified: incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js?rev=1418917&r1=1418916&r2=1418917&view=diff
==============================================================================
--- incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js (original)
+++ incubator/ambari/branches/AMBARI-666/ambari-web/app/views/wizard/controls_view.js Sun Dec  9 12:43:31 2012
@@ -51,12 +51,15 @@ App.ServiceConfigTextField = Ember.TextF
 
   valueBinding: 'serviceConfig.value',
   classNameBindings: 'textFieldClassName',
+  placeholderBinding: 'serviceConfig.defaultValue',
 
   textFieldClassName: function () {
     // sets the width of the field depending on display type
     if (['directory', 'url', 'email', 'user', 'host'].contains(this.get('serviceConfig.displayType'))) {
       return ['span6'];
-    } else {
+    } else if(this.get('serviceConfig.displayType') === 'advanced'){
+      return ['span6'];
+    } else{
       return ['input-small'];
     }
   }.property('serviceConfig.displayType'),
@@ -74,6 +77,7 @@ App.ServiceConfigTextField = Ember.TextF
 App.ServiceConfigTextFieldWithUnit = Ember.View.extend(App.ServiceConfigPopoverSupport, {
   valueBinding: 'serviceConfig.value',
   classNames: [ 'input-append' ],
+  placeholderBinding: 'serviceConfig.defaultValue',
 
   template: Ember.Handlebars.compile('{{view App.ServiceConfigTextField serviceConfigBinding="view.serviceConfig" isPopoverEnabled="false"}}<span class="add-on">{{view.serviceConfig.unit}}</span>'),
 
@@ -114,6 +118,7 @@ App.ServiceConfigTextArea = Ember.TextAr
   valueBinding: 'serviceConfig.value',
   rows: 4,
   classNames: ['span6'],
+  placeholderBinding: 'serviceConfig.defaultValue',
 
   disabled: function () {
     return !this.get('serviceConfig.isEditable');