@zeedhi/common 1.109.0 → 1.110.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.
@@ -5632,6 +5632,18 @@
5632
5632
  super.onBeforeDestroy();
5633
5633
  (_a = this.lookupDatasource) === null || _a === void 0 ? void 0 : _a.destroy();
5634
5634
  }
5635
+ /**
5636
+ * Retrieves a row from lookup using its key
5637
+ * @returns the row object when found, null when it is not found or empty
5638
+ */
5639
+ getLookupRow(value) {
5640
+ const row = this.lookupData[value];
5641
+ if (!row)
5642
+ return null;
5643
+ if (Object.keys(row).length === 0)
5644
+ return null;
5645
+ return row;
5646
+ }
5635
5647
  }
5636
5648
 
5637
5649
  /**
@@ -5931,98 +5943,6 @@
5931
5943
  }
5932
5944
  }
5933
5945
  }
5934
- core.FormatterParserProvider.registerFormatter('column_ZdSelect', ({ column, value, row, componentProps, }) => {
5935
- if (value === null || value === undefined)
5936
- return '';
5937
- const { dataText, formatterDataText, dataTextSeparator, dataValue, dataTextDiscrete, foreignColumns, } = componentProps;
5938
- let currentRow = row;
5939
- const dataTextColumns = Array.isArray(dataText) ? dataText : [dataText];
5940
- if (dataValue) {
5941
- const columns = Array.isArray(formatterDataText) ? formatterDataText : [formatterDataText];
5942
- if (foreignColumns) {
5943
- const loopkupRow = {};
5944
- dataTextColumns.forEach((item) => {
5945
- const dataTextName = typeof item === 'string' ? item : item.name;
5946
- loopkupRow[dataTextName] = currentRow[foreignColumns[dataTextName] || dataTextName];
5947
- });
5948
- loopkupRow[dataValue] = currentRow[column.name];
5949
- column.lookupData[currentRow[column.name]] = loopkupRow;
5950
- }
5951
- else if (!formatterDataText) {
5952
- currentRow = column.getLookupData(dataValue, value[dataValue] || value);
5953
- }
5954
- else if (columns.length === dataTextColumns.length) {
5955
- const loopkupRow = {};
5956
- columns.forEach((item, index) => {
5957
- const dataTextValue = dataTextColumns[index];
5958
- const dataTextName = typeof dataTextValue === 'string' ? dataTextValue : dataTextValue.name;
5959
- loopkupRow[dataTextName] = currentRow[typeof item === 'string' ? item : item.name];
5960
- });
5961
- loopkupRow[dataValue] = currentRow[column.name];
5962
- column.lookupData[currentRow[column.name]] = loopkupRow;
5963
- }
5964
- }
5965
- if (!Object.keys(currentRow).length)
5966
- return typeof value === 'object' ? '' : value;
5967
- let dataTextForeign = dataText;
5968
- if (dataText && foreignColumns) {
5969
- if (typeof dataText === 'string') {
5970
- dataTextForeign = foreignColumns[dataText] || dataText;
5971
- }
5972
- else {
5973
- dataTextForeign = dataTextColumns.map((item) => {
5974
- const itemName = typeof item === 'string' ? item : item.name;
5975
- return foreignColumns[itemName] || itemName;
5976
- });
5977
- }
5978
- }
5979
- const textColumn = dataTextDiscrete || formatterDataText || dataTextForeign;
5980
- if (!textColumn)
5981
- return value;
5982
- if (typeof textColumn === 'string') {
5983
- return currentRow[textColumn] || value;
5984
- }
5985
- const formatterFn = core.FormatterParserProvider.getFormatter('ZdSelect');
5986
- return formatterFn(currentRow, { dataText: textColumn, dataTextSeparator });
5987
- });
5988
- core.FormatterParserProvider.registerFormatter('column_ZdSelectMultiple', ({ column, value, row, componentProps, }) => {
5989
- if (!value || !Array.isArray(value) || value.length === 0)
5990
- return '';
5991
- const { formatterDataText, foreignColumns, dataText } = componentProps;
5992
- const formatterFn = core.FormatterParserProvider.getFormatter('column_ZdSelect');
5993
- const result = value.map((item, index) => {
5994
- let formatterRow = Object.assign({}, row);
5995
- const rowOverride = {};
5996
- if (formatterDataText && formatterDataText.length > 0) {
5997
- const columns = Array.isArray(formatterDataText) ? formatterDataText : [formatterDataText];
5998
- columns.forEach((col) => {
5999
- const textName = typeof col === 'string' ? col : col.name;
6000
- rowOverride[textName] = row[textName][index];
6001
- });
6002
- formatterRow = Object.assign(Object.assign({}, row), rowOverride);
6003
- }
6004
- else if (foreignColumns && dataText) {
6005
- let dataTextForeign = dataText;
6006
- if (typeof dataText === 'string') {
6007
- dataTextForeign = [foreignColumns[dataText] || dataText];
6008
- }
6009
- else {
6010
- dataTextForeign = dataText.map((col) => {
6011
- const colName = typeof col === 'string' ? col : col.name;
6012
- return foreignColumns[colName] || colName;
6013
- });
6014
- }
6015
- dataTextForeign.forEach((col) => {
6016
- rowOverride[col] = row[col][index];
6017
- });
6018
- formatterRow = Object.assign(Object.assign({}, row), rowOverride);
6019
- }
6020
- return formatterFn({
6021
- column, value: item, row: formatterRow, componentProps,
6022
- });
6023
- });
6024
- return result.join(', ');
6025
- });
6026
5946
  const toggleableFormatter = ({ value, componentProps }) => {
6027
5947
  const { trueValue, falseValue, trueIcon, falseIcon, trueDisplayValue, falseDisplayValue, } = componentProps;
6028
5948
  const trueDefined = isUndefined__default["default"](trueValue) ? true : trueValue;
@@ -6908,6 +6828,8 @@
6908
6828
  this.viewEnterEdit = null;
6909
6829
  this.showCancelColumn = false;
6910
6830
  this.newRowIdentifier = '__added_row';
6831
+ this.positionIdentifier = '__position';
6832
+ this.pageIdentifier = '__page';
6911
6833
  this.createGridController();
6912
6834
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
6913
6835
  this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
@@ -6916,6 +6838,7 @@
6916
6838
  this.showCancelColumn = this.getInitValue('showCancelColumn', props.showCancelColumn, this.showCancelColumn);
6917
6839
  this.createAccessors();
6918
6840
  this.addCancelColumn();
6841
+ this.registerDatasourceCallback();
6919
6842
  }
6920
6843
  setViewEnterEdit(viewEnterEdit) {
6921
6844
  this.viewEnterEdit = viewEnterEdit;
@@ -6971,6 +6894,35 @@
6971
6894
  instantiateCancelColumn() {
6972
6895
  return new GridColumnEditable(this.getCancelColumnProps());
6973
6896
  }
6897
+ registerDatasourceCallback() {
6898
+ const callback = () => {
6899
+ const addedRows = Object.keys(this.addedRows).map((key) => this.addedRows[key]);
6900
+ if (addedRows.length === 0)
6901
+ return;
6902
+ let dataWithNewRow = null;
6903
+ const { page } = this.datasource;
6904
+ addedRows.forEach((row) => {
6905
+ const { originalRow } = row;
6906
+ const rowToInsert = originalRow || row;
6907
+ const rowPage = rowToInsert[this.pageIdentifier];
6908
+ const lastPage = this.datasource.getLastPage() || 1;
6909
+ // if the row's page is greater than the last page, should insert the row in the last page
6910
+ // if the row's page is not greater than the last page, should insert the row in the correct page
6911
+ if (rowPage > lastPage) {
6912
+ if (page !== lastPage)
6913
+ return;
6914
+ }
6915
+ else if (rowPage !== page) {
6916
+ return;
6917
+ }
6918
+ dataWithNewRow = this.insertRowInDatasource(rowToInsert, rowToInsert[this.positionIdentifier]);
6919
+ });
6920
+ if (dataWithNewRow) {
6921
+ this.datasource.updatePageData(dataWithNewRow);
6922
+ }
6923
+ };
6924
+ this.datasource.registerGetCallback(callback);
6925
+ }
6974
6926
  createGridController() {
6975
6927
  const controller = new GridEditableController(this);
6976
6928
  core.Loader.addController(`GridEditableController_${this.name}`, controller);
@@ -7162,23 +7114,23 @@
7162
7114
  if (Array.isArray(colValue)) {
7163
7115
  colValue.forEach((item) => {
7164
7116
  const value = typeof item === 'object' ? item[componentProps.dataValue] : item;
7165
- if (column.lookupData[value]) {
7166
- componentProps.datasource.data.push(column.lookupData[value]);
7167
- }
7117
+ this.pushLookupRow(column, componentProps, value);
7168
7118
  });
7169
7119
  return;
7170
7120
  }
7171
7121
  if (colValue && typeof colValue === 'object'
7172
7122
  && Object.prototype.hasOwnProperty.call(colValue, componentProps.dataValue)) {
7173
7123
  const value = colValue[componentProps.dataValue];
7174
- if (column.lookupData[value]) {
7175
- componentProps.datasource.data.push(column.lookupData[value]);
7176
- }
7124
+ this.pushLookupRow(column, componentProps, value);
7177
7125
  return;
7178
7126
  }
7179
- if (column.lookupData[colValue]) {
7180
- componentProps.datasource.data.push(column.lookupData[colValue]);
7181
- }
7127
+ this.pushLookupRow(column, componentProps, colValue);
7128
+ }
7129
+ pushLookupRow(column, componentProps, value) {
7130
+ const lookupRow = column.getLookupRow(value);
7131
+ if (!lookupRow)
7132
+ return;
7133
+ componentProps.datasource.data.push(lookupRow);
7182
7134
  }
7183
7135
  checkCompValidity(component) {
7184
7136
  if (!component.isValid()) {
@@ -7283,6 +7235,7 @@
7283
7235
  return __awaiter(this, void 0, void 0, function* () {
7284
7236
  const { page } = this.datasource;
7285
7237
  yield this.cancelAddedRows();
7238
+ this.addedRows = {};
7286
7239
  yield this.datasource.setPage(page);
7287
7240
  this.editing = false;
7288
7241
  this.editedRows = {};
@@ -7300,14 +7253,10 @@
7300
7253
  delete cloneAddedRows[key];
7301
7254
  this.editedRows = cloneEditedRows;
7302
7255
  this.addedRows = cloneAddedRows;
7303
- let { data } = this.datasource;
7304
- if (this.datasource instanceof core.MemoryDatasource) {
7305
- data = this.datasource.allData;
7306
- }
7307
- const { uniqueKey } = this.datasource;
7256
+ const { data, uniqueKey } = this.datasource;
7308
7257
  const index = data.findIndex((row) => row[uniqueKey] === key);
7309
7258
  data.splice(index, 1);
7310
- return this.datasource.updateData(data);
7259
+ return this.datasource.updatePageData(data);
7311
7260
  });
7312
7261
  }
7313
7262
  cancelAddedRows() {
@@ -7320,7 +7269,7 @@
7320
7269
  allData.splice(index, 1);
7321
7270
  }
7322
7271
  }
7323
- yield this.datasource.updateData(allData);
7272
+ yield this.datasource.updatePageData(allData);
7324
7273
  });
7325
7274
  }
7326
7275
  addDataRow(row) {
@@ -7359,6 +7308,8 @@
7359
7308
  const row = Object.assign(Object.assign({}, this.editedRows[key].originalRow), this.editedRows[key]);
7360
7309
  delete row.originalRow;
7361
7310
  delete row[this.newRowIdentifier];
7311
+ delete row[this.positionIdentifier];
7312
+ delete row[this.pageIdentifier];
7362
7313
  Object.keys(row).forEach((attr) => {
7363
7314
  if (Object.prototype.hasOwnProperty.call(row, `${attr}_original`)) {
7364
7315
  delete row[`${attr}_original`];
@@ -7380,6 +7331,8 @@
7380
7331
  const row = Object.assign(Object.assign({}, this.addedRows[key].originalRow), this.addedRows[key]);
7381
7332
  delete row.originalRow;
7382
7333
  delete row[this.newRowIdentifier];
7334
+ delete row[this.positionIdentifier];
7335
+ delete row[this.pageIdentifier];
7383
7336
  Object.keys(row).forEach((attr) => {
7384
7337
  if (Object.prototype.hasOwnProperty.call(row, `${attr}_original`)) {
7385
7338
  delete row[`${attr}_original`];
@@ -7450,10 +7403,14 @@
7450
7403
  return __awaiter(this, void 0, void 0, function* () {
7451
7404
  const data = this.insertRowInDatasource(row, position);
7452
7405
  this.saveRowReference(row);
7453
- yield this.datasource.updateData(data);
7406
+ yield this.datasource.updatePageData(data);
7454
7407
  this.editing = true;
7455
7408
  });
7456
7409
  }
7410
+ /**
7411
+ * Saves a row reference in editedRows and addedRows
7412
+ * @param row Row to be saved
7413
+ */
7457
7414
  saveRowReference(row) {
7458
7415
  const id = row[this.datasource.uniqueKey];
7459
7416
  if (id) {
@@ -7461,15 +7418,18 @@
7461
7418
  this.addedRows = Object.assign(Object.assign({}, this.addedRows), { [id]: Object.assign({}, row) });
7462
7419
  }
7463
7420
  }
7421
+ /**
7422
+ * Inserts a row in datasource depending on the position
7423
+ * @param row Row to be inserted
7424
+ * @param position Position, 'end' or 'start'
7425
+ * @returns the data containing the newly added row
7426
+ */
7464
7427
  insertRowInDatasource(row, position) {
7465
- let data;
7466
- if (this.datasource instanceof core.MemoryDatasource) {
7467
- data = this.datasource.allData;
7468
- }
7469
- else {
7470
- data = this.datasource.data;
7471
- }
7428
+ const { data } = this.datasource;
7472
7429
  row[this.newRowIdentifier] = true;
7430
+ row[this.positionIdentifier] = position;
7431
+ if (!row[this.pageIdentifier])
7432
+ row[this.pageIdentifier] = this.datasource.page;
7473
7433
  if (position === 'start') {
7474
7434
  data.unshift(row);
7475
7435
  }
@@ -8480,16 +8440,11 @@
8480
8440
  WatchURL.watchers = {};
8481
8441
  WatchURL.originalEvents = new Map();
8482
8442
 
8483
- class BaseReport {
8484
- constructor() {
8485
- this.expressionZeedhiToXls = {
8486
- AVG: 'AVERAGE',
8487
- COUNT: 'COUNTA',
8488
- MAX: 'MAX',
8489
- MIN: 'MIN',
8490
- SUM: 'SUM',
8491
- };
8492
- this.colunmXLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
8443
+ class ReportColumnTransformer {
8444
+ constructor({ getFormatFn, labelFormatter, fileType }) {
8445
+ this.getFormatFn = getFormatFn;
8446
+ this.labelFormatter = labelFormatter;
8447
+ this.fileType = fileType;
8493
8448
  }
8494
8449
  getColumnsWidth(columns) {
8495
8450
  const widths = {};
@@ -8507,7 +8462,7 @@
8507
8462
  }
8508
8463
  return { widths, totalWidth };
8509
8464
  }
8510
- buildColumns(columns) {
8465
+ transform(columns) {
8511
8466
  const { widths, totalWidth } = this.getColumnsWidth(columns);
8512
8467
  return columns.reduce((result, col, index) => {
8513
8468
  let size;
@@ -8517,18 +8472,36 @@
8517
8472
  else {
8518
8473
  size = Math.floor((widths[col.name] * 100) / totalWidth);
8519
8474
  }
8475
+ const description = this.labelFormatter ? this.labelFormatter({ column: col, fileType: this.fileType }) : col.label;
8476
+ const format = this.getFormatFn ? this.getFormatFn(col) : undefined;
8520
8477
  const row = {
8478
+ format,
8479
+ description,
8521
8480
  align: col.align || 'left',
8522
- description: col.label,
8523
8481
  sequence: index,
8524
8482
  size: `${size}%`,
8483
+ xlsType: col.xlsType,
8525
8484
  };
8526
- if (col.xlsType) {
8527
- row.xlsType = col.xlsType;
8528
- }
8529
8485
  return Object.assign(Object.assign({}, result), { [col.name]: row });
8530
8486
  }, {});
8531
8487
  }
8488
+ }
8489
+
8490
+ class BaseReport {
8491
+ constructor(labelFormatter) {
8492
+ this.expressionZeedhiToXls = {
8493
+ AVG: 'AVERAGE',
8494
+ COUNT: 'COUNTA',
8495
+ MAX: 'MAX',
8496
+ MIN: 'MIN',
8497
+ SUM: 'SUM',
8498
+ };
8499
+ this.colunmXLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
8500
+ this.reportColumnTransformer = this.getReportColumnTransformer(labelFormatter);
8501
+ }
8502
+ getReportColumnTransformer(labelFormatter) {
8503
+ return new ReportColumnTransformer({ labelFormatter, fileType: this.getFileType() });
8504
+ }
8532
8505
  buildFilter(filter, columns) {
8533
8506
  return Object.keys(filter).map((key) => {
8534
8507
  var _a;
@@ -8551,6 +8524,9 @@
8551
8524
  super(...arguments);
8552
8525
  this.route = '/generateCSV';
8553
8526
  }
8527
+ getFileType() {
8528
+ return 'csv';
8529
+ }
8554
8530
  buildDataset(data, columns) {
8555
8531
  const columnNames = columns.map((col) => col.name);
8556
8532
  const result = data.reduce((reduced, row) => {
@@ -8560,7 +8536,7 @@
8560
8536
  return JSON.stringify(result);
8561
8537
  }
8562
8538
  buildMetadata(name, title, columns, filter) {
8563
- const builtCols = this.buildColumns(columns);
8539
+ const builtCols = this.reportColumnTransformer.transform(columns);
8564
8540
  const builtFilters = this.buildFilter(filter || {}, columns);
8565
8541
  const lang = this.formatLangCode(core.I18n.instance.language);
8566
8542
  const clientLogo = '';
@@ -8596,30 +8572,17 @@
8596
8572
  super(...arguments);
8597
8573
  this.route = '/generateReport';
8598
8574
  }
8575
+ getFileType() {
8576
+ return 'pdf';
8577
+ }
8578
+ getReportColumnTransformer(labelFormatter) {
8579
+ const getFormatFn = this.getFormatOfColumn.bind(this);
8580
+ const fileType = this.getFileType();
8581
+ return new ReportColumnTransformer({ getFormatFn, labelFormatter, fileType });
8582
+ }
8599
8583
  buildDataset(data) {
8600
8584
  return JSON.stringify(data);
8601
8585
  }
8602
- buildColumns(columns) {
8603
- const { widths, totalWidth } = this.getColumnsWidth(columns);
8604
- return columns.reduce((result, col, index) => {
8605
- let size;
8606
- if (!totalWidth) {
8607
- size = Math.floor(100 / columns.length);
8608
- }
8609
- else {
8610
- size = Math.floor((widths[col.name] * 100) / totalWidth);
8611
- }
8612
- const row = {
8613
- align: col.align || 'left',
8614
- description: col.label,
8615
- sequence: index,
8616
- format: this.getFormatOfColumn(col),
8617
- size: `${size}%`,
8618
- xlsType: col.xlsType,
8619
- };
8620
- return Object.assign(Object.assign({}, result), { [col.name]: row });
8621
- }, {});
8622
- }
8623
8586
  getFormatOfColumn(column) {
8624
8587
  let format;
8625
8588
  let { mask } = column;
@@ -8667,7 +8630,7 @@
8667
8630
  }
8668
8631
  buildMetadata(name, title, columns, filter, portrait = true) {
8669
8632
  return __awaiter(this, void 0, void 0, function* () {
8670
- const builtCols = this.buildColumns(columns);
8633
+ const builtCols = this.reportColumnTransformer.transform(columns);
8671
8634
  const builtFilters = this.buildFilter(filter || {}, columns);
8672
8635
  const lang = this.formatLangCode(core.I18n.instance.language);
8673
8636
  let clientLogo = '';
@@ -8752,6 +8715,9 @@
8752
8715
  super(...arguments);
8753
8716
  this.route = '/generateXLS';
8754
8717
  }
8718
+ getFileType() {
8719
+ return 'xls';
8720
+ }
8755
8721
  buildDataset(data, columns) {
8756
8722
  const result = this.formatRawDataSet(data, columns);
8757
8723
  return JSON.stringify(result);
@@ -8766,7 +8732,7 @@
8766
8732
  return result;
8767
8733
  }
8768
8734
  buildMetadata(name, title, columns, filter) {
8769
- const builtCols = this.buildColumns(columns);
8735
+ const builtCols = this.reportColumnTransformer.transform(columns);
8770
8736
  const builtFilters = this.buildFilter(filter || {}, columns);
8771
8737
  const lang = this.formatLangCode(core.I18n.instance.language);
8772
8738
  const clientLogo = '';
@@ -8806,12 +8772,15 @@
8806
8772
  super(...arguments);
8807
8773
  this.route = '/generateXLS';
8808
8774
  }
8775
+ getFileType() {
8776
+ return 'xls';
8777
+ }
8809
8778
  buildDataset(data, metadata) {
8810
8779
  const result = this.formatDataSet(metadata, data);
8811
8780
  return JSON.stringify(result);
8812
8781
  }
8813
8782
  buildMetadata(name, title, columns, filter) {
8814
- const builtCols = this.buildColumns(columns);
8783
+ const builtCols = this.reportColumnTransformer.transform(columns);
8815
8784
  const builtFilters = this.buildFilter(filter || {}, columns);
8816
8785
  const lang = this.formatLangCode(core.I18n.instance.language);
8817
8786
  const clientLogo = '';
@@ -9003,12 +8972,15 @@
9003
8972
  super(...arguments);
9004
8973
  this.route = '/generateXLS';
9005
8974
  }
8975
+ getFileType() {
8976
+ return 'xls';
8977
+ }
9006
8978
  buildDataset(data, metadata) {
9007
8979
  const result = this.formatDataSet(metadata, data);
9008
8980
  return JSON.stringify(result);
9009
8981
  }
9010
8982
  buildMetadata(name, title, columns, filter) {
9011
- const builtCols = this.buildColumns(columns);
8983
+ const builtCols = this.reportColumnTransformer.transform(columns);
9012
8984
  const builtFilters = this.buildFilter(filter || {}, columns);
9013
8985
  const lang = this.formatLangCode(core.I18n.instance.language);
9014
8986
  const clientLogo = '';
@@ -9295,25 +9267,25 @@
9295
9267
  return formattedData;
9296
9268
  });
9297
9269
  }
9298
- getReportType(type) {
9270
+ getReportType(type, labelFormatter) {
9299
9271
  if (type === 'csv') {
9300
- return new CSVReport();
9272
+ return new CSVReport(labelFormatter);
9301
9273
  }
9302
9274
  if (type === 'pdf') {
9303
- return new PDFReport();
9275
+ return new PDFReport(labelFormatter);
9304
9276
  }
9305
9277
  if (type === 'xls') {
9306
- return new XLSReport();
9278
+ return new XLSReport(labelFormatter);
9307
9279
  }
9308
9280
  if (type === 'xls2') {
9309
- return new XLS2Report();
9281
+ return new XLS2Report(labelFormatter);
9310
9282
  }
9311
9283
  if (type === 'xls3') {
9312
- return new XLS3Report();
9284
+ return new XLS3Report(labelFormatter);
9313
9285
  }
9314
9286
  throw new Error(`Invalid report type: ${type}`);
9315
9287
  }
9316
- getReport(type, portrait = true, rowObj, beforeReportEvent) {
9288
+ getReport(type, portrait = true, rowObj, beforeReportEvent, labelFormatter) {
9317
9289
  var _a;
9318
9290
  return __awaiter(this, void 0, void 0, function* () {
9319
9291
  const data = (_a = this.data) !== null && _a !== void 0 ? _a : yield this.getData();
@@ -9324,7 +9296,7 @@
9324
9296
  containerLabel: this.title,
9325
9297
  widgetLabel: this.title,
9326
9298
  };
9327
- const reportType = this.getReportType(type);
9299
+ const reportType = this.getReportType(type, labelFormatter);
9328
9300
  const { route } = reportType;
9329
9301
  const { name, columns, datasource } = this.iterable;
9330
9302
  const { groupedData } = Object.assign({}, this.iterable);
@@ -12482,6 +12454,7 @@
12482
12454
  this.limit = null;
12483
12455
  this.showSelectAll = false;
12484
12456
  this.showCheckboxAll = false;
12457
+ this.formatterFn = core.FormatterParserProvider.getFormatter('ZdSelectMultiple');
12485
12458
  this.checkboxAllValue = false;
12486
12459
  if (!this.selectedValue) {
12487
12460
  this.selectedValue = [];
@@ -12698,22 +12671,6 @@
12698
12671
  });
12699
12672
  this.insertsRemoved = [];
12700
12673
  }
12701
- /**
12702
- * Return formatted dataText and values
12703
- */
12704
- formatter(value) {
12705
- if (!value || value.length === 0) {
12706
- return [];
12707
- }
12708
- const selectFormatter = core.FormatterParserProvider.getFormatter('ZdSelect');
12709
- const formattedValue = value.map((row) => {
12710
- const isDisabled = this.dataDisabled && row[this.dataDisabled];
12711
- const formattedRow = { value: row[this.dataValue], disabled: isDisabled, originalRow: row };
12712
- formattedRow.text = selectFormatter(row, this);
12713
- return formattedRow;
12714
- });
12715
- return formattedValue;
12716
- }
12717
12674
  /**
12718
12675
  * Returns the text shown when there's one or more selected items that doesn't fit in the input
12719
12676
  */
@@ -12959,7 +12916,21 @@
12959
12916
  };
12960
12917
  return modalSelectionDef;
12961
12918
  }
12962
- }
12919
+ }
12920
+ core.FormatterParserProvider.registerFormatter('ZdSelectMultiple', (value, props) => {
12921
+ const { dataDisabled, dataValue } = props;
12922
+ if (!value || value.length === 0) {
12923
+ return [];
12924
+ }
12925
+ const selectFormatter = core.FormatterParserProvider.getFormatter('ZdSelect');
12926
+ const formattedValue = value.map((row) => {
12927
+ const isDisabled = dataDisabled && row[dataDisabled];
12928
+ const formattedRow = { value: row[dataValue], disabled: isDisabled, originalRow: row };
12929
+ formattedRow.text = selectFormatter(row, props);
12930
+ return formattedRow;
12931
+ });
12932
+ return formattedValue;
12933
+ });
12963
12934
 
12964
12935
  /**
12965
12936
  * Base class for Select Tree component.
@@ -13050,7 +13021,6 @@
13050
13021
  * Defines if should wait and not execute GET method when Datasource is created
13051
13022
  */
13052
13023
  this.lazyLoad = true;
13053
- this.selectValue = null;
13054
13024
  /**
13055
13025
  * Uses delayed loading to load tree branches
13056
13026
  */
@@ -13071,7 +13041,9 @@
13071
13041
  * Defines the name of the form target to set using dataValueOut
13072
13042
  */
13073
13043
  this.dataValueOutFormName = '';
13044
+ this.formatterFn = core.FormatterParserProvider.getFormatter('ZdSelectTree');
13074
13045
  this.savedNodes = undefined;
13046
+ this.search = '';
13075
13047
  this.debounceSearch = debounce__default["default"](this.searchChange, 500);
13076
13048
  this.nodes = this.getInitValue('nodes', props.nodes, this.nodes);
13077
13049
  this.alwaysOpen = this.getInitValue('alwaysOpen', props.alwaysOpen, this.alwaysOpen);
@@ -13091,7 +13063,6 @@
13091
13063
  this.dataValue = this.getInitValue('dataValue', props.dataValue, this.dataValue);
13092
13064
  this.dataDisabled = this.getInitValue('dataDisabled', props.dataDisabled, this.dataDisabled);
13093
13065
  this.disabledItems = this.getInitValue('disabledItems', props.disabledItems, this.disabledItems);
13094
- this.preventLoadOnFocus = this.getInitValue('preventLoadOnFocus', props.preventLoadOnFocus, this.preventLoadOnFocus);
13095
13066
  this.fetchOnDemand = this.getInitValue('fetchOnDemand', props.fetchOnDemand, this.fetchOnDemand);
13096
13067
  this.fieldHasChild = this.getInitValue('fieldHasChild', props.fieldHasChild, this.fieldHasChild);
13097
13068
  this.menuMaxWidth = this.getInitValue('menuMaxWidth', props.menuMaxWidth, this.menuMaxWidth);
@@ -13109,8 +13080,21 @@
13109
13080
  this.datasource = core.DatasourceFactory.factory(Object.assign(Object.assign({}, props.datasource), { searchIn: props.datasource.searchIn || searchFieldNames, lazyLoad: true, loadAll: true }));
13110
13081
  this.createDataStructure();
13111
13082
  }
13083
+ if (this.dataTextDiscrete && !Array.isArray(this.dataTextDiscrete))
13084
+ this.dataTextDiscrete = [this.dataTextDiscrete];
13085
+ this.discreteProps = {
13086
+ dataText: this.dataTextDiscrete,
13087
+ dataTextSeparator: this.dataTextSeparator,
13088
+ };
13089
+ this.preventLoadOnFocus = !this.datasource || !this.lazyLoad;
13090
+ this.preventLoadOnFocus = this.getInitValue('preventLoadOnFocus', props.preventLoadOnFocus, this.preventLoadOnFocus);
13091
+ this.value = this.getInitValue('value', props.value, this.value);
13112
13092
  this.createAccessors();
13113
13093
  }
13094
+ /**
13095
+ * Returns the currentRow in the dataText key
13096
+ */
13097
+ formatter(value, props) { return this.formatterFn(value, props !== null && props !== void 0 ? props : this); }
13114
13098
  focus(event, element) {
13115
13099
  const _super = Object.create(null, {
13116
13100
  focus: { get: () => super.focus }
@@ -13165,8 +13149,8 @@
13165
13149
  children = undefined;
13166
13150
  }
13167
13151
  }
13168
- const dataText = this.formatRow(this.dataText, row);
13169
- const dataTextDiscrete = this.formatRow(this.dataTextDiscrete, row);
13152
+ const dataText = this.formatter(row);
13153
+ const dataTextDiscrete = this.formatter(row, this.discreteProps);
13170
13154
  return {
13171
13155
  id: row[this.dataValue],
13172
13156
  label: dataText,
@@ -13186,40 +13170,6 @@
13186
13170
  });
13187
13171
  return newNodes;
13188
13172
  }
13189
- formatRow(dataText, row) {
13190
- const dataTextArr = Array.isArray(dataText) ? dataText : [dataText];
13191
- const dataTextNames = [];
13192
- const masks = [];
13193
- dataTextArr.forEach((text) => {
13194
- if (typeof text === 'string') {
13195
- dataTextNames.push(text);
13196
- masks.push('');
13197
- }
13198
- else {
13199
- dataTextNames.push(text.name);
13200
- if (core.Accessor.isAccessorDefinition(text.mask)) {
13201
- const [controller, accessor] = core.Accessor.getAccessor(text.mask);
13202
- masks.push(core.Loader.getInstance(controller)[accessor]);
13203
- }
13204
- else {
13205
- masks.push(text.mask);
13206
- }
13207
- }
13208
- });
13209
- const rowText = dataTextNames.reduce((result, column, index) => {
13210
- if (row[column]) {
13211
- const separator = index > 0 ? this.dataTextSeparator : '';
13212
- let masked = row[column];
13213
- if (masks[index]) {
13214
- const maskValue = typeof masks[index] === 'function' ? masks[index](row[column]) : masks[index];
13215
- masked = core.Mask.getValueWithMask(row[column], maskValue);
13216
- }
13217
- return result + separator + masked;
13218
- }
13219
- return result;
13220
- }, '');
13221
- return rowText;
13222
- }
13223
13173
  /**
13224
13174
  * Triggered when the menu opens
13225
13175
  */
@@ -13243,6 +13193,7 @@
13243
13193
  * Triggered after the search query changes
13244
13194
  */
13245
13195
  searchChange(searchQuery, element) {
13196
+ this.search = searchQuery;
13246
13197
  if (this.fetchOnDemand) {
13247
13198
  if (!searchQuery && this.savedNodes) {
13248
13199
  this.nodes = this.savedNodes;
@@ -13330,7 +13281,7 @@
13330
13281
  if (!this.selectValue)
13331
13282
  return this.selectValue;
13332
13283
  if (this.returnObject) {
13333
- return this.clearRow(this.selectValue.row);
13284
+ return this.clearRow(this.selectValue.row || this.selectValue);
13334
13285
  }
13335
13286
  return this.selectValue;
13336
13287
  }
@@ -13377,6 +13328,8 @@
13377
13328
  }
13378
13329
  }
13379
13330
  }
13331
+ const selectFormatterFn$1 = core.FormatterParserProvider.getFormatter('ZdSelect');
13332
+ core.FormatterParserProvider.registerFormatter('ZdSelectTree', selectFormatterFn$1);
13380
13333
  InputFactory.register('ZdSelectTree', SelectTree);
13381
13334
 
13382
13335
  /**
@@ -13401,7 +13354,6 @@
13401
13354
  * Selected Nodes
13402
13355
  */
13403
13356
  this.selectedNodes = [];
13404
- this.selectValue = [];
13405
13357
  /**
13406
13358
  * Changes the behavior of checked nodes that will be displayed in the array of values
13407
13359
  */
@@ -13429,19 +13381,25 @@
13429
13381
  this.callEvent('onDeselect', { element, component: this, node });
13430
13382
  }
13431
13383
  get value() {
13384
+ if (!this.selectValue)
13385
+ return [];
13432
13386
  if (this.returnObject) {
13433
- return this.selectValue.map((value) => this.clearRow(value.row));
13387
+ return this.selectValue.map((value) => this.clearRow(value.row || value));
13434
13388
  }
13435
13389
  return this.selectValue;
13436
13390
  }
13437
13391
  set value(value) {
13438
- this.selectValue = value;
13392
+ this.setValue(value);
13439
13393
  }
13440
13394
  setValue(value) {
13395
+ if (!value) {
13396
+ this.selectValue = [];
13397
+ return;
13398
+ }
13441
13399
  const arrValue = Array.isArray(value) ? value : [value];
13442
13400
  const key = this.datasource ? this.dataValue : 'id';
13443
13401
  if (!this.returnObject) {
13444
- this.value = arrValue.map((item) => {
13402
+ this.selectValue = arrValue.map((item) => {
13445
13403
  if (typeof item === 'object') {
13446
13404
  return item[key];
13447
13405
  }
@@ -13449,19 +13407,27 @@
13449
13407
  });
13450
13408
  return;
13451
13409
  }
13452
- this.value = arrValue.map((item) => {
13410
+ this.selectValue = arrValue.map((item) => {
13453
13411
  if (typeof item !== 'object') {
13454
13412
  return { id: item };
13455
13413
  }
13456
13414
  return { id: item[key] };
13457
13415
  });
13458
13416
  }
13459
- getAllNodes(nodes = this.nodes) {
13460
- let result = nodes;
13417
+ /**
13418
+ * Retrieves all nodes in the tree as a flat array. Nodes that are not matched are excluded
13419
+ * Nodes that are not matched but whose parent is matched are included
13420
+ * @param nodes
13421
+ * @param matched defines whether the parent of the current node branch is matched
13422
+ * @returns all nodes in the tree as a flat array, filtering unmatched nodes
13423
+ */
13424
+ getAllNodes(nodes = this.nodes, matched = true) {
13425
+ let result = [...nodes];
13426
+ result = result.filter((node) => node.isMatched || matched);
13461
13427
  nodes.forEach((node) => {
13462
13428
  if (!node.children)
13463
13429
  return;
13464
- const childNodes = this.getAllNodes(node.children);
13430
+ const childNodes = this.getAllNodes(node.children, node.isMatched || matched);
13465
13431
  result = [...result, ...childNodes];
13466
13432
  });
13467
13433
  return result;
@@ -13469,28 +13435,96 @@
13469
13435
  /**
13470
13436
  * Dispatches select/unselect event
13471
13437
  */
13472
- onSelectAll(isSelected, event, element) {
13438
+ onSelectAll(isSelected, event, element, nodes = this.nodes) {
13473
13439
  if (isSelected) {
13474
13440
  this.callEvent('selectedAll', { event, element, component: this });
13475
13441
  if (!event.defaultPrevented) {
13476
- this.selectAllItems();
13442
+ this.selectAllItems(nodes);
13477
13443
  }
13478
13444
  }
13479
13445
  else {
13480
13446
  this.callEvent('unselectedAll', { event, element, component: this });
13481
13447
  if (!event.defaultPrevented) {
13482
- this.unSelectAllItems();
13448
+ this.unSelectAllItems(nodes);
13483
13449
  }
13484
13450
  }
13485
13451
  }
13486
- selectAllItems() {
13487
- const allNodes = this.datasource ? this.datasource.data : this.getAllNodes();
13488
- this.setValue(allNodes);
13452
+ /**
13453
+ * Selects all items in the tree \
13454
+ * If the component is fetchOnDemand, it will select all values from datasource.data \
13455
+ * If not, it will select all nodes from the tree, unless the nodes to be selected are specified
13456
+ * @param nodes nodes to be selected. These are the nodes that are currently visible in the tree
13457
+ * (if the user is searching, selects only the searched nodes)
13458
+ * @returns
13459
+ */
13460
+ selectAllItems(nodes = this.nodes) {
13461
+ var _a;
13462
+ if (((_a = this.datasource) === null || _a === void 0 ? void 0 : _a.data) && this.fetchOnDemand) {
13463
+ this.setValue(this.datasource.data);
13464
+ return;
13465
+ }
13466
+ const allNodes = this.getAllNodes(nodes, !this.search);
13467
+ // merge all nodes with the current value before setting it
13468
+ const currentValue = this.getValueAsObject();
13469
+ const nodeMap = this.createMergeMap(currentValue, allNodes);
13470
+ const uniqueArray = Array.from(nodeMap.values());
13471
+ this.setValue(uniqueArray);
13489
13472
  }
13490
- unSelectAllItems() {
13491
- this.setValue([]);
13473
+ /**
13474
+ * Unelects all items in the tree \
13475
+ * If the component is fetchOnDemand, it will select all values from datasource.data \
13476
+ * If not, it will select all nodes from the tree, unless the nodes to be selected are specified
13477
+ * @param nodes nodes to be selected. These are the nodes that are currently visible in the tree
13478
+ * (if the user is searching, selects only the searched nodes)
13479
+ * @returns
13480
+ */
13481
+ unSelectAllItems(nodes = this.nodes) {
13482
+ var _a;
13483
+ if (((_a = this.datasource) === null || _a === void 0 ? void 0 : _a.data) && this.fetchOnDemand) {
13484
+ this.setValue([]);
13485
+ return;
13486
+ }
13487
+ const allNodes = this.getAllNodes(nodes, !this.search);
13488
+ // merge all nodes with the current value before setting it
13489
+ const currentValue = this.getValueAsObject();
13490
+ const nodeMap = this.createMergeMap(currentValue);
13491
+ // remove the current visible nodes from the array
13492
+ const valuesToRemove = allNodes.map((node) => node.id);
13493
+ valuesToRemove.forEach((value) => {
13494
+ nodeMap.delete(value);
13495
+ });
13496
+ const uniqueArray = Array.from(nodeMap.values());
13497
+ this.setValue(uniqueArray);
13492
13498
  }
13493
- }
13499
+ /**
13500
+ * Takes two arrays and creates a map of the unique values
13501
+ * @returns map of a merge between the two arrays, removing duplicates
13502
+ */
13503
+ createMergeMap(arr1, arr2 = []) {
13504
+ const mergedNodes = arr1.concat(arr2);
13505
+ // filter out duplicate nodes
13506
+ const uniqueMap = new Map();
13507
+ mergedNodes.forEach((node) => {
13508
+ uniqueMap.set(node.id, node);
13509
+ });
13510
+ return uniqueMap;
13511
+ }
13512
+ getValueIds() {
13513
+ if (this.returnObject) {
13514
+ return this.value.map((item) => item.id);
13515
+ }
13516
+ return this.value;
13517
+ }
13518
+ getValueAsObject() {
13519
+ return this.value.map((row) => {
13520
+ if (this.returnObject)
13521
+ return row;
13522
+ return { id: row };
13523
+ });
13524
+ }
13525
+ }
13526
+ const selectFormatterFn = core.FormatterParserProvider.getFormatter('ZdSelectMultiple');
13527
+ core.FormatterParserProvider.registerFormatter('ZdSelectTreeMultiple', selectFormatterFn);
13494
13528
 
13495
13529
  /**
13496
13530
  * Base class for SelectableList component.
@@ -15867,6 +15901,131 @@
15867
15901
  }
15868
15902
  }
15869
15903
 
15904
+ const asArray = (value) => (Array.isArray(value) ? value : [value]);
15905
+ const getForeignLookupRow = (column, row, dataValue, dataTextColumns, foreignColumns) => {
15906
+ const lookupRow = {};
15907
+ dataTextColumns.forEach((item) => {
15908
+ const dataTextName = typeof item === 'string' ? item : item.name;
15909
+ lookupRow[dataTextName] = row[foreignColumns[dataTextName] || dataTextName];
15910
+ });
15911
+ lookupRow[dataValue] = row[column.name];
15912
+ return lookupRow;
15913
+ };
15914
+ const getFormatterLookupRow = (column, row, dataValue, formatterDataTextColumns, dataTextColumns) => {
15915
+ const lookupRow = {};
15916
+ formatterDataTextColumns.forEach((item, index) => {
15917
+ const dataTextValue = dataTextColumns[index];
15918
+ const dataTextName = typeof dataTextValue === 'string' ? dataTextValue : dataTextValue.name;
15919
+ const formatterDataTextColumn = typeof item === 'string' ? item : item.name;
15920
+ lookupRow[dataTextName] = row[formatterDataTextColumn];
15921
+ });
15922
+ lookupRow[dataValue] = row[column.name];
15923
+ return lookupRow;
15924
+ };
15925
+ /**
15926
+ * Stores data in column.lookupData when using foreignColumns or formatterDataText.
15927
+ * Makes a lookup when not using foreignColumns or formatterDataText
15928
+ * @returns the row from grid's datasource when using foreignColumns or formatterDataText. Otherwise,
15929
+ * returns the row from the column's component datasource
15930
+ */
15931
+ const storeOrRetrieveLookup = (column, row, value, dataValue, componentProps) => {
15932
+ const { dataText, foreignColumns, formatterDataText, } = componentProps;
15933
+ const dataTextColumns = asArray(dataText);
15934
+ // when using foreignColumns, should store foreign keys information in lookupData
15935
+ if (foreignColumns) {
15936
+ column.lookupData[row[column.name]] = getForeignLookupRow(column, row, dataValue, dataTextColumns, foreignColumns);
15937
+ return row;
15938
+ }
15939
+ // when not using formatterDataText, should fetch data from datasource to be able to format this cell
15940
+ if (!formatterDataText) {
15941
+ return column.getLookupData(dataValue, value[dataValue] || value);
15942
+ }
15943
+ const formatterDataTextColumns = asArray(formatterDataText);
15944
+ // when using formatterDataText, should store dataText information in lookupData
15945
+ if (formatterDataTextColumns.length === dataTextColumns.length) {
15946
+ const rowColumn = row[column.name];
15947
+ column.lookupData[rowColumn] = getFormatterLookupRow(column, row, dataValue, formatterDataTextColumns, dataTextColumns);
15948
+ return row;
15949
+ }
15950
+ return row;
15951
+ };
15952
+ const formatter$1 = ({ column, value, row, componentProps, }) => {
15953
+ if (value === null || value === undefined)
15954
+ return '';
15955
+ const { dataText, formatterDataText, dataTextSeparator, dataValue, dataTextDiscrete, foreignColumns, } = componentProps;
15956
+ let currentRow = row;
15957
+ const dataTextColumns = asArray(dataText);
15958
+ // when dataValue is defined, should try to store or retrieve row data from lookupData
15959
+ if (dataValue) {
15960
+ currentRow = storeOrRetrieveLookup(column, row, value, dataValue, componentProps);
15961
+ }
15962
+ if (!Object.keys(currentRow).length)
15963
+ return typeof value === 'object' ? '' : value;
15964
+ let dataTextForeign = dataText;
15965
+ if (dataText && foreignColumns) {
15966
+ if (typeof dataText === 'string') {
15967
+ dataTextForeign = foreignColumns[dataText] || dataText;
15968
+ }
15969
+ else {
15970
+ dataTextForeign = dataTextColumns.map((item) => {
15971
+ const itemName = typeof item === 'string' ? item : item.name;
15972
+ return foreignColumns[itemName] || itemName;
15973
+ });
15974
+ }
15975
+ }
15976
+ const textColumn = dataTextDiscrete || formatterDataText || dataTextForeign;
15977
+ if (!textColumn)
15978
+ return value;
15979
+ if (typeof textColumn === 'string') {
15980
+ return currentRow[textColumn] || value;
15981
+ }
15982
+ const formatterFn = core.FormatterParserProvider.getFormatter('ZdSelect');
15983
+ return formatterFn(currentRow, { dataText: textColumn, dataTextSeparator });
15984
+ };
15985
+ core.FormatterParserProvider.registerFormatter('column_ZdSelect', formatter$1);
15986
+ core.FormatterParserProvider.registerFormatter('column_ZdSelectTree', formatter$1);
15987
+
15988
+ const formatter = ({ column, value, row, componentProps, }) => {
15989
+ if (!value || !Array.isArray(value) || value.length === 0)
15990
+ return '';
15991
+ const { formatterDataText, foreignColumns, dataText } = componentProps;
15992
+ const formatterFn = core.FormatterParserProvider.getFormatter('column_ZdSelect');
15993
+ const result = value.map((item, index) => {
15994
+ let formatterRow = Object.assign({}, row);
15995
+ const rowOverride = {};
15996
+ if (formatterDataText && formatterDataText.length > 0) {
15997
+ const columns = Array.isArray(formatterDataText) ? formatterDataText : [formatterDataText];
15998
+ columns.forEach((col) => {
15999
+ const textName = typeof col === 'string' ? col : col.name;
16000
+ rowOverride[textName] = row[textName][index];
16001
+ });
16002
+ formatterRow = Object.assign(Object.assign({}, row), rowOverride);
16003
+ }
16004
+ else if (foreignColumns && dataText) {
16005
+ let dataTextForeign = dataText;
16006
+ if (typeof dataText === 'string') {
16007
+ dataTextForeign = [foreignColumns[dataText] || dataText];
16008
+ }
16009
+ else {
16010
+ dataTextForeign = dataText.map((col) => {
16011
+ const colName = typeof col === 'string' ? col : col.name;
16012
+ return foreignColumns[colName] || colName;
16013
+ });
16014
+ }
16015
+ dataTextForeign.forEach((col) => {
16016
+ rowOverride[col] = row[col][index];
16017
+ });
16018
+ formatterRow = Object.assign(Object.assign({}, row), rowOverride);
16019
+ }
16020
+ return formatterFn({
16021
+ column, value: item, row: formatterRow, componentProps,
16022
+ });
16023
+ });
16024
+ return result.join(', ');
16025
+ };
16026
+ core.FormatterParserProvider.registerFormatter('column_ZdSelectMultiple', formatter);
16027
+ core.FormatterParserProvider.registerFormatter('column_ZdSelectTreeMultiple', formatter);
16028
+
15870
16029
  const AutoNumeric = require('@zeedhi/autonumeric/dist/autoNumeric');
15871
16030
  const packageContent = require('../package.json');
15872
16031
  core.VersionService.addPackageVersion(packageContent.name, packageContent.version);