Browse Source

AMBARI-10234. Widgets validation rules should affect config internal valid/invalid state (onechiporenko)

Oleg Nechiporenko 10 years ago
parent
commit
589faa74a9

+ 13 - 3
ambari-web/app/views/common/configs/widgets/list_config_widget_view.js

@@ -98,6 +98,12 @@ App.ListConfigWidgetView = App.ConfigWidgetView.extend({
    */
    */
   allowedToSelect: 1,
   allowedToSelect: 1,
 
 
+  /**
+   * Minimum number of options needed to select (based on <code>config.valueAttributes.selection_cardinality</code>)
+   * @type {number}
+   */
+  neededToSelect: 0,
+
   templateName: require('templates/common/configs/widgets/list_config_widget'),
   templateName: require('templates/common/configs/widgets/list_config_widget'),
 
 
   willInsertElement: function () {
   willInsertElement: function () {
@@ -177,24 +183,28 @@ App.ListConfigWidgetView = App.ConfigWidgetView.extend({
 
 
   /**
   /**
    * If user already selected maximum of allowed options, disable other options
    * If user already selected maximum of allowed options, disable other options
+   * If user selected less than minimum of needed options, mark config.value as invalid
    * If user deselect some option, all disabled options become enabled
    * If user deselect some option, all disabled options become enabled
    * Triggers on each option select/deselect
    * Triggers on each option select/deselect
    * @method checkSelectedItemsCount
    * @method checkSelectedItemsCount
    */
    */
   checkSelectedItemsCount: function () {
   checkSelectedItemsCount: function () {
     var allowedToSelect = this.get('allowedToSelect'),
     var allowedToSelect = this.get('allowedToSelect'),
+      neededToSelect = this.get('neededToSelect'),
       currentlySelected = this.get('options').filterProperty('isSelected').length,
       currentlySelected = this.get('options').filterProperty('isSelected').length,
       selectionDisabled = allowedToSelect <= currentlySelected;
       selectionDisabled = allowedToSelect <= currentlySelected;
     this.get('options').filterProperty('isSelected', false).setEach('isDisabled', selectionDisabled);
     this.get('options').filterProperty('isSelected', false).setEach('isDisabled', selectionDisabled);
+    this.set('config.errorMessage', currentlySelected < neededToSelect ? 'You should select at least ' + neededToSelect + ' item(s)' : '');
   },
   },
 
 
   /**
   /**
-   * Get maximum number of options allowed to select basing on config cardinality value
+   * Get maximum number of options allowed to select and needed to select basing on config cardinality value
    * @method parseCardinality
    * @method parseCardinality
    */
    */
   parseCardinality: function () {
   parseCardinality: function () {
-    var cardinality = numberUtils.getCardinalityValue(this.get('config.stackConfigProperty.valueAttributes.selection_cardinality'), true);
-    this.set('allowedToSelect', cardinality);
+    var cardinality = this.get('config.stackConfigProperty.valueAttributes.selection_cardinality');
+    this.set('allowedToSelect', numberUtils.getCardinalityValue(cardinality, true));
+    this.set('neededToSelect', numberUtils.getCardinalityValue(cardinality, false));
   },
   },
 
 
   /**
   /**

+ 3 - 0
ambari-web/app/views/common/configs/widgets/slider_config_widget_view.js

@@ -111,6 +111,7 @@ App.SliderConfigWidgetView = App.ConfigWidgetView.extend({
       var parsed = parseFunction(mirrorValue);
       var parsed = parseFunction(mirrorValue);
       if (parsed >= min && parsed <= max) {
       if (parsed >= min && parsed <= max) {
         this.set('isMirrorValueValid', true);
         this.set('isMirrorValueValid', true);
+        this.set('config.errorMessage', '');
         this.set('config.value', '' + parsed);
         this.set('config.value', '' + parsed);
         if (slider) {
         if (slider) {
           slider.setValue(parsed);
           slider.setValue(parsed);
@@ -118,10 +119,12 @@ App.SliderConfigWidgetView = App.ConfigWidgetView.extend({
       }
       }
       else {
       else {
         this.set('isMirrorValueValid', false);
         this.set('isMirrorValueValid', false);
+        this.set('config.errorMessage', 'Invalid value');
       }
       }
     }
     }
     else {
     else {
       this.set('isMirrorValueValid', false);
       this.set('isMirrorValueValid', false);
+      this.set('config.errorMessage', 'Invalid value');
     }
     }
   },
   },
 
 

+ 5 - 2
ambari-web/app/views/common/configs/widgets/time_interval_spinner_view.js

@@ -251,8 +251,11 @@ App.TimeIntervalSpinnerView = App.ConfigWidgetView.extend({
     else if (convertedValue > parseInt(this.get('config.stackConfigProperty.valueAttributes.maximum'))) {
     else if (convertedValue > parseInt(this.get('config.stackConfigProperty.valueAttributes.maximum'))) {
       errorMessage = Em.I18n.t('number.validate.moreThanMaximum').format(this.dateToText(this.get('maxValue')));
       errorMessage = Em.I18n.t('number.validate.moreThanMaximum').format(this.dateToText(this.get('maxValue')));
     }
     }
-    this.set('isValid', !errorMessage);
-    this.set('errorMessage', errorMessage);
+    this.setProperties({
+      isValid: !errorMessage,
+      errorMessage: errorMessage
+    });
+    this.get('config').set('errorMessage', errorMessage);
   },
   },
 
 
   /**
   /**

+ 16 - 0
ambari-web/test/views/common/configs/widgets/list_config_widget_view_test.js

@@ -138,4 +138,20 @@ describe('App.ListConfigWidgetView', function () {
 
 
   });
   });
 
 
+  describe('#checkSelectedItemsCount', function () {
+
+    beforeEach(function () {
+      view.set('config.stackConfigProperty.valueAttributes.selection_cardinality', '1+');
+      view.parseCardinality();
+    });
+
+    it('should check minimum count of the selected items', function () {
+      view.get('options').setEach('isSelected', false);
+      expect(view.get('config.errorMessage')).to.have.property('length').that.is.least(1);
+      view.get('options').setEach('isSelected', true);
+      expect(view.get('config.errorMessage')).to.equal('');
+    });
+
+  });
+
 });
 });

+ 4 - 0
ambari-web/test/views/common/configs/widgets/slider_config_widget_view_test.js

@@ -86,20 +86,24 @@ describe('App.SliderConfigWidgetView', function () {
       viewInt.set('mirrorValue', 1000);
       viewInt.set('mirrorValue', 1000);
       expect(viewInt.get('isMirrorValueValid')).to.be.true;
       expect(viewInt.get('isMirrorValueValid')).to.be.true;
       expect(viewInt.get('config.value')).to.equal('1000');
       expect(viewInt.get('config.value')).to.equal('1000');
+      expect(viewInt.get('config.errorMessage')).to.equal('');
 
 
       viewInt.set('mirrorValue', 100500);
       viewInt.set('mirrorValue', 100500);
       expect(viewInt.get('isMirrorValueValid')).to.be.false;
       expect(viewInt.get('isMirrorValueValid')).to.be.false;
       expect(viewInt.get('config.value')).to.equal('1000');
       expect(viewInt.get('config.value')).to.equal('1000');
+      expect(viewInt.get('config.errorMessage')).to.have.property('length').that.is.least(1);
     });
     });
 
 
     it('check float', function () {
     it('check float', function () {
       viewFloat.set('mirrorValue', 55.5);
       viewFloat.set('mirrorValue', 55.5);
       expect(viewFloat.get('isMirrorValueValid')).to.be.true;
       expect(viewFloat.get('isMirrorValueValid')).to.be.true;
       expect(viewFloat.get('config.value')).to.equal('55.5');
       expect(viewFloat.get('config.value')).to.equal('55.5');
+      expect(viewFloat.get('config.errorMessage')).to.equal('');
 
 
       viewFloat.set('mirrorValue', 100500.5);
       viewFloat.set('mirrorValue', 100500.5);
       expect(viewFloat.get('isMirrorValueValid')).to.be.false;
       expect(viewFloat.get('isMirrorValueValid')).to.be.false;
       expect(viewFloat.get('config.value')).to.equal('55.5');
       expect(viewFloat.get('config.value')).to.equal('55.5');
+      expect(viewFloat.get('config.errorMessage')).to.have.property('length').that.is.least(1);
     });
     });
 
 
   });
   });

+ 3 - 1
ambari-web/test/views/common/configs/widgets/time_interval_spinner_view_test.js

@@ -19,6 +19,7 @@
 var App = require('app');
 var App = require('app');
 
 
 describe('App.TimeIntervalSpinnerView', function() {
 describe('App.TimeIntervalSpinnerView', function() {
+
   describe('#convertToWidgetUnits', function(){
   describe('#convertToWidgetUnits', function(){
     beforeEach(function() {
     beforeEach(function() {
       this.view = App.TimeIntervalSpinnerView.create({});
       this.view = App.TimeIntervalSpinnerView.create({});
@@ -86,7 +87,7 @@ describe('App.TimeIntervalSpinnerView', function() {
         inputType: 'hours',
         inputType: 'hours',
         desiredUnits: "hours",
         desiredUnits: "hours",
         e: [
         e: [
-          { label: 'Hours', value: 2},
+          { label: 'Hours', value: 2}
         ]
         ]
       }
       }
     ];
     ];
@@ -139,4 +140,5 @@ describe('App.TimeIntervalSpinnerView', function() {
       });
       });
     });
     });
   });
   });
+
 });
 });