@zeedhi/common 1.108.1 → 1.109.1

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.
@@ -2876,11 +2876,20 @@ class Number$1 extends TextInput {
2876
2876
  this.formatterFn = FormatterParserProvider.getFormatter('ZdNumber');
2877
2877
  this.parserFn = FormatterParserProvider.getParser('ZdNumber');
2878
2878
  this.maskValid = false;
2879
- const newMask = Object.assign(Object.assign({}, this.defaultMask), props.mask);
2879
+ const newMask = this.mergeMasks(this.defaultMask, props.mask);
2880
2880
  this.align = this.getInitValue('align', props.align, this.align);
2881
2881
  this.mask = this.getInitValue('mask', newMask, this.defaultMask);
2882
2882
  this.createAccessors();
2883
2883
  this.validateMask();
2884
+ this.initializeMaskProxy();
2885
+ }
2886
+ /**
2887
+ * Merges two masks
2888
+ */
2889
+ mergeMasks(maskA, maskB) {
2890
+ if (typeof maskB !== 'object')
2891
+ return Object.assign({}, maskA);
2892
+ return Object.assign(Object.assign({}, maskA), maskB);
2884
2893
  }
2885
2894
  validateMask() {
2886
2895
  AutoNumeric.validate(this.mask, true);
@@ -2934,6 +2943,35 @@ class Number$1 extends TextInput {
2934
2943
  this.localValue = parsed;
2935
2944
  }
2936
2945
  }
2946
+ /**
2947
+ * initializes a mask proxy to call update when the mask is changed
2948
+ */
2949
+ initializeMaskProxy() {
2950
+ this.internalMask = new Proxy(Object.assign({}, this.mask), {
2951
+ set: (target, prop, newValue) => {
2952
+ target[prop] = newValue;
2953
+ setTimeout(() => {
2954
+ var _a;
2955
+ (_a = this.autoNumericObj) === null || _a === void 0 ? void 0 : _a.update(this.mask);
2956
+ });
2957
+ return true;
2958
+ },
2959
+ });
2960
+ }
2961
+ get mask() {
2962
+ return this.internalMask;
2963
+ }
2964
+ set mask(value) {
2965
+ this.internalMask = value;
2966
+ if (typeof value !== 'object')
2967
+ return;
2968
+ // when the mask is replaced, should reinitialize the mask Proxy
2969
+ setTimeout(() => {
2970
+ var _a;
2971
+ this.initializeMaskProxy();
2972
+ (_a = this.autoNumericObj) === null || _a === void 0 ? void 0 : _a.update(this.mask);
2973
+ });
2974
+ }
2937
2975
  /**
2938
2976
  * Retrieves a formatted value with mask
2939
2977
  * @param value Any value
@@ -5587,6 +5625,18 @@ class Column extends Component {
5587
5625
  super.onBeforeDestroy();
5588
5626
  (_a = this.lookupDatasource) === null || _a === void 0 ? void 0 : _a.destroy();
5589
5627
  }
5628
+ /**
5629
+ * Retrieves a row from lookup using its key
5630
+ * @returns the row object when found, null when it is not found or empty
5631
+ */
5632
+ getLookupRow(value) {
5633
+ const row = this.lookupData[value];
5634
+ if (!row)
5635
+ return null;
5636
+ if (Object.keys(row).length === 0)
5637
+ return null;
5638
+ return row;
5639
+ }
5590
5640
  }
5591
5641
 
5592
5642
  /**
@@ -5886,98 +5936,6 @@ class GridColumn extends Column {
5886
5936
  }
5887
5937
  }
5888
5938
  }
5889
- FormatterParserProvider.registerFormatter('column_ZdSelect', ({ column, value, row, componentProps, }) => {
5890
- if (value === null || value === undefined)
5891
- return '';
5892
- const { dataText, formatterDataText, dataTextSeparator, dataValue, dataTextDiscrete, foreignColumns, } = componentProps;
5893
- let currentRow = row;
5894
- const dataTextColumns = Array.isArray(dataText) ? dataText : [dataText];
5895
- if (dataValue) {
5896
- const columns = Array.isArray(formatterDataText) ? formatterDataText : [formatterDataText];
5897
- if (foreignColumns) {
5898
- const loopkupRow = {};
5899
- dataTextColumns.forEach((item) => {
5900
- const dataTextName = typeof item === 'string' ? item : item.name;
5901
- loopkupRow[dataTextName] = currentRow[foreignColumns[dataTextName] || dataTextName];
5902
- });
5903
- loopkupRow[dataValue] = currentRow[column.name];
5904
- column.lookupData[currentRow[column.name]] = loopkupRow;
5905
- }
5906
- else if (!formatterDataText) {
5907
- currentRow = column.getLookupData(dataValue, value[dataValue] || value);
5908
- }
5909
- else if (columns.length === dataTextColumns.length) {
5910
- const loopkupRow = {};
5911
- columns.forEach((item, index) => {
5912
- const dataTextValue = dataTextColumns[index];
5913
- const dataTextName = typeof dataTextValue === 'string' ? dataTextValue : dataTextValue.name;
5914
- loopkupRow[dataTextName] = currentRow[typeof item === 'string' ? item : item.name];
5915
- });
5916
- loopkupRow[dataValue] = currentRow[column.name];
5917
- column.lookupData[currentRow[column.name]] = loopkupRow;
5918
- }
5919
- }
5920
- if (!Object.keys(currentRow).length)
5921
- return typeof value === 'object' ? '' : value;
5922
- let dataTextForeign = dataText;
5923
- if (dataText && foreignColumns) {
5924
- if (typeof dataText === 'string') {
5925
- dataTextForeign = foreignColumns[dataText] || dataText;
5926
- }
5927
- else {
5928
- dataTextForeign = dataTextColumns.map((item) => {
5929
- const itemName = typeof item === 'string' ? item : item.name;
5930
- return foreignColumns[itemName] || itemName;
5931
- });
5932
- }
5933
- }
5934
- const textColumn = dataTextDiscrete || formatterDataText || dataTextForeign;
5935
- if (!textColumn)
5936
- return value;
5937
- if (typeof textColumn === 'string') {
5938
- return currentRow[textColumn] || value;
5939
- }
5940
- const formatterFn = FormatterParserProvider.getFormatter('ZdSelect');
5941
- return formatterFn(currentRow, { dataText: textColumn, dataTextSeparator });
5942
- });
5943
- FormatterParserProvider.registerFormatter('column_ZdSelectMultiple', ({ column, value, row, componentProps, }) => {
5944
- if (!value || !Array.isArray(value) || value.length === 0)
5945
- return '';
5946
- const { formatterDataText, foreignColumns, dataText } = componentProps;
5947
- const formatterFn = FormatterParserProvider.getFormatter('column_ZdSelect');
5948
- const result = value.map((item, index) => {
5949
- let formatterRow = Object.assign({}, row);
5950
- const rowOverride = {};
5951
- if (formatterDataText && formatterDataText.length > 0) {
5952
- const columns = Array.isArray(formatterDataText) ? formatterDataText : [formatterDataText];
5953
- columns.forEach((col) => {
5954
- const textName = typeof col === 'string' ? col : col.name;
5955
- rowOverride[textName] = row[textName][index];
5956
- });
5957
- formatterRow = Object.assign(Object.assign({}, row), rowOverride);
5958
- }
5959
- else if (foreignColumns && dataText) {
5960
- let dataTextForeign = dataText;
5961
- if (typeof dataText === 'string') {
5962
- dataTextForeign = [foreignColumns[dataText] || dataText];
5963
- }
5964
- else {
5965
- dataTextForeign = dataText.map((col) => {
5966
- const colName = typeof col === 'string' ? col : col.name;
5967
- return foreignColumns[colName] || colName;
5968
- });
5969
- }
5970
- dataTextForeign.forEach((col) => {
5971
- rowOverride[col] = row[col][index];
5972
- });
5973
- formatterRow = Object.assign(Object.assign({}, row), rowOverride);
5974
- }
5975
- return formatterFn({
5976
- column, value: item, row: formatterRow, componentProps,
5977
- });
5978
- });
5979
- return result.join(', ');
5980
- });
5981
5939
  const toggleableFormatter = ({ value, componentProps }) => {
5982
5940
  const { trueValue, falseValue, trueIcon, falseIcon, trueDisplayValue, falseDisplayValue, } = componentProps;
5983
5941
  const trueDefined = isUndefined(trueValue) ? true : trueValue;
@@ -7117,23 +7075,23 @@ class GridEditable extends Grid {
7117
7075
  if (Array.isArray(colValue)) {
7118
7076
  colValue.forEach((item) => {
7119
7077
  const value = typeof item === 'object' ? item[componentProps.dataValue] : item;
7120
- if (column.lookupData[value]) {
7121
- componentProps.datasource.data.push(column.lookupData[value]);
7122
- }
7078
+ this.pushLookupRow(column, componentProps, value);
7123
7079
  });
7124
7080
  return;
7125
7081
  }
7126
7082
  if (colValue && typeof colValue === 'object'
7127
7083
  && Object.prototype.hasOwnProperty.call(colValue, componentProps.dataValue)) {
7128
7084
  const value = colValue[componentProps.dataValue];
7129
- if (column.lookupData[value]) {
7130
- componentProps.datasource.data.push(column.lookupData[value]);
7131
- }
7085
+ this.pushLookupRow(column, componentProps, value);
7132
7086
  return;
7133
7087
  }
7134
- if (column.lookupData[colValue]) {
7135
- componentProps.datasource.data.push(column.lookupData[colValue]);
7136
- }
7088
+ this.pushLookupRow(column, componentProps, colValue);
7089
+ }
7090
+ pushLookupRow(column, componentProps, value) {
7091
+ const lookupRow = column.getLookupRow(value);
7092
+ if (!lookupRow)
7093
+ return;
7094
+ componentProps.datasource.data.push(lookupRow);
7137
7095
  }
7138
7096
  checkCompValidity(component) {
7139
7097
  if (!component.isValid()) {
@@ -12437,6 +12395,7 @@ class SelectMultiple extends Select {
12437
12395
  this.limit = null;
12438
12396
  this.showSelectAll = false;
12439
12397
  this.showCheckboxAll = false;
12398
+ this.formatterFn = FormatterParserProvider.getFormatter('ZdSelectMultiple');
12440
12399
  this.checkboxAllValue = false;
12441
12400
  if (!this.selectedValue) {
12442
12401
  this.selectedValue = [];
@@ -12653,22 +12612,6 @@ class SelectMultiple extends Select {
12653
12612
  });
12654
12613
  this.insertsRemoved = [];
12655
12614
  }
12656
- /**
12657
- * Return formatted dataText and values
12658
- */
12659
- formatter(value) {
12660
- if (!value || value.length === 0) {
12661
- return [];
12662
- }
12663
- const selectFormatter = FormatterParserProvider.getFormatter('ZdSelect');
12664
- const formattedValue = value.map((row) => {
12665
- const isDisabled = this.dataDisabled && row[this.dataDisabled];
12666
- const formattedRow = { value: row[this.dataValue], disabled: isDisabled, originalRow: row };
12667
- formattedRow.text = selectFormatter(row, this);
12668
- return formattedRow;
12669
- });
12670
- return formattedValue;
12671
- }
12672
12615
  /**
12673
12616
  * Returns the text shown when there's one or more selected items that doesn't fit in the input
12674
12617
  */
@@ -12914,7 +12857,21 @@ class SelectMultiple extends Select {
12914
12857
  };
12915
12858
  return modalSelectionDef;
12916
12859
  }
12917
- }
12860
+ }
12861
+ FormatterParserProvider.registerFormatter('ZdSelectMultiple', (value, props) => {
12862
+ const { dataDisabled, dataValue } = props;
12863
+ if (!value || value.length === 0) {
12864
+ return [];
12865
+ }
12866
+ const selectFormatter = FormatterParserProvider.getFormatter('ZdSelect');
12867
+ const formattedValue = value.map((row) => {
12868
+ const isDisabled = dataDisabled && row[dataDisabled];
12869
+ const formattedRow = { value: row[dataValue], disabled: isDisabled, originalRow: row };
12870
+ formattedRow.text = selectFormatter(row, props);
12871
+ return formattedRow;
12872
+ });
12873
+ return formattedValue;
12874
+ });
12918
12875
 
12919
12876
  /**
12920
12877
  * Base class for Select Tree component.
@@ -13005,7 +12962,6 @@ class SelectTree extends TextInput {
13005
12962
  * Defines if should wait and not execute GET method when Datasource is created
13006
12963
  */
13007
12964
  this.lazyLoad = true;
13008
- this.selectValue = null;
13009
12965
  /**
13010
12966
  * Uses delayed loading to load tree branches
13011
12967
  */
@@ -13026,7 +12982,9 @@ class SelectTree extends TextInput {
13026
12982
  * Defines the name of the form target to set using dataValueOut
13027
12983
  */
13028
12984
  this.dataValueOutFormName = '';
12985
+ this.formatterFn = FormatterParserProvider.getFormatter('ZdSelectTree');
13029
12986
  this.savedNodes = undefined;
12987
+ this.search = '';
13030
12988
  this.debounceSearch = debounce(this.searchChange, 500);
13031
12989
  this.nodes = this.getInitValue('nodes', props.nodes, this.nodes);
13032
12990
  this.alwaysOpen = this.getInitValue('alwaysOpen', props.alwaysOpen, this.alwaysOpen);
@@ -13046,7 +13004,6 @@ class SelectTree extends TextInput {
13046
13004
  this.dataValue = this.getInitValue('dataValue', props.dataValue, this.dataValue);
13047
13005
  this.dataDisabled = this.getInitValue('dataDisabled', props.dataDisabled, this.dataDisabled);
13048
13006
  this.disabledItems = this.getInitValue('disabledItems', props.disabledItems, this.disabledItems);
13049
- this.preventLoadOnFocus = this.getInitValue('preventLoadOnFocus', props.preventLoadOnFocus, this.preventLoadOnFocus);
13050
13007
  this.fetchOnDemand = this.getInitValue('fetchOnDemand', props.fetchOnDemand, this.fetchOnDemand);
13051
13008
  this.fieldHasChild = this.getInitValue('fieldHasChild', props.fieldHasChild, this.fieldHasChild);
13052
13009
  this.menuMaxWidth = this.getInitValue('menuMaxWidth', props.menuMaxWidth, this.menuMaxWidth);
@@ -13064,8 +13021,21 @@ class SelectTree extends TextInput {
13064
13021
  this.datasource = DatasourceFactory.factory(Object.assign(Object.assign({}, props.datasource), { searchIn: props.datasource.searchIn || searchFieldNames, lazyLoad: true, loadAll: true }));
13065
13022
  this.createDataStructure();
13066
13023
  }
13024
+ if (this.dataTextDiscrete && !Array.isArray(this.dataTextDiscrete))
13025
+ this.dataTextDiscrete = [this.dataTextDiscrete];
13026
+ this.discreteProps = {
13027
+ dataText: this.dataTextDiscrete,
13028
+ dataTextSeparator: this.dataTextSeparator,
13029
+ };
13030
+ this.preventLoadOnFocus = !this.datasource || !this.lazyLoad;
13031
+ this.preventLoadOnFocus = this.getInitValue('preventLoadOnFocus', props.preventLoadOnFocus, this.preventLoadOnFocus);
13032
+ this.value = this.getInitValue('value', props.value, this.value);
13067
13033
  this.createAccessors();
13068
13034
  }
13035
+ /**
13036
+ * Returns the currentRow in the dataText key
13037
+ */
13038
+ formatter(value, props) { return this.formatterFn(value, props !== null && props !== void 0 ? props : this); }
13069
13039
  focus(event, element) {
13070
13040
  const _super = Object.create(null, {
13071
13041
  focus: { get: () => super.focus }
@@ -13120,8 +13090,8 @@ class SelectTree extends TextInput {
13120
13090
  children = undefined;
13121
13091
  }
13122
13092
  }
13123
- const dataText = this.formatRow(this.dataText, row);
13124
- const dataTextDiscrete = this.formatRow(this.dataTextDiscrete, row);
13093
+ const dataText = this.formatter(row);
13094
+ const dataTextDiscrete = this.formatter(row, this.discreteProps);
13125
13095
  return {
13126
13096
  id: row[this.dataValue],
13127
13097
  label: dataText,
@@ -13141,40 +13111,6 @@ class SelectTree extends TextInput {
13141
13111
  });
13142
13112
  return newNodes;
13143
13113
  }
13144
- formatRow(dataText, row) {
13145
- const dataTextArr = Array.isArray(dataText) ? dataText : [dataText];
13146
- const dataTextNames = [];
13147
- const masks = [];
13148
- dataTextArr.forEach((text) => {
13149
- if (typeof text === 'string') {
13150
- dataTextNames.push(text);
13151
- masks.push('');
13152
- }
13153
- else {
13154
- dataTextNames.push(text.name);
13155
- if (Accessor.isAccessorDefinition(text.mask)) {
13156
- const [controller, accessor] = Accessor.getAccessor(text.mask);
13157
- masks.push(Loader.getInstance(controller)[accessor]);
13158
- }
13159
- else {
13160
- masks.push(text.mask);
13161
- }
13162
- }
13163
- });
13164
- const rowText = dataTextNames.reduce((result, column, index) => {
13165
- if (row[column]) {
13166
- const separator = index > 0 ? this.dataTextSeparator : '';
13167
- let masked = row[column];
13168
- if (masks[index]) {
13169
- const maskValue = typeof masks[index] === 'function' ? masks[index](row[column]) : masks[index];
13170
- masked = Mask.getValueWithMask(row[column], maskValue);
13171
- }
13172
- return result + separator + masked;
13173
- }
13174
- return result;
13175
- }, '');
13176
- return rowText;
13177
- }
13178
13114
  /**
13179
13115
  * Triggered when the menu opens
13180
13116
  */
@@ -13198,6 +13134,7 @@ class SelectTree extends TextInput {
13198
13134
  * Triggered after the search query changes
13199
13135
  */
13200
13136
  searchChange(searchQuery, element) {
13137
+ this.search = searchQuery;
13201
13138
  if (this.fetchOnDemand) {
13202
13139
  if (!searchQuery && this.savedNodes) {
13203
13140
  this.nodes = this.savedNodes;
@@ -13285,7 +13222,7 @@ class SelectTree extends TextInput {
13285
13222
  if (!this.selectValue)
13286
13223
  return this.selectValue;
13287
13224
  if (this.returnObject) {
13288
- return this.clearRow(this.selectValue.row);
13225
+ return this.clearRow(this.selectValue.row || this.selectValue);
13289
13226
  }
13290
13227
  return this.selectValue;
13291
13228
  }
@@ -13332,6 +13269,8 @@ class SelectTree extends TextInput {
13332
13269
  }
13333
13270
  }
13334
13271
  }
13272
+ const selectFormatterFn$1 = FormatterParserProvider.getFormatter('ZdSelect');
13273
+ FormatterParserProvider.registerFormatter('ZdSelectTree', selectFormatterFn$1);
13335
13274
  InputFactory.register('ZdSelectTree', SelectTree);
13336
13275
 
13337
13276
  /**
@@ -13356,7 +13295,6 @@ class SelectTreeMultiple extends SelectTree {
13356
13295
  * Selected Nodes
13357
13296
  */
13358
13297
  this.selectedNodes = [];
13359
- this.selectValue = [];
13360
13298
  /**
13361
13299
  * Changes the behavior of checked nodes that will be displayed in the array of values
13362
13300
  */
@@ -13384,19 +13322,25 @@ class SelectTreeMultiple extends SelectTree {
13384
13322
  this.callEvent('onDeselect', { element, component: this, node });
13385
13323
  }
13386
13324
  get value() {
13325
+ if (!this.selectValue)
13326
+ return [];
13387
13327
  if (this.returnObject) {
13388
- return this.selectValue.map((value) => this.clearRow(value.row));
13328
+ return this.selectValue.map((value) => this.clearRow(value.row || value));
13389
13329
  }
13390
13330
  return this.selectValue;
13391
13331
  }
13392
13332
  set value(value) {
13393
- this.selectValue = value;
13333
+ this.setValue(value);
13394
13334
  }
13395
13335
  setValue(value) {
13336
+ if (!value) {
13337
+ this.selectValue = [];
13338
+ return;
13339
+ }
13396
13340
  const arrValue = Array.isArray(value) ? value : [value];
13397
13341
  const key = this.datasource ? this.dataValue : 'id';
13398
13342
  if (!this.returnObject) {
13399
- this.value = arrValue.map((item) => {
13343
+ this.selectValue = arrValue.map((item) => {
13400
13344
  if (typeof item === 'object') {
13401
13345
  return item[key];
13402
13346
  }
@@ -13404,19 +13348,27 @@ class SelectTreeMultiple extends SelectTree {
13404
13348
  });
13405
13349
  return;
13406
13350
  }
13407
- this.value = arrValue.map((item) => {
13351
+ this.selectValue = arrValue.map((item) => {
13408
13352
  if (typeof item !== 'object') {
13409
13353
  return { id: item };
13410
13354
  }
13411
13355
  return { id: item[key] };
13412
13356
  });
13413
13357
  }
13414
- getAllNodes(nodes = this.nodes) {
13415
- let result = nodes;
13358
+ /**
13359
+ * Retrieves all nodes in the tree as a flat array. Nodes that are not matched are excluded
13360
+ * Nodes that are not matched but whose parent is matched are included
13361
+ * @param nodes
13362
+ * @param matched defines whether the parent of the current node branch is matched
13363
+ * @returns all nodes in the tree as a flat array, filtering unmatched nodes
13364
+ */
13365
+ getAllNodes(nodes = this.nodes, matched = true) {
13366
+ let result = [...nodes];
13367
+ result = result.filter((node) => node.isMatched || matched);
13416
13368
  nodes.forEach((node) => {
13417
13369
  if (!node.children)
13418
13370
  return;
13419
- const childNodes = this.getAllNodes(node.children);
13371
+ const childNodes = this.getAllNodes(node.children, node.isMatched || matched);
13420
13372
  result = [...result, ...childNodes];
13421
13373
  });
13422
13374
  return result;
@@ -13424,28 +13376,96 @@ class SelectTreeMultiple extends SelectTree {
13424
13376
  /**
13425
13377
  * Dispatches select/unselect event
13426
13378
  */
13427
- onSelectAll(isSelected, event, element) {
13379
+ onSelectAll(isSelected, event, element, nodes = this.nodes) {
13428
13380
  if (isSelected) {
13429
13381
  this.callEvent('selectedAll', { event, element, component: this });
13430
13382
  if (!event.defaultPrevented) {
13431
- this.selectAllItems();
13383
+ this.selectAllItems(nodes);
13432
13384
  }
13433
13385
  }
13434
13386
  else {
13435
13387
  this.callEvent('unselectedAll', { event, element, component: this });
13436
13388
  if (!event.defaultPrevented) {
13437
- this.unSelectAllItems();
13389
+ this.unSelectAllItems(nodes);
13438
13390
  }
13439
13391
  }
13440
13392
  }
13441
- selectAllItems() {
13442
- const allNodes = this.datasource ? this.datasource.data : this.getAllNodes();
13443
- this.setValue(allNodes);
13393
+ /**
13394
+ * Selects all items in the tree \
13395
+ * If the component is fetchOnDemand, it will select all values from datasource.data \
13396
+ * If not, it will select all nodes from the tree, unless the nodes to be selected are specified
13397
+ * @param nodes nodes to be selected. These are the nodes that are currently visible in the tree
13398
+ * (if the user is searching, selects only the searched nodes)
13399
+ * @returns
13400
+ */
13401
+ selectAllItems(nodes = this.nodes) {
13402
+ var _a;
13403
+ if (((_a = this.datasource) === null || _a === void 0 ? void 0 : _a.data) && this.fetchOnDemand) {
13404
+ this.setValue(this.datasource.data);
13405
+ return;
13406
+ }
13407
+ const allNodes = this.getAllNodes(nodes, !this.search);
13408
+ // merge all nodes with the current value before setting it
13409
+ const currentValue = this.getValueAsObject();
13410
+ const nodeMap = this.createMergeMap(currentValue, allNodes);
13411
+ const uniqueArray = Array.from(nodeMap.values());
13412
+ this.setValue(uniqueArray);
13444
13413
  }
13445
- unSelectAllItems() {
13446
- this.setValue([]);
13414
+ /**
13415
+ * Unelects all items in the tree \
13416
+ * If the component is fetchOnDemand, it will select all values from datasource.data \
13417
+ * If not, it will select all nodes from the tree, unless the nodes to be selected are specified
13418
+ * @param nodes nodes to be selected. These are the nodes that are currently visible in the tree
13419
+ * (if the user is searching, selects only the searched nodes)
13420
+ * @returns
13421
+ */
13422
+ unSelectAllItems(nodes = this.nodes) {
13423
+ var _a;
13424
+ if (((_a = this.datasource) === null || _a === void 0 ? void 0 : _a.data) && this.fetchOnDemand) {
13425
+ this.setValue([]);
13426
+ return;
13427
+ }
13428
+ const allNodes = this.getAllNodes(nodes, !this.search);
13429
+ // merge all nodes with the current value before setting it
13430
+ const currentValue = this.getValueAsObject();
13431
+ const nodeMap = this.createMergeMap(currentValue);
13432
+ // remove the current visible nodes from the array
13433
+ const valuesToRemove = allNodes.map((node) => node.id);
13434
+ valuesToRemove.forEach((value) => {
13435
+ nodeMap.delete(value);
13436
+ });
13437
+ const uniqueArray = Array.from(nodeMap.values());
13438
+ this.setValue(uniqueArray);
13447
13439
  }
13448
- }
13440
+ /**
13441
+ * Takes two arrays and creates a map of the unique values
13442
+ * @returns map of a merge between the two arrays, removing duplicates
13443
+ */
13444
+ createMergeMap(arr1, arr2 = []) {
13445
+ const mergedNodes = arr1.concat(arr2);
13446
+ // filter out duplicate nodes
13447
+ const uniqueMap = new Map();
13448
+ mergedNodes.forEach((node) => {
13449
+ uniqueMap.set(node.id, node);
13450
+ });
13451
+ return uniqueMap;
13452
+ }
13453
+ getValueIds() {
13454
+ if (this.returnObject) {
13455
+ return this.value.map((item) => item.id);
13456
+ }
13457
+ return this.value;
13458
+ }
13459
+ getValueAsObject() {
13460
+ return this.value.map((row) => {
13461
+ if (this.returnObject)
13462
+ return row;
13463
+ return { id: row };
13464
+ });
13465
+ }
13466
+ }
13467
+ const selectFormatterFn = FormatterParserProvider.getFormatter('ZdSelectMultiple');
13468
+ FormatterParserProvider.registerFormatter('ZdSelectTreeMultiple', selectFormatterFn);
13449
13469
 
13450
13470
  /**
13451
13471
  * Base class for SelectableList component.
@@ -15822,6 +15842,131 @@ class TreeGridEditable extends TreeGrid {
15822
15842
  }
15823
15843
  }
15824
15844
 
15845
+ const asArray = (value) => (Array.isArray(value) ? value : [value]);
15846
+ const getForeignLookupRow = (column, row, dataValue, dataTextColumns, foreignColumns) => {
15847
+ const lookupRow = {};
15848
+ dataTextColumns.forEach((item) => {
15849
+ const dataTextName = typeof item === 'string' ? item : item.name;
15850
+ lookupRow[dataTextName] = row[foreignColumns[dataTextName] || dataTextName];
15851
+ });
15852
+ lookupRow[dataValue] = row[column.name];
15853
+ return lookupRow;
15854
+ };
15855
+ const getFormatterLookupRow = (column, row, dataValue, formatterDataTextColumns, dataTextColumns) => {
15856
+ const lookupRow = {};
15857
+ formatterDataTextColumns.forEach((item, index) => {
15858
+ const dataTextValue = dataTextColumns[index];
15859
+ const dataTextName = typeof dataTextValue === 'string' ? dataTextValue : dataTextValue.name;
15860
+ const formatterDataTextColumn = typeof item === 'string' ? item : item.name;
15861
+ lookupRow[dataTextName] = row[formatterDataTextColumn];
15862
+ });
15863
+ lookupRow[dataValue] = row[column.name];
15864
+ return lookupRow;
15865
+ };
15866
+ /**
15867
+ * Stores data in column.lookupData when using foreignColumns or formatterDataText.
15868
+ * Makes a lookup when not using foreignColumns or formatterDataText
15869
+ * @returns the row from grid's datasource when using foreignColumns or formatterDataText. Otherwise,
15870
+ * returns the row from the column's component datasource
15871
+ */
15872
+ const storeOrRetrieveLookup = (column, row, value, dataValue, componentProps) => {
15873
+ const { dataText, foreignColumns, formatterDataText, } = componentProps;
15874
+ const dataTextColumns = asArray(dataText);
15875
+ // when using foreignColumns, should store foreign keys information in lookupData
15876
+ if (foreignColumns) {
15877
+ column.lookupData[row[column.name]] = getForeignLookupRow(column, row, dataValue, dataTextColumns, foreignColumns);
15878
+ return row;
15879
+ }
15880
+ // when not using formatterDataText, should fetch data from datasource to be able to format this cell
15881
+ if (!formatterDataText) {
15882
+ return column.getLookupData(dataValue, value[dataValue] || value);
15883
+ }
15884
+ const formatterDataTextColumns = asArray(formatterDataText);
15885
+ // when using formatterDataText, should store dataText information in lookupData
15886
+ if (formatterDataTextColumns.length === dataTextColumns.length) {
15887
+ const rowColumn = row[column.name];
15888
+ column.lookupData[rowColumn] = getFormatterLookupRow(column, row, dataValue, formatterDataTextColumns, dataTextColumns);
15889
+ return row;
15890
+ }
15891
+ return row;
15892
+ };
15893
+ const formatter$1 = ({ column, value, row, componentProps, }) => {
15894
+ if (value === null || value === undefined)
15895
+ return '';
15896
+ const { dataText, formatterDataText, dataTextSeparator, dataValue, dataTextDiscrete, foreignColumns, } = componentProps;
15897
+ let currentRow = row;
15898
+ const dataTextColumns = asArray(dataText);
15899
+ // when dataValue is defined, should try to store or retrieve row data from lookupData
15900
+ if (dataValue) {
15901
+ currentRow = storeOrRetrieveLookup(column, row, value, dataValue, componentProps);
15902
+ }
15903
+ if (!Object.keys(currentRow).length)
15904
+ return typeof value === 'object' ? '' : value;
15905
+ let dataTextForeign = dataText;
15906
+ if (dataText && foreignColumns) {
15907
+ if (typeof dataText === 'string') {
15908
+ dataTextForeign = foreignColumns[dataText] || dataText;
15909
+ }
15910
+ else {
15911
+ dataTextForeign = dataTextColumns.map((item) => {
15912
+ const itemName = typeof item === 'string' ? item : item.name;
15913
+ return foreignColumns[itemName] || itemName;
15914
+ });
15915
+ }
15916
+ }
15917
+ const textColumn = dataTextDiscrete || formatterDataText || dataTextForeign;
15918
+ if (!textColumn)
15919
+ return value;
15920
+ if (typeof textColumn === 'string') {
15921
+ return currentRow[textColumn] || value;
15922
+ }
15923
+ const formatterFn = FormatterParserProvider.getFormatter('ZdSelect');
15924
+ return formatterFn(currentRow, { dataText: textColumn, dataTextSeparator });
15925
+ };
15926
+ FormatterParserProvider.registerFormatter('column_ZdSelect', formatter$1);
15927
+ FormatterParserProvider.registerFormatter('column_ZdSelectTree', formatter$1);
15928
+
15929
+ const formatter = ({ column, value, row, componentProps, }) => {
15930
+ if (!value || !Array.isArray(value) || value.length === 0)
15931
+ return '';
15932
+ const { formatterDataText, foreignColumns, dataText } = componentProps;
15933
+ const formatterFn = FormatterParserProvider.getFormatter('column_ZdSelect');
15934
+ const result = value.map((item, index) => {
15935
+ let formatterRow = Object.assign({}, row);
15936
+ const rowOverride = {};
15937
+ if (formatterDataText && formatterDataText.length > 0) {
15938
+ const columns = Array.isArray(formatterDataText) ? formatterDataText : [formatterDataText];
15939
+ columns.forEach((col) => {
15940
+ const textName = typeof col === 'string' ? col : col.name;
15941
+ rowOverride[textName] = row[textName][index];
15942
+ });
15943
+ formatterRow = Object.assign(Object.assign({}, row), rowOverride);
15944
+ }
15945
+ else if (foreignColumns && dataText) {
15946
+ let dataTextForeign = dataText;
15947
+ if (typeof dataText === 'string') {
15948
+ dataTextForeign = [foreignColumns[dataText] || dataText];
15949
+ }
15950
+ else {
15951
+ dataTextForeign = dataText.map((col) => {
15952
+ const colName = typeof col === 'string' ? col : col.name;
15953
+ return foreignColumns[colName] || colName;
15954
+ });
15955
+ }
15956
+ dataTextForeign.forEach((col) => {
15957
+ rowOverride[col] = row[col][index];
15958
+ });
15959
+ formatterRow = Object.assign(Object.assign({}, row), rowOverride);
15960
+ }
15961
+ return formatterFn({
15962
+ column, value: item, row: formatterRow, componentProps,
15963
+ });
15964
+ });
15965
+ return result.join(', ');
15966
+ };
15967
+ FormatterParserProvider.registerFormatter('column_ZdSelectMultiple', formatter);
15968
+ FormatterParserProvider.registerFormatter('column_ZdSelectTreeMultiple', formatter);
15969
+
15825
15970
  const AutoNumeric = require('@zeedhi/autonumeric/dist/autoNumeric');
15826
15971
  const packageContent = require('../package.json');
15827
15972
  VersionService.addPackageVersion(packageContent.name, packageContent.version);