@zeedhi/common 1.109.1 → 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.
@@ -1,4 +1,4 @@
1
- import { AccessorManager, Event, KeyMap, MethodNotAssignedError, Metadata, Accessor, I18n, FormatterParserProvider, Validation, Mask, DatasourceFactory, Loader, Config, dayjs, Utils, DateHelper, Router, Messages, InstanceNotFoundError, ViewService, MemoryDatasource, URL as URL$1, Http, Cookie, VersionService } from '@zeedhi/core';
1
+ import { AccessorManager, Event, KeyMap, MethodNotAssignedError, Metadata, Accessor, I18n, FormatterParserProvider, Validation, Mask, DatasourceFactory, Loader, Config, dayjs, Utils, DateHelper, Router, Messages, InstanceNotFoundError, ViewService, URL as URL$1, Http, Cookie, VersionService } from '@zeedhi/core';
2
2
  import merge from 'lodash.merge';
3
3
  import cloneDeep from 'lodash.clonedeep';
4
4
  import debounce from 'lodash.debounce';
@@ -6821,6 +6821,8 @@ class GridEditable extends Grid {
6821
6821
  this.viewEnterEdit = null;
6822
6822
  this.showCancelColumn = false;
6823
6823
  this.newRowIdentifier = '__added_row';
6824
+ this.positionIdentifier = '__position';
6825
+ this.pageIdentifier = '__page';
6824
6826
  this.createGridController();
6825
6827
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
6826
6828
  this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
@@ -6829,6 +6831,7 @@ class GridEditable extends Grid {
6829
6831
  this.showCancelColumn = this.getInitValue('showCancelColumn', props.showCancelColumn, this.showCancelColumn);
6830
6832
  this.createAccessors();
6831
6833
  this.addCancelColumn();
6834
+ this.registerDatasourceCallback();
6832
6835
  }
6833
6836
  setViewEnterEdit(viewEnterEdit) {
6834
6837
  this.viewEnterEdit = viewEnterEdit;
@@ -6884,6 +6887,35 @@ class GridEditable extends Grid {
6884
6887
  instantiateCancelColumn() {
6885
6888
  return new GridColumnEditable(this.getCancelColumnProps());
6886
6889
  }
6890
+ registerDatasourceCallback() {
6891
+ const callback = () => {
6892
+ const addedRows = Object.keys(this.addedRows).map((key) => this.addedRows[key]);
6893
+ if (addedRows.length === 0)
6894
+ return;
6895
+ let dataWithNewRow = null;
6896
+ const { page } = this.datasource;
6897
+ addedRows.forEach((row) => {
6898
+ const { originalRow } = row;
6899
+ const rowToInsert = originalRow || row;
6900
+ const rowPage = rowToInsert[this.pageIdentifier];
6901
+ const lastPage = this.datasource.getLastPage() || 1;
6902
+ // if the row's page is greater than the last page, should insert the row in the last page
6903
+ // if the row's page is not greater than the last page, should insert the row in the correct page
6904
+ if (rowPage > lastPage) {
6905
+ if (page !== lastPage)
6906
+ return;
6907
+ }
6908
+ else if (rowPage !== page) {
6909
+ return;
6910
+ }
6911
+ dataWithNewRow = this.insertRowInDatasource(rowToInsert, rowToInsert[this.positionIdentifier]);
6912
+ });
6913
+ if (dataWithNewRow) {
6914
+ this.datasource.updatePageData(dataWithNewRow);
6915
+ }
6916
+ };
6917
+ this.datasource.registerGetCallback(callback);
6918
+ }
6887
6919
  createGridController() {
6888
6920
  const controller = new GridEditableController(this);
6889
6921
  Loader.addController(`GridEditableController_${this.name}`, controller);
@@ -7196,6 +7228,7 @@ class GridEditable extends Grid {
7196
7228
  return __awaiter(this, void 0, void 0, function* () {
7197
7229
  const { page } = this.datasource;
7198
7230
  yield this.cancelAddedRows();
7231
+ this.addedRows = {};
7199
7232
  yield this.datasource.setPage(page);
7200
7233
  this.editing = false;
7201
7234
  this.editedRows = {};
@@ -7213,14 +7246,10 @@ class GridEditable extends Grid {
7213
7246
  delete cloneAddedRows[key];
7214
7247
  this.editedRows = cloneEditedRows;
7215
7248
  this.addedRows = cloneAddedRows;
7216
- let { data } = this.datasource;
7217
- if (this.datasource instanceof MemoryDatasource) {
7218
- data = this.datasource.allData;
7219
- }
7220
- const { uniqueKey } = this.datasource;
7249
+ const { data, uniqueKey } = this.datasource;
7221
7250
  const index = data.findIndex((row) => row[uniqueKey] === key);
7222
7251
  data.splice(index, 1);
7223
- return this.datasource.updateData(data);
7252
+ return this.datasource.updatePageData(data);
7224
7253
  });
7225
7254
  }
7226
7255
  cancelAddedRows() {
@@ -7233,7 +7262,7 @@ class GridEditable extends Grid {
7233
7262
  allData.splice(index, 1);
7234
7263
  }
7235
7264
  }
7236
- yield this.datasource.updateData(allData);
7265
+ yield this.datasource.updatePageData(allData);
7237
7266
  });
7238
7267
  }
7239
7268
  addDataRow(row) {
@@ -7272,6 +7301,8 @@ class GridEditable extends Grid {
7272
7301
  const row = Object.assign(Object.assign({}, this.editedRows[key].originalRow), this.editedRows[key]);
7273
7302
  delete row.originalRow;
7274
7303
  delete row[this.newRowIdentifier];
7304
+ delete row[this.positionIdentifier];
7305
+ delete row[this.pageIdentifier];
7275
7306
  Object.keys(row).forEach((attr) => {
7276
7307
  if (Object.prototype.hasOwnProperty.call(row, `${attr}_original`)) {
7277
7308
  delete row[`${attr}_original`];
@@ -7293,6 +7324,8 @@ class GridEditable extends Grid {
7293
7324
  const row = Object.assign(Object.assign({}, this.addedRows[key].originalRow), this.addedRows[key]);
7294
7325
  delete row.originalRow;
7295
7326
  delete row[this.newRowIdentifier];
7327
+ delete row[this.positionIdentifier];
7328
+ delete row[this.pageIdentifier];
7296
7329
  Object.keys(row).forEach((attr) => {
7297
7330
  if (Object.prototype.hasOwnProperty.call(row, `${attr}_original`)) {
7298
7331
  delete row[`${attr}_original`];
@@ -7363,10 +7396,14 @@ class GridEditable extends Grid {
7363
7396
  return __awaiter(this, void 0, void 0, function* () {
7364
7397
  const data = this.insertRowInDatasource(row, position);
7365
7398
  this.saveRowReference(row);
7366
- yield this.datasource.updateData(data);
7399
+ yield this.datasource.updatePageData(data);
7367
7400
  this.editing = true;
7368
7401
  });
7369
7402
  }
7403
+ /**
7404
+ * Saves a row reference in editedRows and addedRows
7405
+ * @param row Row to be saved
7406
+ */
7370
7407
  saveRowReference(row) {
7371
7408
  const id = row[this.datasource.uniqueKey];
7372
7409
  if (id) {
@@ -7374,15 +7411,18 @@ class GridEditable extends Grid {
7374
7411
  this.addedRows = Object.assign(Object.assign({}, this.addedRows), { [id]: Object.assign({}, row) });
7375
7412
  }
7376
7413
  }
7414
+ /**
7415
+ * Inserts a row in datasource depending on the position
7416
+ * @param row Row to be inserted
7417
+ * @param position Position, 'end' or 'start'
7418
+ * @returns the data containing the newly added row
7419
+ */
7377
7420
  insertRowInDatasource(row, position) {
7378
- let data;
7379
- if (this.datasource instanceof MemoryDatasource) {
7380
- data = this.datasource.allData;
7381
- }
7382
- else {
7383
- data = this.datasource.data;
7384
- }
7421
+ const { data } = this.datasource;
7385
7422
  row[this.newRowIdentifier] = true;
7423
+ row[this.positionIdentifier] = position;
7424
+ if (!row[this.pageIdentifier])
7425
+ row[this.pageIdentifier] = this.datasource.page;
7386
7426
  if (position === 'start') {
7387
7427
  data.unshift(row);
7388
7428
  }
@@ -8393,16 +8433,11 @@ class WatchURL {
8393
8433
  WatchURL.watchers = {};
8394
8434
  WatchURL.originalEvents = new Map();
8395
8435
 
8396
- class BaseReport {
8397
- constructor() {
8398
- this.expressionZeedhiToXls = {
8399
- AVG: 'AVERAGE',
8400
- COUNT: 'COUNTA',
8401
- MAX: 'MAX',
8402
- MIN: 'MIN',
8403
- SUM: 'SUM',
8404
- };
8405
- this.colunmXLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
8436
+ class ReportColumnTransformer {
8437
+ constructor({ getFormatFn, labelFormatter, fileType }) {
8438
+ this.getFormatFn = getFormatFn;
8439
+ this.labelFormatter = labelFormatter;
8440
+ this.fileType = fileType;
8406
8441
  }
8407
8442
  getColumnsWidth(columns) {
8408
8443
  const widths = {};
@@ -8420,7 +8455,7 @@ class BaseReport {
8420
8455
  }
8421
8456
  return { widths, totalWidth };
8422
8457
  }
8423
- buildColumns(columns) {
8458
+ transform(columns) {
8424
8459
  const { widths, totalWidth } = this.getColumnsWidth(columns);
8425
8460
  return columns.reduce((result, col, index) => {
8426
8461
  let size;
@@ -8430,18 +8465,36 @@ class BaseReport {
8430
8465
  else {
8431
8466
  size = Math.floor((widths[col.name] * 100) / totalWidth);
8432
8467
  }
8468
+ const description = this.labelFormatter ? this.labelFormatter({ column: col, fileType: this.fileType }) : col.label;
8469
+ const format = this.getFormatFn ? this.getFormatFn(col) : undefined;
8433
8470
  const row = {
8471
+ format,
8472
+ description,
8434
8473
  align: col.align || 'left',
8435
- description: col.label,
8436
8474
  sequence: index,
8437
8475
  size: `${size}%`,
8476
+ xlsType: col.xlsType,
8438
8477
  };
8439
- if (col.xlsType) {
8440
- row.xlsType = col.xlsType;
8441
- }
8442
8478
  return Object.assign(Object.assign({}, result), { [col.name]: row });
8443
8479
  }, {});
8444
8480
  }
8481
+ }
8482
+
8483
+ class BaseReport {
8484
+ constructor(labelFormatter) {
8485
+ this.expressionZeedhiToXls = {
8486
+ AVG: 'AVERAGE',
8487
+ COUNT: 'COUNTA',
8488
+ MAX: 'MAX',
8489
+ MIN: 'MIN',
8490
+ SUM: 'SUM',
8491
+ };
8492
+ this.colunmXLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
8493
+ this.reportColumnTransformer = this.getReportColumnTransformer(labelFormatter);
8494
+ }
8495
+ getReportColumnTransformer(labelFormatter) {
8496
+ return new ReportColumnTransformer({ labelFormatter, fileType: this.getFileType() });
8497
+ }
8445
8498
  buildFilter(filter, columns) {
8446
8499
  return Object.keys(filter).map((key) => {
8447
8500
  var _a;
@@ -8464,6 +8517,9 @@ class CSVReport extends BaseReport {
8464
8517
  super(...arguments);
8465
8518
  this.route = '/generateCSV';
8466
8519
  }
8520
+ getFileType() {
8521
+ return 'csv';
8522
+ }
8467
8523
  buildDataset(data, columns) {
8468
8524
  const columnNames = columns.map((col) => col.name);
8469
8525
  const result = data.reduce((reduced, row) => {
@@ -8473,7 +8529,7 @@ class CSVReport extends BaseReport {
8473
8529
  return JSON.stringify(result);
8474
8530
  }
8475
8531
  buildMetadata(name, title, columns, filter) {
8476
- const builtCols = this.buildColumns(columns);
8532
+ const builtCols = this.reportColumnTransformer.transform(columns);
8477
8533
  const builtFilters = this.buildFilter(filter || {}, columns);
8478
8534
  const lang = this.formatLangCode(I18n.instance.language);
8479
8535
  const clientLogo = '';
@@ -8509,30 +8565,17 @@ class PDFReport extends BaseReport {
8509
8565
  super(...arguments);
8510
8566
  this.route = '/generateReport';
8511
8567
  }
8568
+ getFileType() {
8569
+ return 'pdf';
8570
+ }
8571
+ getReportColumnTransformer(labelFormatter) {
8572
+ const getFormatFn = this.getFormatOfColumn.bind(this);
8573
+ const fileType = this.getFileType();
8574
+ return new ReportColumnTransformer({ getFormatFn, labelFormatter, fileType });
8575
+ }
8512
8576
  buildDataset(data) {
8513
8577
  return JSON.stringify(data);
8514
8578
  }
8515
- buildColumns(columns) {
8516
- const { widths, totalWidth } = this.getColumnsWidth(columns);
8517
- return columns.reduce((result, col, index) => {
8518
- let size;
8519
- if (!totalWidth) {
8520
- size = Math.floor(100 / columns.length);
8521
- }
8522
- else {
8523
- size = Math.floor((widths[col.name] * 100) / totalWidth);
8524
- }
8525
- const row = {
8526
- align: col.align || 'left',
8527
- description: col.label,
8528
- sequence: index,
8529
- format: this.getFormatOfColumn(col),
8530
- size: `${size}%`,
8531
- xlsType: col.xlsType,
8532
- };
8533
- return Object.assign(Object.assign({}, result), { [col.name]: row });
8534
- }, {});
8535
- }
8536
8579
  getFormatOfColumn(column) {
8537
8580
  let format;
8538
8581
  let { mask } = column;
@@ -8580,7 +8623,7 @@ class PDFReport extends BaseReport {
8580
8623
  }
8581
8624
  buildMetadata(name, title, columns, filter, portrait = true) {
8582
8625
  return __awaiter(this, void 0, void 0, function* () {
8583
- const builtCols = this.buildColumns(columns);
8626
+ const builtCols = this.reportColumnTransformer.transform(columns);
8584
8627
  const builtFilters = this.buildFilter(filter || {}, columns);
8585
8628
  const lang = this.formatLangCode(I18n.instance.language);
8586
8629
  let clientLogo = '';
@@ -8665,6 +8708,9 @@ class XLSReport extends BaseReport {
8665
8708
  super(...arguments);
8666
8709
  this.route = '/generateXLS';
8667
8710
  }
8711
+ getFileType() {
8712
+ return 'xls';
8713
+ }
8668
8714
  buildDataset(data, columns) {
8669
8715
  const result = this.formatRawDataSet(data, columns);
8670
8716
  return JSON.stringify(result);
@@ -8679,7 +8725,7 @@ class XLSReport extends BaseReport {
8679
8725
  return result;
8680
8726
  }
8681
8727
  buildMetadata(name, title, columns, filter) {
8682
- const builtCols = this.buildColumns(columns);
8728
+ const builtCols = this.reportColumnTransformer.transform(columns);
8683
8729
  const builtFilters = this.buildFilter(filter || {}, columns);
8684
8730
  const lang = this.formatLangCode(I18n.instance.language);
8685
8731
  const clientLogo = '';
@@ -8719,12 +8765,15 @@ class XLS2Report extends BaseReport {
8719
8765
  super(...arguments);
8720
8766
  this.route = '/generateXLS';
8721
8767
  }
8768
+ getFileType() {
8769
+ return 'xls';
8770
+ }
8722
8771
  buildDataset(data, metadata) {
8723
8772
  const result = this.formatDataSet(metadata, data);
8724
8773
  return JSON.stringify(result);
8725
8774
  }
8726
8775
  buildMetadata(name, title, columns, filter) {
8727
- const builtCols = this.buildColumns(columns);
8776
+ const builtCols = this.reportColumnTransformer.transform(columns);
8728
8777
  const builtFilters = this.buildFilter(filter || {}, columns);
8729
8778
  const lang = this.formatLangCode(I18n.instance.language);
8730
8779
  const clientLogo = '';
@@ -8916,12 +8965,15 @@ class XLS3Report extends BaseReport {
8916
8965
  super(...arguments);
8917
8966
  this.route = '/generateXLS';
8918
8967
  }
8968
+ getFileType() {
8969
+ return 'xls';
8970
+ }
8919
8971
  buildDataset(data, metadata) {
8920
8972
  const result = this.formatDataSet(metadata, data);
8921
8973
  return JSON.stringify(result);
8922
8974
  }
8923
8975
  buildMetadata(name, title, columns, filter) {
8924
- const builtCols = this.buildColumns(columns);
8976
+ const builtCols = this.reportColumnTransformer.transform(columns);
8925
8977
  const builtFilters = this.buildFilter(filter || {}, columns);
8926
8978
  const lang = this.formatLangCode(I18n.instance.language);
8927
8979
  const clientLogo = '';
@@ -9208,25 +9260,25 @@ class Report {
9208
9260
  return formattedData;
9209
9261
  });
9210
9262
  }
9211
- getReportType(type) {
9263
+ getReportType(type, labelFormatter) {
9212
9264
  if (type === 'csv') {
9213
- return new CSVReport();
9265
+ return new CSVReport(labelFormatter);
9214
9266
  }
9215
9267
  if (type === 'pdf') {
9216
- return new PDFReport();
9268
+ return new PDFReport(labelFormatter);
9217
9269
  }
9218
9270
  if (type === 'xls') {
9219
- return new XLSReport();
9271
+ return new XLSReport(labelFormatter);
9220
9272
  }
9221
9273
  if (type === 'xls2') {
9222
- return new XLS2Report();
9274
+ return new XLS2Report(labelFormatter);
9223
9275
  }
9224
9276
  if (type === 'xls3') {
9225
- return new XLS3Report();
9277
+ return new XLS3Report(labelFormatter);
9226
9278
  }
9227
9279
  throw new Error(`Invalid report type: ${type}`);
9228
9280
  }
9229
- getReport(type, portrait = true, rowObj, beforeReportEvent) {
9281
+ getReport(type, portrait = true, rowObj, beforeReportEvent, labelFormatter) {
9230
9282
  var _a;
9231
9283
  return __awaiter(this, void 0, void 0, function* () {
9232
9284
  const data = (_a = this.data) !== null && _a !== void 0 ? _a : yield this.getData();
@@ -9237,7 +9289,7 @@ class Report {
9237
9289
  containerLabel: this.title,
9238
9290
  widgetLabel: this.title,
9239
9291
  };
9240
- const reportType = this.getReportType(type);
9292
+ const reportType = this.getReportType(type, labelFormatter);
9241
9293
  const { route } = reportType;
9242
9294
  const { name, columns, datasource } = this.iterable;
9243
9295
  const { groupedData } = Object.assign({}, this.iterable);
@@ -6828,6 +6828,8 @@
6828
6828
  this.viewEnterEdit = null;
6829
6829
  this.showCancelColumn = false;
6830
6830
  this.newRowIdentifier = '__added_row';
6831
+ this.positionIdentifier = '__position';
6832
+ this.pageIdentifier = '__page';
6831
6833
  this.createGridController();
6832
6834
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
6833
6835
  this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
@@ -6836,6 +6838,7 @@
6836
6838
  this.showCancelColumn = this.getInitValue('showCancelColumn', props.showCancelColumn, this.showCancelColumn);
6837
6839
  this.createAccessors();
6838
6840
  this.addCancelColumn();
6841
+ this.registerDatasourceCallback();
6839
6842
  }
6840
6843
  setViewEnterEdit(viewEnterEdit) {
6841
6844
  this.viewEnterEdit = viewEnterEdit;
@@ -6891,6 +6894,35 @@
6891
6894
  instantiateCancelColumn() {
6892
6895
  return new GridColumnEditable(this.getCancelColumnProps());
6893
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
+ }
6894
6926
  createGridController() {
6895
6927
  const controller = new GridEditableController(this);
6896
6928
  core.Loader.addController(`GridEditableController_${this.name}`, controller);
@@ -7203,6 +7235,7 @@
7203
7235
  return __awaiter(this, void 0, void 0, function* () {
7204
7236
  const { page } = this.datasource;
7205
7237
  yield this.cancelAddedRows();
7238
+ this.addedRows = {};
7206
7239
  yield this.datasource.setPage(page);
7207
7240
  this.editing = false;
7208
7241
  this.editedRows = {};
@@ -7220,14 +7253,10 @@
7220
7253
  delete cloneAddedRows[key];
7221
7254
  this.editedRows = cloneEditedRows;
7222
7255
  this.addedRows = cloneAddedRows;
7223
- let { data } = this.datasource;
7224
- if (this.datasource instanceof core.MemoryDatasource) {
7225
- data = this.datasource.allData;
7226
- }
7227
- const { uniqueKey } = this.datasource;
7256
+ const { data, uniqueKey } = this.datasource;
7228
7257
  const index = data.findIndex((row) => row[uniqueKey] === key);
7229
7258
  data.splice(index, 1);
7230
- return this.datasource.updateData(data);
7259
+ return this.datasource.updatePageData(data);
7231
7260
  });
7232
7261
  }
7233
7262
  cancelAddedRows() {
@@ -7240,7 +7269,7 @@
7240
7269
  allData.splice(index, 1);
7241
7270
  }
7242
7271
  }
7243
- yield this.datasource.updateData(allData);
7272
+ yield this.datasource.updatePageData(allData);
7244
7273
  });
7245
7274
  }
7246
7275
  addDataRow(row) {
@@ -7279,6 +7308,8 @@
7279
7308
  const row = Object.assign(Object.assign({}, this.editedRows[key].originalRow), this.editedRows[key]);
7280
7309
  delete row.originalRow;
7281
7310
  delete row[this.newRowIdentifier];
7311
+ delete row[this.positionIdentifier];
7312
+ delete row[this.pageIdentifier];
7282
7313
  Object.keys(row).forEach((attr) => {
7283
7314
  if (Object.prototype.hasOwnProperty.call(row, `${attr}_original`)) {
7284
7315
  delete row[`${attr}_original`];
@@ -7300,6 +7331,8 @@
7300
7331
  const row = Object.assign(Object.assign({}, this.addedRows[key].originalRow), this.addedRows[key]);
7301
7332
  delete row.originalRow;
7302
7333
  delete row[this.newRowIdentifier];
7334
+ delete row[this.positionIdentifier];
7335
+ delete row[this.pageIdentifier];
7303
7336
  Object.keys(row).forEach((attr) => {
7304
7337
  if (Object.prototype.hasOwnProperty.call(row, `${attr}_original`)) {
7305
7338
  delete row[`${attr}_original`];
@@ -7370,10 +7403,14 @@
7370
7403
  return __awaiter(this, void 0, void 0, function* () {
7371
7404
  const data = this.insertRowInDatasource(row, position);
7372
7405
  this.saveRowReference(row);
7373
- yield this.datasource.updateData(data);
7406
+ yield this.datasource.updatePageData(data);
7374
7407
  this.editing = true;
7375
7408
  });
7376
7409
  }
7410
+ /**
7411
+ * Saves a row reference in editedRows and addedRows
7412
+ * @param row Row to be saved
7413
+ */
7377
7414
  saveRowReference(row) {
7378
7415
  const id = row[this.datasource.uniqueKey];
7379
7416
  if (id) {
@@ -7381,15 +7418,18 @@
7381
7418
  this.addedRows = Object.assign(Object.assign({}, this.addedRows), { [id]: Object.assign({}, row) });
7382
7419
  }
7383
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
+ */
7384
7427
  insertRowInDatasource(row, position) {
7385
- let data;
7386
- if (this.datasource instanceof core.MemoryDatasource) {
7387
- data = this.datasource.allData;
7388
- }
7389
- else {
7390
- data = this.datasource.data;
7391
- }
7428
+ const { data } = this.datasource;
7392
7429
  row[this.newRowIdentifier] = true;
7430
+ row[this.positionIdentifier] = position;
7431
+ if (!row[this.pageIdentifier])
7432
+ row[this.pageIdentifier] = this.datasource.page;
7393
7433
  if (position === 'start') {
7394
7434
  data.unshift(row);
7395
7435
  }
@@ -8400,16 +8440,11 @@
8400
8440
  WatchURL.watchers = {};
8401
8441
  WatchURL.originalEvents = new Map();
8402
8442
 
8403
- class BaseReport {
8404
- constructor() {
8405
- this.expressionZeedhiToXls = {
8406
- AVG: 'AVERAGE',
8407
- COUNT: 'COUNTA',
8408
- MAX: 'MAX',
8409
- MIN: 'MIN',
8410
- SUM: 'SUM',
8411
- };
8412
- this.colunmXLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
8443
+ class ReportColumnTransformer {
8444
+ constructor({ getFormatFn, labelFormatter, fileType }) {
8445
+ this.getFormatFn = getFormatFn;
8446
+ this.labelFormatter = labelFormatter;
8447
+ this.fileType = fileType;
8413
8448
  }
8414
8449
  getColumnsWidth(columns) {
8415
8450
  const widths = {};
@@ -8427,7 +8462,7 @@
8427
8462
  }
8428
8463
  return { widths, totalWidth };
8429
8464
  }
8430
- buildColumns(columns) {
8465
+ transform(columns) {
8431
8466
  const { widths, totalWidth } = this.getColumnsWidth(columns);
8432
8467
  return columns.reduce((result, col, index) => {
8433
8468
  let size;
@@ -8437,18 +8472,36 @@
8437
8472
  else {
8438
8473
  size = Math.floor((widths[col.name] * 100) / totalWidth);
8439
8474
  }
8475
+ const description = this.labelFormatter ? this.labelFormatter({ column: col, fileType: this.fileType }) : col.label;
8476
+ const format = this.getFormatFn ? this.getFormatFn(col) : undefined;
8440
8477
  const row = {
8478
+ format,
8479
+ description,
8441
8480
  align: col.align || 'left',
8442
- description: col.label,
8443
8481
  sequence: index,
8444
8482
  size: `${size}%`,
8483
+ xlsType: col.xlsType,
8445
8484
  };
8446
- if (col.xlsType) {
8447
- row.xlsType = col.xlsType;
8448
- }
8449
8485
  return Object.assign(Object.assign({}, result), { [col.name]: row });
8450
8486
  }, {});
8451
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
+ }
8452
8505
  buildFilter(filter, columns) {
8453
8506
  return Object.keys(filter).map((key) => {
8454
8507
  var _a;
@@ -8471,6 +8524,9 @@
8471
8524
  super(...arguments);
8472
8525
  this.route = '/generateCSV';
8473
8526
  }
8527
+ getFileType() {
8528
+ return 'csv';
8529
+ }
8474
8530
  buildDataset(data, columns) {
8475
8531
  const columnNames = columns.map((col) => col.name);
8476
8532
  const result = data.reduce((reduced, row) => {
@@ -8480,7 +8536,7 @@
8480
8536
  return JSON.stringify(result);
8481
8537
  }
8482
8538
  buildMetadata(name, title, columns, filter) {
8483
- const builtCols = this.buildColumns(columns);
8539
+ const builtCols = this.reportColumnTransformer.transform(columns);
8484
8540
  const builtFilters = this.buildFilter(filter || {}, columns);
8485
8541
  const lang = this.formatLangCode(core.I18n.instance.language);
8486
8542
  const clientLogo = '';
@@ -8516,30 +8572,17 @@
8516
8572
  super(...arguments);
8517
8573
  this.route = '/generateReport';
8518
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
+ }
8519
8583
  buildDataset(data) {
8520
8584
  return JSON.stringify(data);
8521
8585
  }
8522
- buildColumns(columns) {
8523
- const { widths, totalWidth } = this.getColumnsWidth(columns);
8524
- return columns.reduce((result, col, index) => {
8525
- let size;
8526
- if (!totalWidth) {
8527
- size = Math.floor(100 / columns.length);
8528
- }
8529
- else {
8530
- size = Math.floor((widths[col.name] * 100) / totalWidth);
8531
- }
8532
- const row = {
8533
- align: col.align || 'left',
8534
- description: col.label,
8535
- sequence: index,
8536
- format: this.getFormatOfColumn(col),
8537
- size: `${size}%`,
8538
- xlsType: col.xlsType,
8539
- };
8540
- return Object.assign(Object.assign({}, result), { [col.name]: row });
8541
- }, {});
8542
- }
8543
8586
  getFormatOfColumn(column) {
8544
8587
  let format;
8545
8588
  let { mask } = column;
@@ -8587,7 +8630,7 @@
8587
8630
  }
8588
8631
  buildMetadata(name, title, columns, filter, portrait = true) {
8589
8632
  return __awaiter(this, void 0, void 0, function* () {
8590
- const builtCols = this.buildColumns(columns);
8633
+ const builtCols = this.reportColumnTransformer.transform(columns);
8591
8634
  const builtFilters = this.buildFilter(filter || {}, columns);
8592
8635
  const lang = this.formatLangCode(core.I18n.instance.language);
8593
8636
  let clientLogo = '';
@@ -8672,6 +8715,9 @@
8672
8715
  super(...arguments);
8673
8716
  this.route = '/generateXLS';
8674
8717
  }
8718
+ getFileType() {
8719
+ return 'xls';
8720
+ }
8675
8721
  buildDataset(data, columns) {
8676
8722
  const result = this.formatRawDataSet(data, columns);
8677
8723
  return JSON.stringify(result);
@@ -8686,7 +8732,7 @@
8686
8732
  return result;
8687
8733
  }
8688
8734
  buildMetadata(name, title, columns, filter) {
8689
- const builtCols = this.buildColumns(columns);
8735
+ const builtCols = this.reportColumnTransformer.transform(columns);
8690
8736
  const builtFilters = this.buildFilter(filter || {}, columns);
8691
8737
  const lang = this.formatLangCode(core.I18n.instance.language);
8692
8738
  const clientLogo = '';
@@ -8726,12 +8772,15 @@
8726
8772
  super(...arguments);
8727
8773
  this.route = '/generateXLS';
8728
8774
  }
8775
+ getFileType() {
8776
+ return 'xls';
8777
+ }
8729
8778
  buildDataset(data, metadata) {
8730
8779
  const result = this.formatDataSet(metadata, data);
8731
8780
  return JSON.stringify(result);
8732
8781
  }
8733
8782
  buildMetadata(name, title, columns, filter) {
8734
- const builtCols = this.buildColumns(columns);
8783
+ const builtCols = this.reportColumnTransformer.transform(columns);
8735
8784
  const builtFilters = this.buildFilter(filter || {}, columns);
8736
8785
  const lang = this.formatLangCode(core.I18n.instance.language);
8737
8786
  const clientLogo = '';
@@ -8923,12 +8972,15 @@
8923
8972
  super(...arguments);
8924
8973
  this.route = '/generateXLS';
8925
8974
  }
8975
+ getFileType() {
8976
+ return 'xls';
8977
+ }
8926
8978
  buildDataset(data, metadata) {
8927
8979
  const result = this.formatDataSet(metadata, data);
8928
8980
  return JSON.stringify(result);
8929
8981
  }
8930
8982
  buildMetadata(name, title, columns, filter) {
8931
- const builtCols = this.buildColumns(columns);
8983
+ const builtCols = this.reportColumnTransformer.transform(columns);
8932
8984
  const builtFilters = this.buildFilter(filter || {}, columns);
8933
8985
  const lang = this.formatLangCode(core.I18n.instance.language);
8934
8986
  const clientLogo = '';
@@ -9215,25 +9267,25 @@
9215
9267
  return formattedData;
9216
9268
  });
9217
9269
  }
9218
- getReportType(type) {
9270
+ getReportType(type, labelFormatter) {
9219
9271
  if (type === 'csv') {
9220
- return new CSVReport();
9272
+ return new CSVReport(labelFormatter);
9221
9273
  }
9222
9274
  if (type === 'pdf') {
9223
- return new PDFReport();
9275
+ return new PDFReport(labelFormatter);
9224
9276
  }
9225
9277
  if (type === 'xls') {
9226
- return new XLSReport();
9278
+ return new XLSReport(labelFormatter);
9227
9279
  }
9228
9280
  if (type === 'xls2') {
9229
- return new XLS2Report();
9281
+ return new XLS2Report(labelFormatter);
9230
9282
  }
9231
9283
  if (type === 'xls3') {
9232
- return new XLS3Report();
9284
+ return new XLS3Report(labelFormatter);
9233
9285
  }
9234
9286
  throw new Error(`Invalid report type: ${type}`);
9235
9287
  }
9236
- getReport(type, portrait = true, rowObj, beforeReportEvent) {
9288
+ getReport(type, portrait = true, rowObj, beforeReportEvent, labelFormatter) {
9237
9289
  var _a;
9238
9290
  return __awaiter(this, void 0, void 0, function* () {
9239
9291
  const data = (_a = this.data) !== null && _a !== void 0 ? _a : yield this.getData();
@@ -9244,7 +9296,7 @@
9244
9296
  containerLabel: this.title,
9245
9297
  widgetLabel: this.title,
9246
9298
  };
9247
- const reportType = this.getReportType(type);
9299
+ const reportType = this.getReportType(type, labelFormatter);
9248
9300
  const { route } = reportType;
9249
9301
  const { name, columns, datasource } = this.iterable;
9250
9302
  const { groupedData } = Object.assign({}, this.iterable);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeedhi/common",
3
- "version": "1.109.1",
3
+ "version": "1.110.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": "7260f4ea8769c7f86c4f6c3e379e141f6ac401c0"
46
+ "gitHead": "fc3c2ff25bee46c565577b6749a4d0539762407f"
47
47
  }
@@ -59,6 +59,7 @@ export declare class GridEditable extends Grid implements IGridEditable {
59
59
  protected addCancelColumn(): void;
60
60
  protected getCancelColumnProps(): IGridColumnEditable;
61
61
  protected instantiateCancelColumn(): GridColumnEditable;
62
+ protected registerDatasourceCallback(): void;
62
63
  protected createGridController(): void;
63
64
  /**
64
65
  * Changes column order
@@ -165,6 +166,8 @@ export declare class GridEditable extends Grid implements IGridEditable {
165
166
  */
166
167
  isValid(column: IGridColumnEditable, row: IDictionary, revalidate?: boolean): string | boolean;
167
168
  private newRowIdentifier;
169
+ private positionIdentifier;
170
+ private pageIdentifier;
168
171
  /**
169
172
  * Cancels all edited rows and enable grid components
170
173
  */
@@ -206,7 +209,17 @@ export declare class GridEditable extends Grid implements IGridEditable {
206
209
  * @param position whether the new Row will be inserted at the beginning or end of the data array
207
210
  */
208
211
  addNewRow(row: IDictionary, position?: 'end' | 'start'): Promise<void>;
212
+ /**
213
+ * Saves a row reference in editedRows and addedRows
214
+ * @param row Row to be saved
215
+ */
209
216
  protected saveRowReference(row: IDictionary<any>): void;
217
+ /**
218
+ * Inserts a row in datasource depending on the position
219
+ * @param row Row to be inserted
220
+ * @param position Position, 'end' or 'start'
221
+ * @returns the data containing the newly added row
222
+ */
210
223
  protected insertRowInDatasource(row: IDictionary<any>, position: 'end' | 'start'): IDictionary<any>[];
211
224
  /**
212
225
  * Gets the editable component name
@@ -1,15 +1,15 @@
1
1
  import { IDictionary } from '@zeedhi/core';
2
2
  import { IColumn } from '../../../components';
3
- import { IReportType, MetadataColumn, MetadataFilter } from './interfaces';
3
+ import { IReportType, MetadataFilter, LabelFormatter } from './interfaces';
4
+ import { ReportColumnTransformer } from './report-column-transformer';
4
5
  export declare abstract class BaseReport implements IReportType {
6
+ reportColumnTransformer: ReportColumnTransformer;
7
+ constructor(labelFormatter?: LabelFormatter);
8
+ protected getReportColumnTransformer(labelFormatter?: LabelFormatter): ReportColumnTransformer;
9
+ abstract getFileType(): string;
5
10
  abstract route: string;
6
11
  abstract buildDataset(data: IDictionary<any>[], metadata?: any): any;
7
12
  abstract buildMetadata(name: string, title: string, columns: IColumn[], filter?: IDictionary<any>, portrait?: boolean): Promise<any>;
8
- protected getColumnsWidth(columns: IColumn[]): {
9
- widths: IDictionary<number>;
10
- totalWidth: number;
11
- };
12
- protected buildColumns(columns: IColumn[]): MetadataColumn;
13
13
  protected buildFilter(filter: IDictionary, columns: IColumn[]): MetadataFilter;
14
14
  protected formatLangCode(lang?: string): string;
15
15
  protected expressionZeedhiToXls: any;
@@ -2,6 +2,7 @@ import { IDictionary } from '@zeedhi/core';
2
2
  import { IColumn } from '../../../components';
3
3
  import { BaseReport } from './base-report';
4
4
  export declare class CSVReport extends BaseReport {
5
+ getFileType(): string;
5
6
  readonly route: string;
6
7
  buildDataset(data: IDictionary<any>[], columns: IColumn[]): string;
7
8
  buildMetadata(name: string, title: string, columns: IColumn[], filter?: IDictionary<any>): Promise<string>;
@@ -45,3 +45,35 @@ export interface IMetadataObj {
45
45
  xlsMergedCell?: any[];
46
46
  xlsDefaultType?: string;
47
47
  }
48
+ export declare type ReportFixFormat = {
49
+ type: 'fix';
50
+ params: {
51
+ mask: string;
52
+ };
53
+ };
54
+ export declare type ReportCurrencyFormat = {
55
+ type: 'currency';
56
+ symbol: string;
57
+ decimal: string;
58
+ thousands: string;
59
+ precision: number;
60
+ };
61
+ export declare type ReportNumberFormat = {
62
+ params: {
63
+ decimal: string;
64
+ thousands: string;
65
+ precision: number;
66
+ };
67
+ };
68
+ export declare type ReportFormat = ReportFixFormat | ReportCurrencyFormat | ReportNumberFormat;
69
+ export declare type GetFormatFn = (col: IColumn) => ReportFormat;
70
+ export declare type LabelFormatterParams = {
71
+ column: IColumn;
72
+ fileType: string;
73
+ };
74
+ export declare type LabelFormatter = ({ column, fileType }: LabelFormatterParams) => string;
75
+ export declare type ReportColumnTransformerParams = {
76
+ getFormatFn?: GetFormatFn;
77
+ labelFormatter?: LabelFormatter;
78
+ fileType: string;
79
+ };
@@ -1,11 +1,13 @@
1
1
  import { IDictionary } from '@zeedhi/core';
2
2
  import { IColumn } from '../../../components';
3
3
  import { BaseReport } from './base-report';
4
- import { MetadataColumn } from './interfaces';
4
+ import { LabelFormatter } from './interfaces';
5
+ import { ReportColumnTransformer } from './report-column-transformer';
5
6
  export declare class PDFReport extends BaseReport {
7
+ getFileType(): string;
6
8
  readonly route: string;
9
+ protected getReportColumnTransformer(labelFormatter?: LabelFormatter): ReportColumnTransformer;
7
10
  buildDataset(data: IDictionary<any>[]): string;
8
- protected buildColumns(columns: IColumn[]): MetadataColumn;
9
11
  private getFormatOfColumn;
10
12
  private isNumberComponent;
11
13
  private checkAccessor;
@@ -0,0 +1,9 @@
1
+ import { MetadataColumn, ReportColumnTransformerParams } from './interfaces';
2
+ export declare class ReportColumnTransformer {
3
+ private getFormatFn?;
4
+ private labelFormatter?;
5
+ private fileType;
6
+ constructor({ getFormatFn, labelFormatter, fileType }: ReportColumnTransformerParams);
7
+ private getColumnsWidth;
8
+ transform(columns: any[]): MetadataColumn;
9
+ }
@@ -2,6 +2,7 @@ import { IDictionary } from '@zeedhi/core';
2
2
  import { IColumn } from '../../../components';
3
3
  import { BaseReport } from './base-report';
4
4
  export declare class XLSReport extends BaseReport {
5
+ getFileType(): string;
5
6
  readonly route: string;
6
7
  buildDataset(data: IDictionary<any>[], columns: IColumn[]): string;
7
8
  private formatRawDataSet;
@@ -3,6 +3,7 @@ import { IColumn } from '../../../components';
3
3
  import { BaseReport } from './base-report';
4
4
  import { IMetadataObj } from './interfaces';
5
5
  export declare class XLS2Report extends BaseReport {
6
+ getFileType(): string;
6
7
  readonly route: string;
7
8
  buildDataset(data: IDictionary<any>[], metadata: IMetadataObj): string;
8
9
  buildMetadata(name: string, title: string, columns: IColumn[], filter?: IDictionary<any>): Promise<string>;
@@ -3,6 +3,7 @@ import { IColumn } from '../../../components';
3
3
  import { BaseReport } from './base-report';
4
4
  import { IMetadataObj } from './interfaces';
5
5
  export declare class XLS3Report extends BaseReport {
6
+ getFileType(): string;
6
7
  readonly route: string;
7
8
  buildDataset(data: IDictionary<any>[], metadata: IMetadataObj): string;
8
9
  buildMetadata(name: string, title: string, columns: IColumn[], filter?: IDictionary<any>): Promise<string>;
@@ -1,5 +1,6 @@
1
1
  import { IDictionary } from '@zeedhi/core';
2
2
  import { Iterable } from '../../components';
3
+ import { LabelFormatter } from './report-type';
3
4
  import { IBeforeReportEvent, IReport } from './interfaces';
4
5
  export declare class Report implements IReport {
5
6
  iterable: Iterable;
@@ -12,6 +13,6 @@ export declare class Report implements IReport {
12
13
  private isToggleableComponent;
13
14
  private getData;
14
15
  private getReportType;
15
- getReport(type: string, portrait?: boolean, rowObj?: any, beforeReportEvent?: IBeforeReportEvent): Promise<string>;
16
+ getReport(type: string, portrait?: boolean, rowObj?: any, beforeReportEvent?: IBeforeReportEvent, labelFormatter?: LabelFormatter): Promise<string>;
16
17
  private filterColumns;
17
18
  }