Browse Source

AMBARI-7054. Slider View: Create app wizard should allow adding of custom-configs. (onechiporenko)

Oleg Nechiporenko 10 năm trước cách đây
mục cha
commit
0fb6e63557

+ 112 - 10
contrib/views/slider/src/main/resources/ui/app/components/configSection.js

@@ -17,32 +17,134 @@
  */
 
 App.ConfigSectionComponent = Em.Component.extend({
-  layoutName:'components/configSection',
-  config:null,
-  section:'',
+
+  layoutName: 'components/configSection',
+
+  config: null,
+
+  section: '',
 
   /**
    * label for current section
    * @return {String}
    */
   sectionLabel: function () {
-    return this.get('section').classify();
+    return this.get('section').classify().replace(/([A-Z])/g, ' $1');
   }.property(),
 
   /**
    * Return True is section name equals 'general'
    * @type {Boolean}
    */
-  isGeneral:Ember.computed.equal('section', 'general'),
+  isGeneral: Ember.computed.equal('section', 'general'),
+
+  /**
+   * Return True is section name equals 'custom'
+   * @type {Boolean}
+   */
+  isCustom: Ember.computed.equal('section', 'custom'),
 
   /**
    * Filtered configs for current section
    */
-  sectionConfigs: Ember.computed.filter('config', function(item) {
+  sectionConfigs: Ember.computed.filter('config', function (item) {
     if (this.get('isGeneral')) {
-      return !item.name.match('^site.');
-    } else {
-      return !!item.name.match('^site.'+this.get('section')) ;
+      return !item.name.match('^site.') && this.get('predefinedConfigNames').contains(item.name);
+    }
+    else {
+      if (this.get('isCustom')) {
+        return !this.get('predefinedConfigNames').contains(item.name);
+      }
+      else {
+        return !!item.name.match('^site.' + this.get('section'));
+      }
+    }
+  }),
+
+  /**
+   * Is button "Add Property" visible
+   * True - yes, false - no (and "App Property"-form is visible)
+   * @type {bool}
+   */
+  buttonVisible: true,
+
+  /**
+   * Template for new config
+   * @type {Ember.Object}
+   */
+  newConfig: Em.Object.create({
+    name: '',
+    value: '',
+    nameError: '',
+    hasError: false
+  }),
+
+  /**
+   * Clear <code>newConfig</code>
+   * @method cleanNewConfig
+   */
+  cleanNewConfig: function() {
+    this.get('newConfig').setProperties({
+      name: '',
+      value: '',
+      messsage: '',
+      hasError: false
+    });
+  },
+
+  actions: {
+
+    /**
+     * Click on "App Property"-button
+     * @method addProperty
+     */
+    addProperty: function() {
+      this.toggleProperty('buttonVisible');
+    },
+
+    /**
+     * Delete custom config added by user
+     * @param {{name: string, label: string, value: *}} config
+     * @method deleteConfig
+     */
+    deleteConfig: function(config) {
+      this.get('config').removeObject(config);
+    },
+
+    /**
+     * Validate and save custom config added by user
+     * @method submit
+     */
+    submit: function() {
+      var name = this.get('newConfig.name'),
+        value = this.get('newConfig.value');
+      if (this.get('config').mapBy('name').contains(name)) {
+        this.get('newConfig').setProperties({
+          hasError: true,
+          messsage: Em.I18n.t('configs.add_property.name_exists')
+        });
+        return;
+      }
+      if (!/^[A-Za-z][A-Za-z0-9_\-\.]*$/.test(name)) {
+        this.get('newConfig').setProperties({
+          hasError: true,
+          messsage: Em.I18n.t('configs.add_property.invalid_name')
+        });
+        return;
+      }
+      this.get('config').pushObject({name: name, value: value, label: name});
+      this.cleanNewConfig();
+      this.toggleProperty('buttonVisible');
+    },
+
+    /**
+     * Hide "Add Property"-form
+     * @method discard
+     */
+    discard: function() {
+      this.cleanNewConfig();
+      this.toggleProperty('buttonVisible');
     }
-  })
+  }
+
 });

+ 1 - 0
contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step1_controller.js

@@ -171,6 +171,7 @@ App.CreateAppWizardStep1Controller = Ember.Controller.extend({
     newApp.set('appType', this.get('selectedType'));
     newApp.set('name', this.get('newAppName'));
     newApp.set('configs', this.get('selectedType.configs'));
+    newApp.set('predefinedConfigNames', Em.keys(this.get('selectedType.configs')));
     this.set('appWizardController.newApp', newApp);
   },
 

+ 7 - 6
contrib/views/slider/src/main/resources/ui/app/controllers/createAppWizard/step3_controller.js

@@ -31,19 +31,19 @@ App.CreateAppWizardStep3Controller = Ember.ObjectController.extend({
   configs: Em.A(),
 
   /**
-   * Convert configs to array of uniq section names
-   * @return {Array}
+   * Convert configs to array of unique section names
+   * @type {Array}
    */
-  sectionKeys:function () {
+  sectionKeys: function () {
     var configs = this.get('newAppConfigs') || {},
-        k = ["general"];
+      k = ["general"];
 
     Object.keys(configs).forEach(function (key) {
       if (key.split('.')[0] == "site") {
         k.push(key.split('.')[1])
       }
     });
-
+    k.push('custom');
     return k.uniq();
   }.property('newAppConfigs'),
 
@@ -111,7 +111,7 @@ App.CreateAppWizardStep3Controller = Ember.ObjectController.extend({
     try {
       configs.forEach(function (item) {
         configsObject[item.name] = item.value;
-      })
+      });
       self.set('configsObject', configsObject);
     } catch (e) {
       self.set('isError', true);
@@ -129,6 +129,7 @@ App.CreateAppWizardStep3Controller = Ember.ObjectController.extend({
   },
 
   actions: {
+
     /**
      * If <code>configs</code> is valid, than save it and proceed to the next step
      */

+ 24 - 3
contrib/views/slider/src/main/resources/ui/app/controllers/create_app_wizard_controller.js

@@ -49,17 +49,38 @@ App.CreateAppWizardController = Ember.ObjectController.extend({
   /**
    * Proceed user to selected step
    * @param {number} step step's number
-   * @param {bool} fromNextButon is user came from "Next"-button click
+   * @param {bool} fromNextButton is user came from "Next"-button click
    * @method gotoStep
    */
-  gotoStep: function (step, fromNextButon) {
-    if (step > this.get('TOTAL_STEPS_NUMBER') || step < 1 || (!fromNextButon && step > this.get('currentStep'))) {
+  gotoStep: function (step, fromNextButton) {
+    if (step > this.get('TOTAL_STEPS_NUMBER') || step < 1 || (!fromNextButton && step > this.get('currentStep'))) {
       return;
     }
     this.set('currentStep', step);
+
+    if (step == 1) {
+      this.dropCustomConfigs();
+    }
     this.transitionToRoute('createAppWizard.step' + step);
   },
 
+  /**
+   * Custom configs added by used should be dropped if user come back to the 1st step
+   * @method dropCustomConfigs
+   */
+  dropCustomConfigs: function() {
+    var configs = this.get('newApp.configs'),
+      predefined = this.get('newApp.predefinedConfigNames'),
+      filtered = {};
+    if (!configs) return;
+    Em.keys(configs).forEach(function(name) {
+      if (predefined.contains(name)) {
+        filtered[name] = configs[name];
+      }
+    });
+    this.set('newApp.configs', filtered);
+  },
+
   /**
    * Proceed user no next step
    * @method nextStep

+ 52 - 6
contrib/views/slider/src/main/resources/ui/app/templates/components/configSection.hbs

@@ -18,13 +18,59 @@
 
 {{#bs-panel heading=sectionLabel collapsible=true dismiss=false open=isGeneral }}
   <form class="form-horizontal" role="form">
-    {{#each sectionConfigs}}
-    <div class="form-group">
-      <label class="col-sm-4 control-label">{{formatWordBreak label devider='.'}}</label>
-      <div class="col-sm-6">
-        {{input value=value class="form-control"}}
+    {{#each config in sectionConfigs}}
+      <div class="form-group">
+
+        <label class="col-sm-4 control-label">{{formatWordBreak config.label devider='.'}}</label>
+
+        <div class="col-sm-6">
+          {{input value=config.value class="form-control"}}
+        </div>
+
+        {{#if isCustom}}
+          <div class="col-sm-2">
+            {{#bs-button clicked="deleteConfig" clickedParamBinding="config" type="danger"}}{{t common.delete}}{{/bs-button}}
+          </div>
+        {{/if}}
+
       </div>
-    </div>
     {{/each}}
   </form>
+  {{#if isCustom}}
+    {{#if buttonVisible}}
+      {{#bs-button clicked="addProperty" type="primary"}}{{t configs.add_property}}{{/bs-button}}
+    {{else}}
+      {{! "Add Property"-form}}
+      <form class="form-horizontal" role="form">
+        <div class="form-group">
+          <div class="col-sm-4">
+            <label class="control-label">{{t common.name}}</label>
+          </div>
+          <div class="col-sm-6">
+            <label class="control-label">{{t common.value}}</label>
+          </div>
+        </div>
+        <div {{bind-attr class=":form-group newConfig.hasError:has-error"}}>
+          <div class="col-sm-4">
+            {{input value=newConfig.name class="form-control"}}
+          </div>
+          <div class="col-sm-6">
+            {{input value=newConfig.value class="form-control"}}
+          </div>
+        </div>
+        <div class="form-group">
+          {{#if newConfig.hasError}}
+            <div class="col-sm-10">
+              <div class="alert alert-danger">
+                {{newConfig.messsage}}
+                </div>
+            </div>
+          {{/if}}
+        </div>
+        {{#bs-button clicked="submit" type="primary"}}{{t common.add}}{{/bs-button}}
+        {{#bs-button clicked="discard"}}{{t common.cancel}}{{/bs-button}}
+      </form>
+    {{! "Add Property"-form end}}
+    {{/if}}
+  {{/if}}
 {{/bs-panel}}

+ 5 - 1
contrib/views/slider/src/main/resources/ui/app/templates/createAppWizard/step3.hbs

@@ -21,7 +21,11 @@
 </p>
 <div {{bind-attr class="controller.isError:has-error :form-group"}}>
   {{#each controller.sectionKeys}}
-    {{config-section section=this config=controller.configs}}
+    {{config-section
+      section=this
+      config=controller.configs
+      predefinedConfigNames=controller.appWizardController.newApp.predefinedConfigNames
+    }}
   {{/each}}
   {{#if controller.isError}}
     <div class="alert alert-danger">{{t wizard.step3.error}}</div>

+ 6 - 0
contrib/views/slider/src/main/resources/ui/app/translations.js

@@ -24,11 +24,13 @@ Em.I18n.translations = {
   'no': 'No',
 
   'common' : {
+    'add': 'Add',
     'show': 'Show',
     'actions': 'Actions',
     'cancel': 'Cancel',
     'name': "Name",
     'back': "Back",
+    'delete': 'Delete',
     'value': "Value",
     'next': "Next",
     'quickLinks': "Quick Links",
@@ -58,6 +60,10 @@ Em.I18n.translations = {
   'tableView.filters.clearSelection': 'clear selection All',
   'tableView.filters.noItems' : 'There are no items to show',
 
+  'configs.add_property': 'Add Property',
+  'configs.add_property.invalid_name': 'Config name should consists only of letters, numbers, \'-\', \'_\', \'.\' and first character should be a letter.',
+  'configs.add_property.name_exists': 'Config name already exists',
+
   'slider.apps.title': 'Slider Apps',
   'slider.apps.create': 'Create App',
   'sliderApps.filters.info': '{0} of {1} sliders showing',