@zeedhi/common 1.96.0 → 1.96.2

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, Metadata, Accessor, I18n, FormatterParserProvider, Validation, Mask, DatasourceFactory, MethodNotAssignedError, Loader, Config, dayjs, Utils, DateHelper, Router, InstanceNotFoundError, MemoryDatasource, Cookie, Http, URL as URL$1, VersionService } from '@zeedhi/core';
1
+ import { AccessorManager, Event, KeyMap, Metadata, Accessor, I18n, FormatterParserProvider, Validation, Mask, DatasourceFactory, MethodNotAssignedError, Loader, Config, dayjs, Utils, DateHelper, Router, InstanceNotFoundError, ViewService, MemoryDatasource, Cookie, Http, URL as URL$1, 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';
@@ -2003,7 +2003,10 @@ class Input extends ComponentRender {
2003
2003
  */
2004
2004
  updateRules() {
2005
2005
  this.rules = Object.values(this.parsedValidations)
2006
- .map((validation) => () => validation(this.value));
2006
+ .map((validation) => (value) => {
2007
+ const testValue = value !== undefined ? value : this.value;
2008
+ return validation(testValue);
2009
+ });
2007
2010
  }
2008
2011
  /**
2009
2012
  * Input value.
@@ -2056,8 +2059,11 @@ class Input extends ComponentRender {
2056
2059
  * Checks the input value are valid to all applied rules.
2057
2060
  * @returns Input is valid
2058
2061
  */
2059
- isValid() {
2060
- return this.rules.every((rule) => typeof rule(this.value) !== 'string');
2062
+ isValid(value) {
2063
+ return this.rules.every((rule) => {
2064
+ const testValue = value !== undefined ? value : this.value;
2065
+ return typeof rule(testValue) !== 'string';
2066
+ });
2061
2067
  }
2062
2068
  /**
2063
2069
  * Triggered when the input value changes.
@@ -2142,6 +2148,19 @@ class Toggleable extends Input {
2142
2148
  }
2143
2149
  }
2144
2150
 
2151
+ class InputFactory {
2152
+ static register(className, inputClass) {
2153
+ if (!this.inputClasses[className])
2154
+ this.inputClasses[className] = inputClass;
2155
+ }
2156
+ static factory(props) {
2157
+ if (!this.inputClasses[props.component])
2158
+ return undefined;
2159
+ return new this.inputClasses[props.component](props);
2160
+ }
2161
+ }
2162
+ InputFactory.inputClasses = {};
2163
+
2145
2164
  /**
2146
2165
  * Base class for Checkbox component.
2147
2166
  */
@@ -2156,7 +2175,8 @@ class Checkbox extends Toggleable {
2156
2175
  this.showHelper = false;
2157
2176
  this.createAccessors();
2158
2177
  }
2159
- }
2178
+ }
2179
+ InputFactory.register('ZdCheckbox', Checkbox);
2160
2180
 
2161
2181
  /**
2162
2182
  * Base class for Checkbox multiple component.
@@ -2209,7 +2229,8 @@ class CheckboxMultiple extends Input {
2209
2229
  super.onBeforeDestroy();
2210
2230
  this.datasource.destroy();
2211
2231
  }
2212
- }
2232
+ }
2233
+ InputFactory.register('ZdCheckboxMultiple', CheckboxMultiple);
2213
2234
 
2214
2235
  /**
2215
2236
  * Base class for Chip component.
@@ -2696,10 +2717,15 @@ class TextInput extends Input {
2696
2717
  * Defines text input value should concat the suffix text.
2697
2718
  */
2698
2719
  this.valueWithSuffix = textInputDefaults.valueWithSuffix;
2720
+ /**
2721
+ * Defines clicks on outer icon should focus the component.
2722
+ */
2723
+ this.focusOnOuterIconClick = true;
2699
2724
  this.formatterFn = FormatterParserProvider.getFormatter('ZdTextInput');
2700
2725
  this.parserFn = FormatterParserProvider.getParser('ZdTextInput');
2701
2726
  this.appendIcon = this.getInitValue('appendIcon', props.appendIcon, this.appendIcon);
2702
2727
  this.appendOuterIcon = this.getInitValue('appendOuterIcon', props.appendOuterIcon, this.appendOuterIcon);
2728
+ this.focusOnOuterIconClick = this.getInitValue('focusOnOuterIconClick', props.focusOnOuterIconClick, this.focusOnOuterIconClick);
2703
2729
  this.prefix = this.getInitValue('prefix', props.prefix, this.prefix);
2704
2730
  this.prependIcon = this.getInitValue('prependIcon', props.prependIcon, this.prependIcon);
2705
2731
  this.prependOuterIcon = this.getInitValue('prependOuterIcon', props.prependOuterIcon, this.prependOuterIcon);
@@ -2805,7 +2831,8 @@ FormatterParserProvider.registerParser('ZdTextInput', (value, { valueWithPrefix
2805
2831
  formatted = prefixValue + formatted + suffixValue;
2806
2832
  }
2807
2833
  return formatted;
2808
- });
2834
+ });
2835
+ InputFactory.register('ZdTextInput', TextInput);
2809
2836
 
2810
2837
  /**
2811
2838
  * Base class for Number component
@@ -2915,7 +2942,8 @@ FormatterParserProvider.registerParser('ZdNumber', (value, { mask = {}, } = {})
2915
2942
  let maskValue = typeof (maskDef) === 'function' ? maskDef(AutoNumeric.format(value)) : maskDef;
2916
2943
  maskValue = Object.assign(Object.assign({}, Config.masks.numberMask), maskValue);
2917
2944
  return value === '' ? null : AutoNumeric.unformat(value, maskValue);
2918
- });
2945
+ });
2946
+ InputFactory.register('ZdNumber', Number$1);
2919
2947
 
2920
2948
  /**
2921
2949
  * Base class for Currency component
@@ -2951,7 +2979,8 @@ FormatterParserProvider.registerParser('ZdCurrency', (value, { mask = {}, } = {}
2951
2979
  let maskValue = typeof (maskDef) === 'function' ? maskDef(AutoNumeric.format(value)) : maskDef;
2952
2980
  maskValue = Object.assign(Object.assign(Object.assign({}, Config.masks.numberMask), Config.masks.currencyMask), maskValue);
2953
2981
  return value === '' ? null : AutoNumeric.unformat(value, maskValue);
2954
- });
2982
+ });
2983
+ InputFactory.register('ZdCurrency', Currency);
2955
2984
 
2956
2985
  class AlertQueue {
2957
2986
  constructor() {
@@ -4209,7 +4238,8 @@ FormatterParserProvider.registerParser('ZdDateTime', (value, { dateTimeFormat =
4209
4238
  return dayjs(value, displayFormat).format(dateTimeFormat);
4210
4239
  }
4211
4240
  return value;
4212
- });
4241
+ });
4242
+ InputFactory.register('ZdDate', Date$1);
4213
4243
 
4214
4244
  class DateRange extends TextInput {
4215
4245
  /* istanbul ignore next */
@@ -4673,7 +4703,8 @@ FormatterParserProvider.registerParser('ZdDateRange', (value, { dateFormat = Con
4673
4703
  }
4674
4704
  });
4675
4705
  return formattedValue;
4676
- });
4706
+ });
4707
+ InputFactory.register('ZdDateRange', DateRange);
4677
4708
 
4678
4709
  /**
4679
4710
  * Base class for Divider component.
@@ -4942,8 +4973,12 @@ class FileInput extends TextInput {
4942
4973
  this.rules = Object.keys(this.parsedValidations)
4943
4974
  .map((key) => {
4944
4975
  const validation = this.parsedValidations[key];
4945
- if (key !== 'maxFileSize')
4946
- return () => validation(this.value);
4976
+ if (key !== 'maxFileSize') {
4977
+ return (value) => {
4978
+ const testValue = value !== undefined ? value : this.value;
4979
+ return validation(testValue);
4980
+ };
4981
+ }
4947
4982
  return () => {
4948
4983
  if (this.viewGetFileSizes) {
4949
4984
  const fileSizes = this.viewGetFileSizes();
@@ -4965,7 +5000,8 @@ Validation.register('maxFileSize', (config) => (fileSizes) => {
4965
5000
  });
4966
5001
  const message = I18n.translate((config.message || 'VALIDATION_FILE_SIZE'), { fileError });
4967
5002
  return (fileError === '') || message;
4968
- });
5003
+ });
5004
+ InputFactory.register('ZdFileInput', FileInput);
4969
5005
 
4970
5006
  /**
4971
5007
  * Base class for Footer component.
@@ -5745,12 +5781,12 @@ FormatterParserProvider.registerFormatter('column_ZdSelect', ({ column, value, r
5745
5781
  const { dataText, formatterDataText, dataTextSeparator, dataValue, } = componentProps;
5746
5782
  let currentRow = row;
5747
5783
  if (dataValue) {
5784
+ const dataTextColumns = Array.isArray(dataText) ? dataText : [dataText];
5785
+ const columns = Array.isArray(formatterDataText) ? formatterDataText : [formatterDataText];
5748
5786
  if (!formatterDataText) {
5749
5787
  currentRow = column.getLookupData(dataValue, value[dataValue] || value);
5750
5788
  }
5751
- else {
5752
- const columns = Array.isArray(formatterDataText) ? formatterDataText : [formatterDataText];
5753
- const dataTextColumns = Array.isArray(dataText) ? dataText : [dataText];
5789
+ else if (columns.length === dataTextColumns.length) {
5754
5790
  const loopkupRow = {};
5755
5791
  columns.forEach((item, index) => {
5756
5792
  const dataTextValue = dataTextColumns[index];
@@ -6008,7 +6044,7 @@ class Grid extends Iterable {
6008
6044
  },
6009
6045
  tab: {
6010
6046
  event: this.navigateRight.bind(this),
6011
- prevent: true,
6047
+ prevent: false,
6012
6048
  active: true,
6013
6049
  index: 99,
6014
6050
  input: true,
@@ -6016,7 +6052,7 @@ class Grid extends Iterable {
6016
6052
  },
6017
6053
  'shift+tab': {
6018
6054
  event: this.navigateLeft.bind(this),
6019
- prevent: true,
6055
+ prevent: false,
6020
6056
  active: true,
6021
6057
  index: 99,
6022
6058
  input: true,
@@ -6267,51 +6303,58 @@ class Grid extends Iterable {
6267
6303
  arrSelection.splice(index, 1);
6268
6304
  }
6269
6305
  }
6270
- navigateLeft() {
6306
+ navigateLeft({ event }) {
6271
6307
  if (!this.viewNavigate)
6272
6308
  return;
6273
- this.viewNavigate('left');
6309
+ this.viewNavigate('left', event);
6274
6310
  }
6275
- navigateRight() {
6311
+ navigateRight({ event }) {
6276
6312
  if (!this.viewNavigate)
6277
6313
  return;
6278
- this.viewNavigate('right');
6314
+ this.viewNavigate('right', event);
6279
6315
  }
6280
6316
  navigateUp() {
6281
- if (this.cellSelection && this.viewNavigate) {
6282
- this.viewNavigate('up');
6283
- return;
6284
- }
6285
- const { uniqueKey, currentRow } = this.datasource;
6286
- const rowIndex = this.datasource.data.findIndex((row) => row[uniqueKey] === currentRow[uniqueKey]);
6287
- if (rowIndex === -1) {
6288
- this.datasource.currentRow = this.datasource.data[this.datasource.data.length - 1];
6289
- [this.currentColumn] = this.columns;
6290
- return;
6291
- }
6292
- if (rowIndex === 0) {
6293
- this.navigatePageDown();
6317
+ if (!this.viewNavigate)
6294
6318
  return;
6295
- }
6296
- this.datasource.currentRow = this.datasource.data[rowIndex - 1];
6319
+ this.viewNavigate('up');
6297
6320
  }
6298
6321
  navigateDown() {
6299
- if (this.cellSelection && this.viewNavigate) {
6300
- this.viewNavigate('down');
6322
+ if (!this.viewNavigate)
6301
6323
  return;
6302
- }
6324
+ this.viewNavigate('down');
6325
+ }
6326
+ navigateDatasource(up) {
6303
6327
  const { uniqueKey, currentRow } = this.datasource;
6304
6328
  const rowIndex = this.datasource.data.findIndex((row) => row[uniqueKey] === currentRow[uniqueKey]);
6305
6329
  if (rowIndex === -1) {
6306
- [this.datasource.currentRow] = this.datasource.data;
6307
- [this.currentColumn] = this.columns;
6308
- return;
6330
+ return this.navigateInitial(up);
6331
+ }
6332
+ if (up && rowIndex === 0) {
6333
+ return this.navigatePageDown();
6309
6334
  }
6310
- if (rowIndex === this.datasource.data.length - 1) {
6311
- this.navigatePageUp();
6335
+ if (!up && rowIndex === this.datasource.data.length - 1) {
6336
+ return this.navigatePageUp();
6337
+ }
6338
+ return this.navigateCurrentRow(up, rowIndex);
6339
+ }
6340
+ navigateCurrentRow(up, rowIndex) {
6341
+ const addIndex = up ? -1 : 1;
6342
+ this.datasource.currentRow = this.datasource.data[rowIndex + addIndex];
6343
+ }
6344
+ navigateInitial(up) {
6345
+ if (up) {
6346
+ this.navigateLast();
6312
6347
  return;
6313
6348
  }
6314
- this.datasource.currentRow = this.datasource.data[rowIndex + 1];
6349
+ this.navigateFirst();
6350
+ }
6351
+ navigateFirst() {
6352
+ [this.datasource.currentRow] = this.datasource.data;
6353
+ [this.currentColumn] = this.columns;
6354
+ }
6355
+ navigateLast() {
6356
+ this.datasource.currentRow = this.datasource.data[this.datasource.data.length - 1];
6357
+ [this.currentColumn] = this.columns;
6315
6358
  }
6316
6359
  navigatePageUp() {
6317
6360
  if (this.datasource.page < Math.ceil(this.datasource.total / this.datasource.limit)) {
@@ -6489,6 +6532,7 @@ class GridEditable extends Grid {
6489
6532
  active: true,
6490
6533
  },
6491
6534
  };
6535
+ this.viewEnterEdit = null;
6492
6536
  this.newRowIdentifier = '__added_row';
6493
6537
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
6494
6538
  this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
@@ -6496,6 +6540,9 @@ class GridEditable extends Grid {
6496
6540
  this.singleEdit = this.getInitValue('singleEdit', props.singleEdit, this.singleEdit);
6497
6541
  this.createAccessors();
6498
6542
  }
6543
+ setViewEnterEdit(viewEnterEdit) {
6544
+ this.viewEnterEdit = viewEnterEdit;
6545
+ }
6499
6546
  onMounted(element) {
6500
6547
  super.onMounted(element);
6501
6548
  KeyMap.bind(this.cancelEditedRowsKeyMapping, this, element);
@@ -6846,6 +6893,9 @@ class GridEditable extends Grid {
6846
6893
  if (!revalidate) {
6847
6894
  return Object.keys(this.invalidComponents).length === 0;
6848
6895
  }
6896
+ if (!this.editing) {
6897
+ return this.isViewGridValid();
6898
+ }
6849
6899
  let allValid = true;
6850
6900
  this.datasource.data.forEach((row) => this.columns.forEach((column) => {
6851
6901
  if (!column.isVisible || !column.editable)
@@ -6855,6 +6905,38 @@ class GridEditable extends Grid {
6855
6905
  }));
6856
6906
  return allValid;
6857
6907
  }
6908
+ /**
6909
+ * Checks whether the grid is valid while not in editing mode
6910
+ */
6911
+ isViewGridValid(forceEditing = true) {
6912
+ const invalidCompNames = [];
6913
+ const componentInstances = {};
6914
+ const editableColumns = this.columns.filter((column) => column.editable && column.isVisible);
6915
+ editableColumns.forEach((column) => {
6916
+ const compName = this.getCompName('temp', column.name);
6917
+ const componentProps = Object.assign(Object.assign({}, column.componentProps), { name: compName });
6918
+ componentInstances[column.name] = InputFactory.factory(componentProps);
6919
+ });
6920
+ this.datasource.data.forEach((row) => {
6921
+ const key = row[this.datasource.uniqueKey];
6922
+ editableColumns.forEach((column) => {
6923
+ const instance = componentInstances[column.name];
6924
+ if (!instance.isValid(row[column.name])) {
6925
+ invalidCompNames.push(this.getCompName(key, column.name));
6926
+ }
6927
+ });
6928
+ });
6929
+ if (invalidCompNames.length > 0 && forceEditing) {
6930
+ this.editing = true;
6931
+ ViewService.nextTick(() => {
6932
+ invalidCompNames.forEach((compName) => {
6933
+ const invalidComponent = Metadata.getInstance(compName);
6934
+ invalidComponent.validate();
6935
+ });
6936
+ });
6937
+ }
6938
+ return invalidCompNames.length === 0;
6939
+ }
6858
6940
  /**
6859
6941
  * Adds new row to the datasource data and pushes it to the editedRows
6860
6942
  * @param row Row
@@ -6985,6 +7067,15 @@ class GridEditable extends Grid {
6985
7067
  delete rows[foundRow[uniqueKey]];
6986
7068
  this.editedRows = rows;
6987
7069
  }
7070
+ /**
7071
+ * Makes the cell enter edit mode
7072
+ */
7073
+ enterEdit(rowKey, columnName) {
7074
+ if (!this.viewEnterEdit) {
7075
+ throw new Error('viewEnterEdit method not assigned');
7076
+ }
7077
+ this.viewEnterEdit(rowKey, columnName);
7078
+ }
6988
7079
  }
6989
7080
 
6990
7081
  /**
@@ -7340,7 +7431,8 @@ class Increment extends Number$1 {
7340
7431
  this.value -= this.step;
7341
7432
  }
7342
7433
  }
7343
- }
7434
+ }
7435
+ InputFactory.register('ZdIncrement', Increment);
7344
7436
 
7345
7437
  class IterableColumnsButtonController {
7346
7438
  constructor(iterableComponent) {
@@ -8025,7 +8117,8 @@ FormatterParserProvider.registerFormatter('ZdSelect', (value, { dataText, dataTe
8025
8117
  }
8026
8118
  return result;
8027
8119
  }, '');
8028
- });
8120
+ });
8121
+ InputFactory.register('ZdSelect', Select);
8029
8122
 
8030
8123
  /**
8031
8124
  * Base class for Iterable Page Size component
@@ -8192,7 +8285,8 @@ class Search extends TextInput {
8192
8285
  yield this.iterableComponent.setSearch(search);
8193
8286
  });
8194
8287
  }
8195
- }
8288
+ }
8289
+ InputFactory.register('ZdSearch', Search);
8196
8290
 
8197
8291
  /**
8198
8292
  * Base class for IterableComponentRender component.
@@ -9450,12 +9544,14 @@ class Modal extends Component {
9450
9544
  */
9451
9545
  show() {
9452
9546
  this.isVisible = true;
9547
+ ViewService.nextTick(() => this.callEvent('onShow', { component: this }));
9453
9548
  }
9454
9549
  /**
9455
9550
  * Closes modal
9456
9551
  */
9457
9552
  hide() {
9458
9553
  this.isVisible = false;
9554
+ ViewService.nextTick(() => this.callEvent('onHide', { component: this }));
9459
9555
  }
9460
9556
  }
9461
9557
 
@@ -9626,7 +9722,8 @@ class Password extends TextInput {
9626
9722
  }
9627
9723
  }
9628
9724
  }
9629
- FormatterParserProvider.registerFormatter('ZdPassword', (value) => (value || '').replace(/./g, '*'));
9725
+ FormatterParserProvider.registerFormatter('ZdPassword', (value) => (value || '').replace(/./g, '*'));
9726
+ InputFactory.register('ZdPassword', Password);
9630
9727
 
9631
9728
  /**
9632
9729
  * Base class for Progress component
@@ -9721,7 +9818,8 @@ class Radio extends Input {
9721
9818
  super.onBeforeDestroy();
9722
9819
  this.datasource.destroy();
9723
9820
  }
9724
- }
9821
+ }
9822
+ InputFactory.register('ZdRadio', Radio);
9725
9823
 
9726
9824
  /**
9727
9825
  * Base class for Range Slider component
@@ -9818,7 +9916,8 @@ class RangeSlider extends Input {
9818
9916
  set value(value) {
9819
9917
  this.rangeSliderValue = value;
9820
9918
  }
9821
- }
9919
+ }
9920
+ InputFactory.register('ZdRangeSlider', RangeSlider);
9822
9921
 
9823
9922
  /**
9824
9923
  * Base class for Row component.
@@ -10245,11 +10344,12 @@ class SelectMultiple extends Select {
10245
10344
  */
10246
10345
  updateRules() {
10247
10346
  this.rules = Object.keys(this.parsedValidations)
10248
- .map((key) => () => {
10347
+ .map((key) => (value) => {
10348
+ const testValue = value !== undefined ? value : this.value;
10249
10349
  const validation = this.parsedValidations[key];
10250
10350
  if (key !== 'required')
10251
- return validation(this.value);
10252
- return validation((this.checkboxAll && 'all') || this.value);
10351
+ return validation(testValue);
10352
+ return validation((this.checkboxAll && 'all') || testValue);
10253
10353
  });
10254
10354
  }
10255
10355
  }
@@ -11079,7 +11179,8 @@ class SelectTree extends TextInput {
11079
11179
  this.setValue(filteredNode.id);
11080
11180
  }
11081
11181
  }
11082
- }
11182
+ }
11183
+ InputFactory.register('ZdSelectTree', SelectTree);
11083
11184
 
11084
11185
  /**
11085
11186
  * Base class for Select Tree Multiple component.
@@ -11529,7 +11630,8 @@ class Switch extends Toggleable {
11529
11630
  this.inset = this.getInitValue('inset', props.inset, this.inset);
11530
11631
  this.createAccessors();
11531
11632
  }
11532
- }
11633
+ }
11634
+ InputFactory.register('ZdSwitch', Switch);
11533
11635
 
11534
11636
  /**
11535
11637
  * Base class for Table component.
@@ -11867,7 +11969,8 @@ class Textarea extends TextInput {
11867
11969
  this.addValidation('maxLength', { limit: parseInt(this.counter.toString(), 10) });
11868
11970
  }
11869
11971
  }
11870
- }
11972
+ }
11973
+ InputFactory.register('ZdTextarea', Textarea);
11871
11974
 
11872
11975
  /**
11873
11976
  * Selects the time format by the rule:
@@ -12255,7 +12358,8 @@ FormatterParserProvider.registerParser('ZdTime', (value, { displayFormat = Confi
12255
12358
  }
12256
12359
  }
12257
12360
  return value;
12258
- });
12361
+ });
12362
+ InputFactory.register('ZdTime', Time);
12259
12363
 
12260
12364
  /**
12261
12365
  * Base class for Tooltip component.
@@ -12900,45 +13004,28 @@ class TreeGrid extends Grid {
12900
13004
  navigateToggle(collapse) {
12901
13005
  this.treeDataStructure.navigateToggle(collapse);
12902
13006
  }
12903
- /**
12904
- * Navigate upwards
12905
- */
12906
- navigateUp() {
12907
- if (this.cellSelection && this.viewNavigate) {
12908
- this.viewNavigate('up');
12909
- return;
12910
- }
13007
+ navigateDatasource(up) {
12911
13008
  const { uniqueKey, currentRow } = this.datasource;
12912
13009
  const rowIndex = this.treeDataStructure.findDataIndex(this.datasource.data, currentRow[uniqueKey]);
12913
- if (rowIndex === -1) {
12914
- const lastOpenedRowIdx = this.treeDataStructure.previousOpenedRow(this.datasource.data.length);
12915
- this.datasource.currentRow = this.datasource.data[lastOpenedRowIdx];
12916
- }
12917
- else {
13010
+ if (up) {
13011
+ if (rowIndex === -1) {
13012
+ const lastOpenedRowIdx = this.treeDataStructure.previousOpenedRow(this.datasource.data.length);
13013
+ this.datasource.currentRow = this.datasource.data[lastOpenedRowIdx];
13014
+ return;
13015
+ }
12918
13016
  const previousRowIdx = this.treeDataStructure.previousOpenedRow(rowIndex);
12919
13017
  if (previousRowIdx > -1) {
12920
13018
  this.datasource.currentRow = this.datasource.data[previousRowIdx];
12921
13019
  }
12922
- }
12923
- }
12924
- /**
12925
- * Navigate downwards
12926
- */
12927
- navigateDown() {
12928
- if (this.cellSelection && this.viewNavigate) {
12929
- this.viewNavigate('down');
12930
13020
  return;
12931
13021
  }
12932
- const { uniqueKey, currentRow } = this.datasource;
12933
- const rowIndex = this.treeDataStructure.findDataIndex(this.datasource.data, currentRow[uniqueKey]);
12934
13022
  if (rowIndex === -1) {
12935
13023
  [this.datasource.currentRow] = this.datasource.data;
13024
+ return;
12936
13025
  }
12937
- else {
12938
- const nextRowIdx = this.treeDataStructure.nextOpenedRow(rowIndex);
12939
- if (nextRowIdx > -1) {
12940
- this.datasource.currentRow = this.datasource.data[nextRowIdx];
12941
- }
13026
+ const nextRowIdx = this.treeDataStructure.nextOpenedRow(rowIndex);
13027
+ if (nextRowIdx > -1) {
13028
+ this.datasource.currentRow = this.datasource.data[nextRowIdx];
12942
13029
  }
12943
13030
  }
12944
13031
  removeDuplicates(arr, key) {
@@ -13078,12 +13165,16 @@ class TreeGridEditable extends TreeGrid {
13078
13165
  active: true,
13079
13166
  },
13080
13167
  };
13168
+ this.viewEnterEdit = null;
13081
13169
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
13082
13170
  this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
13083
13171
  this.singleEdit = this.getInitValue('singleEdit', props.singleEdit, this.singleEdit);
13084
13172
  this.noDataSlot = this.changeDefaultSlotNames(this.noDataSlot);
13085
13173
  this.createAccessors();
13086
13174
  }
13175
+ setViewEnterEdit(viewEnterEdit) {
13176
+ this.viewEnterEdit = viewEnterEdit;
13177
+ }
13087
13178
  onMounted(element) {
13088
13179
  super.onMounted(element);
13089
13180
  KeyMap.bind(this.cancelEditedRowsKeyMapping, this, element);
@@ -13527,6 +13618,15 @@ class TreeGridEditable extends TreeGrid {
13527
13618
  delete rows[foundRow[uniqueKey]];
13528
13619
  this.editedRows = rows;
13529
13620
  }
13621
+ /**
13622
+ * Makes the cell enter edit mode
13623
+ */
13624
+ enterEdit(rowKey, columnName) {
13625
+ if (!this.viewEnterEdit) {
13626
+ throw new Error('viewEnterEdit method not assigned');
13627
+ }
13628
+ this.viewEnterEdit(rowKey, columnName);
13629
+ }
13530
13630
  }
13531
13631
 
13532
13632
  class Icons {
@@ -14665,6 +14765,52 @@ class XLS3Report extends BaseReport {
14665
14765
  }
14666
14766
  }
14667
14767
 
14768
+ /**
14769
+ * Class used to format grouped data into the ZhReports format
14770
+ */
14771
+ class GroupedPDFFormatter {
14772
+ format(data) {
14773
+ return data.map((item) => {
14774
+ if (this.isGroupHeader(item)) {
14775
+ return {
14776
+ __group: item.group,
14777
+ __groupHeader: item.groupHeader,
14778
+ __groupFooter: false,
14779
+ __groupIndex: item.groupIndex,
14780
+ __groupLabel: item.groupLabel,
14781
+ __groupValue: item.groupValue,
14782
+ __groupOpened: item.groupOpened,
14783
+ };
14784
+ }
14785
+ if (this.isGroupFooter(item)) {
14786
+ const groupKeys = ['groupFooter', 'groupIndex', 'groupHeaders', 'groupLabel', 'groupValue', 'groupSummary'];
14787
+ const totalColumnNames = Object.keys(item).filter((key) => !groupKeys.includes(key));
14788
+ const result = {
14789
+ __group: true,
14790
+ __groupFooter: item.groupFooter,
14791
+ __groupIndex: item.groupIndex,
14792
+ __groupLabel: item.groupLabel,
14793
+ __groupValue: item.groupValue,
14794
+ __groupSummary: !!item.groupSummary,
14795
+ };
14796
+ totalColumnNames.forEach((name) => {
14797
+ result[name] = item[name];
14798
+ });
14799
+ return result;
14800
+ }
14801
+ const dataItem = Object.assign({}, item);
14802
+ delete dataItem.groupHeaders;
14803
+ return dataItem;
14804
+ });
14805
+ }
14806
+ isGroupHeader(entry) {
14807
+ return entry.groupHeader === true;
14808
+ }
14809
+ isGroupFooter(entry) {
14810
+ return entry.groupFooter === true;
14811
+ }
14812
+ }
14813
+
14668
14814
  class Report {
14669
14815
  constructor(iterable, title) {
14670
14816
  this.endPoint = Config.reportsEndPoint;
@@ -14721,7 +14867,7 @@ class Report {
14721
14867
  const { route } = reportType;
14722
14868
  const { name, columns, datasource } = this.iterable;
14723
14869
  const { groupedData } = Object.assign({}, this.iterable);
14724
- const formattedColumns = this.removeColumns(columns);
14870
+ const formattedColumns = this.filterColumns(columns);
14725
14871
  const metadataObj = yield reportType.buildMetadata(name, this.title, formattedColumns, datasource.filter, portrait);
14726
14872
  let dataset;
14727
14873
  if ((reportType instanceof XLS2Report || reportType instanceof XLS3Report) && groupedData) {
@@ -14729,6 +14875,11 @@ class Report {
14729
14875
  const metadataObjClone = merge(rowMetadata, JSON.parse(metadataObj));
14730
14876
  dataset = reportType.buildDataset(groupedData, metadataObjClone);
14731
14877
  }
14878
+ else if (reportType instanceof PDFReport && groupedData && groupedData.length > 0) {
14879
+ const formatter = new GroupedPDFFormatter();
14880
+ const pdfGroupedData = formatter.format(groupedData);
14881
+ dataset = reportType.buildDataset(pdfGroupedData);
14882
+ }
14732
14883
  else {
14733
14884
  dataset = reportType.buildDataset(data, formattedColumns);
14734
14885
  }
@@ -14759,7 +14910,7 @@ class Report {
14759
14910
  return new URL(reportFile, this.fileEndPoint).href;
14760
14911
  });
14761
14912
  }
14762
- removeColumns(columns) {
14913
+ filterColumns(columns) {
14763
14914
  return columns.filter((item) => (item.type !== 'action' && item.isVisible));
14764
14915
  }
14765
14916
  }
@@ -14768,4 +14919,4 @@ const AutoNumeric = require('@zeedhi/autonumeric/dist/autoNumeric');
14768
14919
  const packageContent = require('../package.json');
14769
14920
  VersionService.addPackageVersion(packageContent.name, packageContent.version);
14770
14921
 
14771
- export { Alert, AlertService, ApexChart, AutoNumeric, Badge, Breadcrumbs, Button, ButtonGroup, CSVReport, Card, Carousel, Checkbox, CheckboxMultiple, ChildNotFoundError, Chip, CodeEditor, Col, CollapseCard, Column, ColumnNotFoundError, Component, ComponentRender, Container, Currency, Dashboard, Date$1 as Date, DateRange, Dialog, DialogService, Divider, Dropdown, FileInput, Footer, Form, Frame, FramePage, Grid, GridColumn, GridColumnEditable, GridEditable, Header, Icon, Icons, Image, Increment, Input, Iterable, IterableColumnsButton, IterableColumnsButtonController, IterableComponentRender, IterablePageComponent, IterablePageInfo, IterablePageSize, IterablePagination, List, ListGroup, ListItem, Loading, LoadingService, Login, LoginButton, MasterDetail, Menu, MenuButton, MenuGroup, MenuLink, MenuSeparator, Modal, ModalCloseButton, ModalService, Month, Number$1 as Number, PDFReport, Password, Progress, Radio, RangeSlider, Report, Row, Search, Select, SelectMultiple, SelectTree, SelectTreeMultiple, SelectableList, SpeedDial, Steppers, SvgMap, Switch, Tab, Table, Tabs, Tag, Text, TextInput, Textarea, Time, Toggleable, Tooltip, Tree, TreeDataStructure, TreeGrid, TreeGridEditable, WatchURL, XLS2Report, XLS3Report, XLSReport, initTheme };
14922
+ export { Alert, AlertService, ApexChart, AutoNumeric, Badge, Breadcrumbs, Button, ButtonGroup, CSVReport, Card, Carousel, Checkbox, CheckboxMultiple, ChildNotFoundError, Chip, CodeEditor, Col, CollapseCard, Column, ColumnNotFoundError, Component, ComponentRender, Container, Currency, Dashboard, Date$1 as Date, DateRange, Dialog, DialogService, Divider, Dropdown, FileInput, Footer, Form, Frame, FramePage, Grid, GridColumn, GridColumnEditable, GridEditable, GroupedPDFFormatter, Header, Icon, Icons, Image, Increment, Input, InputFactory, Iterable, IterableColumnsButton, IterableColumnsButtonController, IterableComponentRender, IterablePageComponent, IterablePageInfo, IterablePageSize, IterablePagination, List, ListGroup, ListItem, Loading, LoadingService, Login, LoginButton, MasterDetail, Menu, MenuButton, MenuGroup, MenuLink, MenuSeparator, Modal, ModalCloseButton, ModalService, Month, Number$1 as Number, PDFReport, Password, Progress, Radio, RangeSlider, Report, Row, Search, Select, SelectMultiple, SelectTree, SelectTreeMultiple, SelectableList, SpeedDial, Steppers, SvgMap, Switch, Tab, Table, Tabs, Tag, Text, TextInput, Textarea, Time, Toggleable, Tooltip, Tree, TreeDataStructure, TreeGrid, TreeGridEditable, WatchURL, XLS2Report, XLS3Report, XLSReport, initTheme };