@zeedhi/common 1.95.1 → 1.96.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1975,7 +1975,9 @@ class Input extends ComponentRender {
1975
1975
  */
1976
1976
  addValidation(name, config) {
1977
1977
  const validation = Validation.get(name)(config);
1978
- this.validations[name] = config;
1978
+ if (config) {
1979
+ this.validations[name] = config;
1980
+ }
1979
1981
  this.parsedValidations[name] = validation;
1980
1982
  this.updateRules();
1981
1983
  }
@@ -4933,7 +4935,37 @@ class FileInput extends TextInput {
4933
4935
  }
4934
4936
  }
4935
4937
  }
4936
- }
4938
+ setViewGetFileSizes(getFileSizes) {
4939
+ this.viewGetFileSizes = getFileSizes;
4940
+ }
4941
+ updateRules() {
4942
+ this.rules = Object.keys(this.parsedValidations)
4943
+ .map((key) => {
4944
+ const validation = this.parsedValidations[key];
4945
+ if (key !== 'maxFileSize')
4946
+ return () => validation(this.value);
4947
+ return () => {
4948
+ if (this.viewGetFileSizes) {
4949
+ const fileSizes = this.viewGetFileSizes();
4950
+ return validation(fileSizes);
4951
+ }
4952
+ return true;
4953
+ };
4954
+ });
4955
+ }
4956
+ }
4957
+ Validation.register('maxFileSize', (config) => (fileSizes) => {
4958
+ let fileError = '';
4959
+ Object.keys(fileSizes).some((fileName) => {
4960
+ if (fileSizes[fileName] > config.limit) {
4961
+ fileError = fileName;
4962
+ return true;
4963
+ }
4964
+ return false;
4965
+ });
4966
+ const message = I18n.translate((config.message || 'VALIDATION_FILE_SIZE'), { fileError });
4967
+ return (fileError === '') || message;
4968
+ });
4937
4969
 
4938
4970
  /**
4939
4971
  * Base class for Footer component.
@@ -7499,6 +7531,12 @@ class Select extends TextInput {
7499
7531
  [searchIn]: value,
7500
7532
  },
7501
7533
  }),
7534
+ DYNAMIC_FILTER: (value, search_in) => {
7535
+ const arrayValue = Array.isArray(value) ? value : Array.of(value);
7536
+ const filter = arrayValue.map((item) => ({ operation: 'EQUALS', relation: 'OR', value: item }));
7537
+ const dynamicFilter = { [search_in]: filter };
7538
+ return { dynamicFilter };
7539
+ },
7502
7540
  };
7503
7541
  /**
7504
7542
  * Input search value
@@ -7641,13 +7679,16 @@ class Select extends TextInput {
7641
7679
  */
7642
7680
  getItemsBySearchValue(value, searchIn) {
7643
7681
  return __awaiter(this, void 0, void 0, function* () {
7644
- const config = Object.assign(Object.assign(Object.assign({}, this.datasource.clone()), this.dsSearch[this.searchParam](value, searchIn)), { lazyLoad: true });
7682
+ const config = Object.assign(Object.assign(Object.assign({}, this.datasource.clone()), this.dsSearch[this.searchParam](value, searchIn)), { lazyLoad: true, loadAll: Array.isArray(value) });
7645
7683
  this.datasource.loading = true;
7646
7684
  const datasource = DatasourceFactory.factory(config);
7647
7685
  const items = yield datasource.get();
7648
7686
  this.datasource.loading = false;
7649
7687
  datasource.destroy();
7650
- return items.find(this.getCondition(value));
7688
+ if (Array.isArray(value)) {
7689
+ return items.filter((item) => value.includes(item[this.dataValue]));
7690
+ }
7691
+ return items.filter(this.getCondition(value));
7651
7692
  });
7652
7693
  }
7653
7694
  getCondition(filterValue) {
@@ -7752,7 +7793,7 @@ class Select extends TextInput {
7752
7793
  const foundInData = this.datasource.data.find(this.getCondition(filterValue));
7753
7794
  let searchValue = foundInData;
7754
7795
  if (!foundInData && !this.manualMode) {
7755
- searchValue = yield this.getItemsBySearchValue(filterValue, searchIn);
7796
+ [searchValue] = yield this.getItemsBySearchValue(filterValue, searchIn);
7756
7797
  }
7757
7798
  if (!searchValue) {
7758
7799
  this.setFieldRowValue(null);
@@ -9852,12 +9893,16 @@ class SelectMultiple extends Select {
9852
9893
  */
9853
9894
  this.limit = null;
9854
9895
  this.showSelectAll = false;
9896
+ this.showCheckboxAll = false;
9897
+ this.checkboxAllValue = false;
9855
9898
  if (!this.selectedValue) {
9856
9899
  this.selectedValue = [];
9857
9900
  }
9858
9901
  this.showSelectAll = this.getInitValue('showSelectAll', props.showSelectAll, this.showSelectAll);
9859
9902
  this.maxRows = this.getInitValue('maxRows', props.maxRows, this.maxRows);
9860
9903
  this.limit = this.getInitValue('limit', props.limit, this.limit);
9904
+ this.showCheckboxAll = this.getInitValue('showCheckboxAll', props.showCheckboxAll, this.showCheckboxAll);
9905
+ this.checkboxAll = this.getInitValue('checkboxAll', props.checkboxAll, this.checkboxAll);
9861
9906
  if (!Array.isArray(this.dataText))
9862
9907
  this.dataText = [this.dataText];
9863
9908
  this.internalDisplayValue = this.getDisplayValue();
@@ -9887,6 +9932,13 @@ class SelectMultiple extends Select {
9887
9932
  this.selectedValue = rows;
9888
9933
  this.setFieldValue(this.getValues(rows));
9889
9934
  }
9935
+ get checkboxAll() {
9936
+ return this.checkboxAllValue;
9937
+ }
9938
+ set checkboxAll(value) {
9939
+ this.disabled = value;
9940
+ this.checkboxAllValue = value;
9941
+ }
9890
9942
  /**
9891
9943
  * Removes item from array a and add it to array b if condition is satisfied
9892
9944
  */
@@ -9898,8 +9950,8 @@ class SelectMultiple extends Select {
9898
9950
  }
9899
9951
  setFieldValue(value) {
9900
9952
  return __awaiter(this, void 0, void 0, function* () {
9901
- const promises = [];
9902
- const searchValues = [];
9953
+ const foundValues = [];
9954
+ const searchedValues = [];
9903
9955
  let pushed = false;
9904
9956
  value.forEach((row) => {
9905
9957
  let filterValue;
@@ -9909,27 +9961,37 @@ class SelectMultiple extends Select {
9909
9961
  else {
9910
9962
  filterValue = row;
9911
9963
  }
9912
- const searchIn = this.dataValue;
9913
9964
  const foundInData = this.datasource.data.find(this.getCondition(filterValue));
9914
9965
  if (foundInData) {
9915
- searchValues.push(foundInData);
9966
+ foundValues.push(foundInData);
9916
9967
  }
9917
9968
  else if (!this.manualMode) {
9918
- promises.push(this.getItemsBySearchValue(filterValue, searchIn).then((item) => {
9919
- if (item) {
9920
- searchValues.push(item);
9921
- this.datasource.data.unshift(item);
9922
- this.insertedValues.push(item);
9923
- pushed = true;
9924
- }
9925
- }));
9969
+ searchedValues.push(filterValue);
9926
9970
  }
9927
9971
  });
9928
- if (promises.length) {
9972
+ const insertItem = (item) => __awaiter(this, void 0, void 0, function* () {
9973
+ if (!item)
9974
+ return;
9975
+ foundValues.push(item);
9976
+ this.datasource.data.unshift(item);
9977
+ this.insertedValues.push(item);
9978
+ pushed = true;
9979
+ });
9980
+ // using filter/find/dynamicFilter should make only 1 request
9981
+ // using normal search should make one request per search value
9982
+ if (this.searchParam !== 'SEARCH') {
9983
+ const items = yield this.getItemsBySearchValue(searchedValues, this.dataValue);
9984
+ items.forEach(insertItem);
9985
+ }
9986
+ else {
9987
+ const promises = searchedValues.map((searchedValue) => __awaiter(this, void 0, void 0, function* () {
9988
+ const [item] = yield this.getItemsBySearchValue(searchedValue, this.dataValue);
9989
+ insertItem(item);
9990
+ }));
9929
9991
  yield Promise.all(promises);
9930
9992
  }
9931
- if (searchValues.length > 0) {
9932
- this.setFieldRowValue(searchValues);
9993
+ if (foundValues.length > 0) {
9994
+ this.setFieldRowValue(foundValues);
9933
9995
  }
9934
9996
  else {
9935
9997
  this.setFieldRowValue([]);
@@ -10178,6 +10240,18 @@ class SelectMultiple extends Select {
10178
10240
  }
10179
10241
  this.cachedTotal = this.datasource.total;
10180
10242
  }
10243
+ /**
10244
+ * Updates input rules.
10245
+ */
10246
+ updateRules() {
10247
+ this.rules = Object.keys(this.parsedValidations)
10248
+ .map((key) => () => {
10249
+ const validation = this.parsedValidations[key];
10250
+ if (key !== 'required')
10251
+ return validation(this.value);
10252
+ return validation((this.checkboxAll && 'all') || this.value);
10253
+ });
10254
+ }
10181
10255
  }
10182
10256
 
10183
10257
  class TreeDataStructure {
@@ -1982,7 +1982,9 @@
1982
1982
  */
1983
1983
  addValidation(name, config) {
1984
1984
  const validation = core.Validation.get(name)(config);
1985
- this.validations[name] = config;
1985
+ if (config) {
1986
+ this.validations[name] = config;
1987
+ }
1986
1988
  this.parsedValidations[name] = validation;
1987
1989
  this.updateRules();
1988
1990
  }
@@ -4940,7 +4942,37 @@
4940
4942
  }
4941
4943
  }
4942
4944
  }
4943
- }
4945
+ setViewGetFileSizes(getFileSizes) {
4946
+ this.viewGetFileSizes = getFileSizes;
4947
+ }
4948
+ updateRules() {
4949
+ this.rules = Object.keys(this.parsedValidations)
4950
+ .map((key) => {
4951
+ const validation = this.parsedValidations[key];
4952
+ if (key !== 'maxFileSize')
4953
+ return () => validation(this.value);
4954
+ return () => {
4955
+ if (this.viewGetFileSizes) {
4956
+ const fileSizes = this.viewGetFileSizes();
4957
+ return validation(fileSizes);
4958
+ }
4959
+ return true;
4960
+ };
4961
+ });
4962
+ }
4963
+ }
4964
+ core.Validation.register('maxFileSize', (config) => (fileSizes) => {
4965
+ let fileError = '';
4966
+ Object.keys(fileSizes).some((fileName) => {
4967
+ if (fileSizes[fileName] > config.limit) {
4968
+ fileError = fileName;
4969
+ return true;
4970
+ }
4971
+ return false;
4972
+ });
4973
+ const message = core.I18n.translate((config.message || 'VALIDATION_FILE_SIZE'), { fileError });
4974
+ return (fileError === '') || message;
4975
+ });
4944
4976
 
4945
4977
  /**
4946
4978
  * Base class for Footer component.
@@ -7506,6 +7538,12 @@
7506
7538
  [searchIn]: value,
7507
7539
  },
7508
7540
  }),
7541
+ DYNAMIC_FILTER: (value, search_in) => {
7542
+ const arrayValue = Array.isArray(value) ? value : Array.of(value);
7543
+ const filter = arrayValue.map((item) => ({ operation: 'EQUALS', relation: 'OR', value: item }));
7544
+ const dynamicFilter = { [search_in]: filter };
7545
+ return { dynamicFilter };
7546
+ },
7509
7547
  };
7510
7548
  /**
7511
7549
  * Input search value
@@ -7648,13 +7686,16 @@
7648
7686
  */
7649
7687
  getItemsBySearchValue(value, searchIn) {
7650
7688
  return __awaiter(this, void 0, void 0, function* () {
7651
- const config = Object.assign(Object.assign(Object.assign({}, this.datasource.clone()), this.dsSearch[this.searchParam](value, searchIn)), { lazyLoad: true });
7689
+ const config = Object.assign(Object.assign(Object.assign({}, this.datasource.clone()), this.dsSearch[this.searchParam](value, searchIn)), { lazyLoad: true, loadAll: Array.isArray(value) });
7652
7690
  this.datasource.loading = true;
7653
7691
  const datasource = core.DatasourceFactory.factory(config);
7654
7692
  const items = yield datasource.get();
7655
7693
  this.datasource.loading = false;
7656
7694
  datasource.destroy();
7657
- return items.find(this.getCondition(value));
7695
+ if (Array.isArray(value)) {
7696
+ return items.filter((item) => value.includes(item[this.dataValue]));
7697
+ }
7698
+ return items.filter(this.getCondition(value));
7658
7699
  });
7659
7700
  }
7660
7701
  getCondition(filterValue) {
@@ -7759,7 +7800,7 @@
7759
7800
  const foundInData = this.datasource.data.find(this.getCondition(filterValue));
7760
7801
  let searchValue = foundInData;
7761
7802
  if (!foundInData && !this.manualMode) {
7762
- searchValue = yield this.getItemsBySearchValue(filterValue, searchIn);
7803
+ [searchValue] = yield this.getItemsBySearchValue(filterValue, searchIn);
7763
7804
  }
7764
7805
  if (!searchValue) {
7765
7806
  this.setFieldRowValue(null);
@@ -9859,12 +9900,16 @@
9859
9900
  */
9860
9901
  this.limit = null;
9861
9902
  this.showSelectAll = false;
9903
+ this.showCheckboxAll = false;
9904
+ this.checkboxAllValue = false;
9862
9905
  if (!this.selectedValue) {
9863
9906
  this.selectedValue = [];
9864
9907
  }
9865
9908
  this.showSelectAll = this.getInitValue('showSelectAll', props.showSelectAll, this.showSelectAll);
9866
9909
  this.maxRows = this.getInitValue('maxRows', props.maxRows, this.maxRows);
9867
9910
  this.limit = this.getInitValue('limit', props.limit, this.limit);
9911
+ this.showCheckboxAll = this.getInitValue('showCheckboxAll', props.showCheckboxAll, this.showCheckboxAll);
9912
+ this.checkboxAll = this.getInitValue('checkboxAll', props.checkboxAll, this.checkboxAll);
9868
9913
  if (!Array.isArray(this.dataText))
9869
9914
  this.dataText = [this.dataText];
9870
9915
  this.internalDisplayValue = this.getDisplayValue();
@@ -9894,6 +9939,13 @@
9894
9939
  this.selectedValue = rows;
9895
9940
  this.setFieldValue(this.getValues(rows));
9896
9941
  }
9942
+ get checkboxAll() {
9943
+ return this.checkboxAllValue;
9944
+ }
9945
+ set checkboxAll(value) {
9946
+ this.disabled = value;
9947
+ this.checkboxAllValue = value;
9948
+ }
9897
9949
  /**
9898
9950
  * Removes item from array a and add it to array b if condition is satisfied
9899
9951
  */
@@ -9905,8 +9957,8 @@
9905
9957
  }
9906
9958
  setFieldValue(value) {
9907
9959
  return __awaiter(this, void 0, void 0, function* () {
9908
- const promises = [];
9909
- const searchValues = [];
9960
+ const foundValues = [];
9961
+ const searchedValues = [];
9910
9962
  let pushed = false;
9911
9963
  value.forEach((row) => {
9912
9964
  let filterValue;
@@ -9916,27 +9968,37 @@
9916
9968
  else {
9917
9969
  filterValue = row;
9918
9970
  }
9919
- const searchIn = this.dataValue;
9920
9971
  const foundInData = this.datasource.data.find(this.getCondition(filterValue));
9921
9972
  if (foundInData) {
9922
- searchValues.push(foundInData);
9973
+ foundValues.push(foundInData);
9923
9974
  }
9924
9975
  else if (!this.manualMode) {
9925
- promises.push(this.getItemsBySearchValue(filterValue, searchIn).then((item) => {
9926
- if (item) {
9927
- searchValues.push(item);
9928
- this.datasource.data.unshift(item);
9929
- this.insertedValues.push(item);
9930
- pushed = true;
9931
- }
9932
- }));
9976
+ searchedValues.push(filterValue);
9933
9977
  }
9934
9978
  });
9935
- if (promises.length) {
9979
+ const insertItem = (item) => __awaiter(this, void 0, void 0, function* () {
9980
+ if (!item)
9981
+ return;
9982
+ foundValues.push(item);
9983
+ this.datasource.data.unshift(item);
9984
+ this.insertedValues.push(item);
9985
+ pushed = true;
9986
+ });
9987
+ // using filter/find/dynamicFilter should make only 1 request
9988
+ // using normal search should make one request per search value
9989
+ if (this.searchParam !== 'SEARCH') {
9990
+ const items = yield this.getItemsBySearchValue(searchedValues, this.dataValue);
9991
+ items.forEach(insertItem);
9992
+ }
9993
+ else {
9994
+ const promises = searchedValues.map((searchedValue) => __awaiter(this, void 0, void 0, function* () {
9995
+ const [item] = yield this.getItemsBySearchValue(searchedValue, this.dataValue);
9996
+ insertItem(item);
9997
+ }));
9936
9998
  yield Promise.all(promises);
9937
9999
  }
9938
- if (searchValues.length > 0) {
9939
- this.setFieldRowValue(searchValues);
10000
+ if (foundValues.length > 0) {
10001
+ this.setFieldRowValue(foundValues);
9940
10002
  }
9941
10003
  else {
9942
10004
  this.setFieldRowValue([]);
@@ -10185,6 +10247,18 @@
10185
10247
  }
10186
10248
  this.cachedTotal = this.datasource.total;
10187
10249
  }
10250
+ /**
10251
+ * Updates input rules.
10252
+ */
10253
+ updateRules() {
10254
+ this.rules = Object.keys(this.parsedValidations)
10255
+ .map((key) => () => {
10256
+ const validation = this.parsedValidations[key];
10257
+ if (key !== 'required')
10258
+ return validation(this.value);
10259
+ return validation((this.checkboxAll && 'all') || this.value);
10260
+ });
10261
+ }
10188
10262
  }
10189
10263
 
10190
10264
  class TreeDataStructure {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeedhi/common",
3
- "version": "1.95.1",
3
+ "version": "1.96.0",
4
4
  "description": "Zeedhi Common",
5
5
  "author": "Zeedhi <zeedhi@teknisa.com>",
6
6
  "license": "ISC",
@@ -43,5 +43,5 @@
43
43
  "lodash.times": "4.3.*",
44
44
  "mockdate": "3.0.*"
45
45
  },
46
- "gitHead": "61b544362928fc5b8e27258a628420d31345e6f3"
46
+ "gitHead": "4df47f4fde302b75598f5744945c86fb3aad4b6a"
47
47
  }
@@ -65,6 +65,7 @@ export declare class FileInput extends TextInput implements IFileInput {
65
65
  */
66
66
  protected internalValue: any;
67
67
  selectFileButton: IButton;
68
+ private viewGetFileSizes;
68
69
  /**
69
70
  * Create a new FileInput
70
71
  * @param props FileInput definition
@@ -95,4 +96,6 @@ export declare class FileInput extends TextInput implements IFileInput {
95
96
  * @param files File array
96
97
  */
97
98
  dropFiles(files: File[]): void;
99
+ setViewGetFileSizes(getFileSizes: () => object): void;
100
+ protected updateRules(): void;
98
101
  }
@@ -135,7 +135,7 @@ export declare class GridEditable extends Grid implements IGridEditable {
135
135
  * @param column Column
136
136
  * @param row Row
137
137
  */
138
- isValid(column: IGridColumnEditable, row: IDictionary, revalidate?: boolean): boolean;
138
+ isValid(column: IGridColumnEditable, row: IDictionary, revalidate?: boolean): string | boolean;
139
139
  private newRowIdentifier;
140
140
  /**
141
141
  * Cancels all edited rows and enable grid components
@@ -110,7 +110,7 @@ export declare class Input extends ComponentRender implements IInput {
110
110
  /**
111
111
  * Parsed field rules.
112
112
  */
113
- private parsedValidations;
113
+ protected parsedValidations: IDictionary<((value: any) => boolean | string)>;
114
114
  protected formatterFn: Function;
115
115
  protected parserFn: Function;
116
116
  protected internalDisplayValue: string;
@@ -124,11 +124,11 @@ export declare class Input extends ComponentRender implements IInput {
124
124
  /**
125
125
  * Validates input.
126
126
  */
127
- validate(): boolean;
127
+ validate(): string | boolean;
128
128
  /**
129
129
  * Sets view validation method.
130
130
  */
131
- setViewValidate(viewValidate: () => boolean): void;
131
+ setViewValidate(viewValidate: () => boolean | string): void;
132
132
  /**
133
133
  * Sets view reset validation method.
134
134
  */
@@ -161,7 +161,7 @@ export declare class Input extends ComponentRender implements IInput {
161
161
  /**
162
162
  * Updates input rules.
163
163
  */
164
- private updateRules;
164
+ protected updateRules(): void;
165
165
  /**
166
166
  * Input value.
167
167
  */
@@ -1,7 +1,7 @@
1
1
  import { IDatasource } from '@zeedhi/core';
2
2
  import { ITextInput } from '../zd-text-input/interfaces';
3
3
  import { IComponentRender } from '../zd-component/interfaces';
4
- export declare type SearchParam = 'SEARCH' | 'FILTER' | 'FIND';
4
+ export declare type SearchParam = 'SEARCH' | 'FILTER' | 'FIND' | 'DYNAMIC_FILTER';
5
5
  export interface ISelect extends ITextInput {
6
6
  autocomplete?: boolean;
7
7
  autoSelection?: boolean;
@@ -97,6 +97,15 @@ export declare class Select extends TextInput implements ISelect {
97
97
  [x: string]: any;
98
98
  };
99
99
  };
100
+ DYNAMIC_FILTER: (value: unknown, search_in: string) => {
101
+ dynamicFilter: {
102
+ [x: string]: {
103
+ operation: string;
104
+ relation: string;
105
+ value: any;
106
+ }[];
107
+ };
108
+ };
100
109
  };
101
110
  /**
102
111
  * Input search value
@@ -135,7 +144,7 @@ export declare class Select extends TextInput implements ISelect {
135
144
  * Finds and retrieves items searching by value
136
145
  * @param value Default value
137
146
  */
138
- protected getItemsBySearchValue(value: any, searchIn: string): Promise<any>;
147
+ protected getItemsBySearchValue(value: any, searchIn: string): Promise<any[]>;
139
148
  protected getCondition(filterValue: any): (row: any) => boolean;
140
149
  focus(event: Event, element: any): Promise<void>;
141
150
  protected afterFocus(): Promise<void>;
@@ -13,4 +13,6 @@ export interface ISelectMultiple extends ISelect {
13
13
  events?: ISelectMultipleEvents;
14
14
  maxRows?: string | number;
15
15
  limit?: number | null;
16
+ showCheckboxAll?: boolean;
17
+ checkboxAll?: boolean;
16
18
  }
@@ -24,6 +24,7 @@ export declare class SelectMultiple extends Select implements ISelectMultiple {
24
24
  */
25
25
  limit: number | null;
26
26
  showSelectAll: boolean;
27
+ showCheckboxAll: boolean;
27
28
  /**
28
29
  * Create a new Select.
29
30
  * @param props Select properties
@@ -34,6 +35,9 @@ export declare class SelectMultiple extends Select implements ISelectMultiple {
34
35
  */
35
36
  get selectValue(): IDictionary<any>[];
36
37
  set selectValue(rows: IDictionary<any>[]);
38
+ private checkboxAllValue;
39
+ get checkboxAll(): boolean;
40
+ set checkboxAll(value: boolean);
37
41
  /**
38
42
  * Removes item from array a and add it to array b if condition is satisfied
39
43
  */
@@ -104,4 +108,8 @@ export declare class SelectMultiple extends Select implements ISelectMultiple {
104
108
  protected checkValueOnBlur(): void;
105
109
  protected afterFocus(): Promise<void>;
106
110
  private setCache;
111
+ /**
112
+ * Updates input rules.
113
+ */
114
+ protected updateRules(): void;
107
115
  }
@@ -126,7 +126,7 @@ export declare class TreeGridEditable extends TreeGrid implements ITreeGridEdita
126
126
  * @param column Column
127
127
  * @param row Row
128
128
  */
129
- isValid(column: IGridColumnEditable, row: IDictionary, revalidate?: boolean): boolean;
129
+ isValid(column: IGridColumnEditable, row: IDictionary, revalidate?: boolean): string | boolean;
130
130
  /**
131
131
  * Cancels all edited rows and enable grid components
132
132
  */