@zeedhi/common 1.51.0 → 1.54.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.
@@ -2324,7 +2324,12 @@
2324
2324
  * Removes viewport maximum-width size breakpoints.
2325
2325
  */
2326
2326
  this.fluid = true;
2327
+ /**
2328
+ * Define if the container is a scroll view
2329
+ */
2330
+ this.scrollView = false;
2327
2331
  this.fluid = this.getInitValue('fluid', props.fluid, this.fluid);
2332
+ this.scrollView = this.getInitValue('scrollView', props.scrollView, this.scrollView);
2328
2333
  this.fillHeight = this.getInitValue('fillHeight', props.fillHeight, this.fillHeight);
2329
2334
  this.height = this.getInitValue('height', props.height, this.height);
2330
2335
  this.maxHeight = this.getInitValue('maxHeight', props.maxHeight, this.maxHeight);
@@ -4804,6 +4809,23 @@
4804
4809
  }
4805
4810
  }
4806
4811
 
4812
+ class IterableController {
4813
+ constructor(iterable) {
4814
+ this.searchInValue = undefined;
4815
+ this.columns = iterable.columns;
4816
+ }
4817
+ get searchIn() {
4818
+ return this.searchInValue || this.columns.reduce((result, column) => {
4819
+ if (column.type !== 'action' && column.isVisible)
4820
+ result.push(column.name);
4821
+ return result;
4822
+ }, []);
4823
+ }
4824
+ set searchIn(value) {
4825
+ this.searchInValue = value;
4826
+ }
4827
+ }
4828
+
4807
4829
  /**
4808
4830
  * Base class for Iterable components.
4809
4831
  */
@@ -4839,16 +4861,14 @@
4839
4861
  */
4840
4862
  this.actionsApplied = {};
4841
4863
  this.columns = this.getColumns(props.columns || this.columns);
4842
- this.datasource = core.DatasourceFactory.factory(Object.assign(Object.assign({}, props.datasource), { searchIn: ((_a = props.datasource) === null || _a === void 0 ? void 0 : _a.searchIn) || this.getSearchColumns() }));
4864
+ this.createController();
4865
+ this.datasource = core.DatasourceFactory.factory(Object.assign(Object.assign({}, props.datasource), { searchIn: ((_a = props.datasource) === null || _a === void 0 ? void 0 : _a.searchIn) || `{{IterableController_${this.name}.searchIn}}` }));
4843
4866
  this.pageSizes = this.getInitValue('pageSizes', props.pageSizes, this.pageSizes);
4844
4867
  this.virtualScroll = this.getInitValue('virtualScroll', props.virtualScroll, this.virtualScroll);
4845
4868
  }
4846
- getSearchColumns() {
4847
- return this.columns.reduce((result, column) => {
4848
- if (column.type !== 'action')
4849
- result.push(column.name);
4850
- return result;
4851
- }, []);
4869
+ createController() {
4870
+ const controller = new IterableController(this);
4871
+ core.Loader.addController(`IterableController_${this.name}`, controller);
4852
4872
  }
4853
4873
  /**
4854
4874
  * Retrieves columns instances
@@ -5505,6 +5525,7 @@
5505
5525
  };
5506
5526
  this.newRowIdentifier = '__added_row';
5507
5527
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
5528
+ this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
5508
5529
  this.createAccessors();
5509
5530
  }
5510
5531
  onMounted(element) {
@@ -5557,10 +5578,10 @@
5557
5578
  * @param event DOM event
5558
5579
  * @param element DOM Element
5559
5580
  */
5560
- cellClick(row, column, event, element) {
5581
+ cellClick(row, column, event, element, canEdit = true) {
5561
5582
  if (this.editing)
5562
5583
  return;
5563
- if (column.editable) {
5584
+ if (column.editable && canEdit) {
5564
5585
  this.editing = true;
5565
5586
  this.preventRowClick = true;
5566
5587
  this.datasource.currentRow = row;
@@ -5909,6 +5930,9 @@
5909
5930
  throw e;
5910
5931
  }
5911
5932
  }
5933
+ callCanEditRow(row) {
5934
+ return !this.canEditRow || typeof this.canEditRow !== 'function' || this.canEditRow({ row, component: this });
5935
+ }
5912
5936
  }
5913
5937
 
5914
5938
  /**
@@ -10216,7 +10240,7 @@
10216
10240
  /**
10217
10241
  * Defines the format of a time displayed in picker. Available options are ampm and 24hr.
10218
10242
  */
10219
- this.timeFormat = core.Config.timeFormat || 'ampm';
10243
+ this.timeFormat = core.Config.timeFormat || 'ampm'; // change props to pickerFormat
10220
10244
  /**
10221
10245
  * Forces 100% width.
10222
10246
  */
@@ -10247,29 +10271,18 @@
10247
10271
  this.width = 290;
10248
10272
  this.formatterFn = core.FormatterParserProvider.getFormatter('ZdTime');
10249
10273
  this.parserFn = core.FormatterParserProvider.getParser('ZdTime');
10274
+ this.isoFormatValue = 'HH:mm';
10275
+ this.valueFormatInternal = core.Config.valueTimeFormat;
10276
+ this.displayFormatInternal = core.Config.displayTimeFormat;
10250
10277
  /**
10251
- * Map of the mask functions
10252
- */
10253
- this.maskFunctions = {
10254
- ampm: () => this.ampmMask(),
10255
- '24hr': (value) => this.fullTimeMask(value),
10256
- };
10257
- /**
10258
- * Format used in time value
10278
+ * Defines the time input format.
10259
10279
  */
10260
- this.valueFormat = core.Config.valueTimeFormat;
10261
- /**
10262
- * Format used to display the value
10263
- */
10264
- this.displayFormat = core.Config.displayTimeFormat;
10280
+ this.inputFormat = core.Config.timeInputFormat;
10265
10281
  /**
10266
10282
  * True when displayValue is valid
10267
10283
  */
10268
10284
  this.isDisplayValid = true;
10269
- /**
10270
- * Last invalid value passed to formatter
10271
- */
10272
- this.lastInvalid = '';
10285
+ this.timeError = false;
10273
10286
  this.allowedHours = this.getInitValue('allowedHours', props.allowedHours, this.allowedHours);
10274
10287
  this.allowedMinutes = this.getInitValue('allowedMinutes', props.allowedMinutes, this.allowedMinutes);
10275
10288
  this.allowedSeconds = this.getInitValue('allowedSeconds', props.allowedSeconds, this.allowedSeconds);
@@ -10283,40 +10296,40 @@
10283
10296
  this.useSeconds = this.getInitValue('useSeconds', props.useSeconds, this.useSeconds);
10284
10297
  this.width = this.getInitValue('width', props.width, this.width);
10285
10298
  this.autofill = this.getInitValue('autofill', props.autofill, this.autofill);
10286
- this.mask = this.getInitValue('mask', props.mask, this.getMask);
10287
10299
  this.timeValidation = this.timeValidation.bind(this);
10300
+ this.valueFormat = this.getInitValue('valueFormat', props.valueFormat, this.valueFormatInternal);
10301
+ this.displayFormat = this.getInitValue('displayFormat', props.displayFormat, this.displayFormatInternal);
10302
+ this.inputFormat = this.getInitValue('inputFormat', props.inputFormat, this.inputFormat);
10288
10303
  this.timeAllowedValidation = this.timeAllowedValidation.bind(this);
10289
10304
  this.rules.push(this.timeValidation, this.timeAllowedValidation);
10290
- this.valueFormat = this.getInitValue('valueFormat', props.valueFormat, this.valueFormat);
10291
- this.displayFormat = this.getInitValue('displayFormat', props.displayFormat, this.displayFormat);
10305
+ this.mask = this.getInitValue('mask', props.mask, undefined);
10292
10306
  this.createAccessors();
10293
- this.createFormatAccessors();
10294
- }
10295
- createFormatAccessors() {
10296
- if (!this.valueFormat) {
10297
- Object.defineProperty(this, 'valueFormat', {
10298
- get: () => this.defaultValueFmt,
10299
- set: (valueFormat) => {
10300
- delete this.valueFormat;
10301
- this.valueFormat = valueFormat;
10302
- },
10303
- });
10307
+ this.initialMask = this.getInitialMask();
10308
+ this.isSimpleDisplay = this.isSimpleFormat(this.displayFormat);
10309
+ }
10310
+ get displayFormat() {
10311
+ const commonsDisplay = ['hh:mm A', 'hh:mm:ss A', 'HH:mm:ss', 'HH:mm'];
10312
+ if (commonsDisplay.includes(this.displayFormatInternal)) {
10313
+ this.displayFormatInternal = this.defaultFormats[this.timeFormat];
10304
10314
  }
10305
- if (!this.displayFormat) {
10306
- Object.defineProperty(this, 'displayFormat', {
10307
- get: () => this.defaultDisplayFmt,
10308
- set: (displayFormat) => {
10309
- delete this.displayFormat;
10310
- this.displayFormat = displayFormat;
10311
- },
10312
- });
10315
+ return this.displayFormatInternal;
10316
+ }
10317
+ set displayFormat(value) {
10318
+ this.displayFormatInternal = value;
10319
+ }
10320
+ get valueFormat() {
10321
+ const commonsDisplay = ['hh:mm A', 'hh:mm:ss A', 'HH:mm:ss', 'HH:mm'];
10322
+ if (commonsDisplay.includes(this.valueFormatInternal)) {
10323
+ this.valueFormatInternal = this.defaultFormats['24hr'];
10313
10324
  }
10325
+ return this.valueFormatInternal;
10314
10326
  }
10315
- get defaultValueFmt() {
10316
- return this.defaultFormats['24hr'];
10327
+ set valueFormat(value) {
10328
+ this.valueFormatInternal = value;
10317
10329
  }
10318
- get defaultDisplayFmt() {
10319
- return this.defaultFormats[this.timeFormat];
10330
+ get isoFormat() {
10331
+ this.isoFormatValue = this.useSeconds ? 'HH:mm:ss' : 'HH:mm';
10332
+ return this.isoFormatValue;
10320
10333
  }
10321
10334
  get defaultFormats() {
10322
10335
  const seconds = this.useSeconds ? ':ss' : '';
@@ -10325,59 +10338,172 @@
10325
10338
  '24hr': `HH:mm${seconds}`,
10326
10339
  };
10327
10340
  }
10328
- ampmMask() {
10329
- const ampmValue = this.displayValue || '';
10330
- const hours = [/[0-1]/];
10331
- if (ampmValue[0] === '1') {
10332
- hours.push(/[0-2]/);
10341
+ getInitialMask() {
10342
+ if (isUndefined__default["default"](this.mask)) {
10343
+ this.mask = this.inputFormat && this.maskFormat(this.inputFormat);
10333
10344
  }
10334
- else if (ampmValue[0] === '0') {
10335
- hours.push(/[1-9]/);
10345
+ return this.mask;
10346
+ }
10347
+ formatter(value) { return this.formatterFn(value, this); }
10348
+ parser(value) { return this.parserFn(value, this); }
10349
+ /**
10350
+ * Triggered when date is clicked.
10351
+ * @param event
10352
+ * @param element
10353
+ */
10354
+ selectTime(time, event, element) {
10355
+ if (this.events.onSelectTime && typeof this.events.onSelectTime === 'function') {
10356
+ this.events.onSelectTime({
10357
+ time, event, element, component: this,
10358
+ });
10359
+ }
10360
+ }
10361
+ get displayValue() {
10362
+ return this.internalDisplayValue;
10363
+ }
10364
+ set displayValue(newValue) {
10365
+ this.timeError = false;
10366
+ this.internalDisplayValue = newValue;
10367
+ this.internalValue = this.parser(newValue);
10368
+ this.value = this.internalValue; // forces value accessor to be called if necessary
10369
+ }
10370
+ /**
10371
+ * Assign the updated mask to mask property
10372
+ */
10373
+ updateMask() {
10374
+ this.isSimpleDisplay = this.isSimpleFormat(this.displayFormat);
10375
+ this.mask = this.getUpdatedMask();
10376
+ return this.mask;
10377
+ }
10378
+ /**
10379
+ * Gets the updated masked, based on displayFormat if the initial mask is undefined
10380
+ */
10381
+ getUpdatedMask() {
10382
+ if (isUndefined__default["default"](this.initialMask)) {
10383
+ return this.maskFormat(this.displayFormat);
10384
+ }
10385
+ return this.mask;
10386
+ }
10387
+ maskFormat(format) {
10388
+ return format.replace(/[A-Za-z]/gi, '#');
10389
+ }
10390
+ setTimeValue(displayValue) {
10391
+ const lastValue = this.displayValue;
10392
+ if (this.isValidTime(displayValue, this.displayFormat)) {
10393
+ this.internalDisplayValue = displayValue;
10394
+ this.internalValue = this.parser(displayValue);
10395
+ this.timeError = false;
10396
+ if (lastValue !== this.displayValue)
10397
+ this.change(this.value);
10336
10398
  }
10337
10399
  else {
10338
- hours.push(/[0-9]/);
10400
+ if (!displayValue) {
10401
+ this.internalDisplayValue = displayValue;
10402
+ this.internalValue = null;
10403
+ if (lastValue !== this.displayValue)
10404
+ this.change(this.value);
10405
+ }
10406
+ this.timeError = !!displayValue;
10339
10407
  }
10340
- const minutes = [/[0-5]/, /[0-9]/];
10341
- const seconds = this.useSeconds ? [':', ...minutes] : [];
10342
- const ampm = /(A|P)/;
10343
- return [...hours, ':', ...minutes, ...seconds, ' ', ampm, 'M'];
10408
+ this.value = this.internalValue; // forces value accessor to be called if necessary
10344
10409
  }
10345
- fullTimeMask(value) {
10346
- const hours = [
10347
- /[0-2]/,
10348
- value[0] === '2' ? /[0-3]/ : /[0-9]/,
10349
- ];
10350
- const minutes = [/[0-5]/, /[0-9]/];
10351
- const seconds = this.useSeconds ? [':', ...minutes] : [];
10352
- return [...hours, ':', ...minutes, ...seconds];
10410
+ isValidTime(value, format, strict = true) {
10411
+ return core.dayjs(value, format, strict).isValid();
10353
10412
  }
10354
- getMask(value) {
10355
- return this.maskFunctions[this.timeFormat](value);
10413
+ get isoValue() {
10414
+ return this.formatISOTimeValue(this.value);
10415
+ }
10416
+ set isoValue(newValue) {
10417
+ const lastValue = this.value;
10418
+ this.timeError = false;
10419
+ this.value = this.parseISOTimeValue(newValue);
10420
+ if (lastValue !== this.value)
10421
+ this.change(this.value);
10422
+ }
10423
+ formatISOTimeValue(value) {
10424
+ if (value && this.isValidTime(value, this.valueFormat)) {
10425
+ return core.dayjs(value, this.valueFormat).format(this.isoFormat);
10426
+ }
10427
+ return '';
10428
+ }
10429
+ parseISOTimeValue(value) {
10430
+ if (value && this.isValidTime(value, this.valueFormat)) {
10431
+ return core.dayjs(value, this.isoFormat).format(this.valueFormat);
10432
+ }
10433
+ return null;
10356
10434
  }
10357
10435
  /**
10358
- * Checks if value is valid according to valueFormat and if displayValue
10359
- * is true
10360
- */
10361
- isFullyValid(value = this.value) {
10362
- return this.isValidTime(value) && this.isDisplayValid;
10436
+ * Checks if a time format is simple.
10437
+ * Simple time formats are the ones that consists only of 'HH', 'mm', 'mm' or 'YYYY', and mask delimiters
10438
+ * @param format The format to be checked
10439
+ * @returns true if it is simple, false otherwise
10440
+ */
10441
+ isSimpleFormat(format) {
10442
+ const simpleTokens = ['HH', 'mm', 'ss', 'hh', 'A', 'a', 'p', 'P'];
10443
+ // remove the simple tokens from the string
10444
+ const replaced = simpleTokens.reduce((result, token) => result.replace(token, ''), format);
10445
+ const chars = replaced.split('');
10446
+ return chars.length ? chars.every((char) => core.Mask.isMaskDelimiter(char)) : true;
10363
10447
  }
10364
- formatter(value) {
10365
- const eq = this.lastInvalid === value;
10366
- if (eq || !this.isFullyValid(value)) {
10367
- this.isDisplayValid = true;
10368
- this.lastInvalid = value;
10369
- return value;
10448
+ timeValidation() {
10449
+ if (this.isValidTime(this.displayValue, this.displayFormat) || !this.displayValue) {
10450
+ return true;
10370
10451
  }
10371
- return this.formatterFn(value, this);
10452
+ return core.I18n.translate('VALIDATION_INVALID_TIME');
10372
10453
  }
10373
- parser(value) {
10374
- const parsed = this.parserFn(value, this);
10375
- this.isDisplayValid = value === null || value === '' || this.isValidTime(value, this.displayFormat);
10376
- return parsed;
10454
+ timeAllowedValidation() {
10455
+ return !this.displayValue
10456
+ || (this.isValidTime(this.displayValue, this.displayFormat)
10457
+ && this.isTimeAllowed())
10458
+ || core.I18n.translate('VALIDATION_TIME_NOT_ALLOWED');
10377
10459
  }
10378
- isValidTime(value, format = this.valueFormat) {
10379
- return core.dayjs(value, format, true).isValid();
10460
+ click(event, element) {
10461
+ const clickEvent = event || new MouseEvent('click');
10462
+ super.click(clickEvent, element);
10463
+ if (!clickEvent.defaultPrevented) {
10464
+ this.showTimePicker = !this.showTimePicker;
10465
+ }
10466
+ }
10467
+ blur(event, element) {
10468
+ this.removeTimeMask();
10469
+ this.setTimeValue(this.formatter(this.value));
10470
+ super.blur(event, element);
10471
+ this.showTimePicker = false;
10472
+ }
10473
+ focus(event, element) {
10474
+ this.addTimeMask();
10475
+ super.focus(event, element);
10476
+ }
10477
+ /**
10478
+ * Add date mask
10479
+ */
10480
+ addTimeMask() {
10481
+ if (!this.value)
10482
+ return;
10483
+ this.mask = this.initialMask;
10484
+ this.internalDisplayValue = core.dayjs(this.value, this.valueFormat).format(this.inputFormat || this.displayFormat);
10485
+ }
10486
+ /**
10487
+ * Removes the component mask if value is valid
10488
+ */
10489
+ removeTimeMask() {
10490
+ if (isUndefined__default["default"](this.initialMask) || !this.value || this.timeError
10491
+ || !this.isValidTime(this.value, this.valueFormat)) {
10492
+ return;
10493
+ }
10494
+ this.mask = '';
10495
+ }
10496
+ /**
10497
+ * Checks if value is valid according to valueFormat and if displayValue
10498
+ * is true
10499
+ */
10500
+ isFullyValid(value = this.value) {
10501
+ return this.isValidTime(value, this.valueFormat, true) && this.isDisplayValid;
10380
10502
  }
10503
+ /**
10504
+ * Last invalid value passed to formatter
10505
+ */
10506
+ // private lastInvalid: string = '';
10381
10507
  isTimeAllowed(value = this.value) {
10382
10508
  return this.isSameOrAfterMin(value) && this.isSameOrBeforeMax(value)
10383
10509
  && this.isHourAllowed(value) && this.isMinuteAllowed(value)
@@ -10413,49 +10539,54 @@
10413
10539
  const second = core.dayjs(value, this.valueFormat).second();
10414
10540
  return this.allowedSeconds.includes(second);
10415
10541
  }
10416
- timeValidation() {
10417
- return !this.displayValue
10418
- || this.isValidTime(this.displayValue, this.displayFormat)
10419
- || core.I18n.translate('VALIDATION_INVALID_TIME');
10420
- }
10421
- timeAllowedValidation() {
10422
- return !this.displayValue
10423
- || (this.isValidTime(this.displayValue, this.displayFormat)
10424
- && this.isTimeAllowed())
10425
- || core.I18n.translate('VALIDATION_TIME_NOT_ALLOWED');
10426
- }
10427
- click(event) {
10428
- this.callEvent('click', {
10429
- event: (event || new MouseEvent('click')),
10430
- component: this,
10431
- });
10432
- if (!(event === null || event === void 0 ? void 0 : event.defaultPrevented)) {
10433
- this.showTimePicker = !this.showTimePicker;
10434
- }
10435
- }
10436
10542
  clear() {
10437
10543
  this.value = null;
10438
10544
  this.change(this.value);
10439
10545
  }
10440
10546
  }
10441
- core.FormatterParserProvider.registerFormatter('ZdTime', (value, { displayFormat = core.Config.displayFormat, valueFormat = core.Config.valueTimeFormat, } = {}) => {
10547
+ core.FormatterParserProvider.registerFormatter('ZdTime', (value, { valueFormat = core.Config.valueTimeFormat, displayFormat = core.Config.displayTimeFormat, inputFormat = core.Config.timeInputFormat, mask = '', initialMask, isSimpleDisplay = false, } = {}) => {
10442
10548
  if (!value) {
10443
10549
  return '';
10444
10550
  }
10445
- if (core.dayjs(value, valueFormat, true).isValid()) {
10446
- return core.dayjs(value, valueFormat).format(displayFormat);
10551
+ const isTimeValid = core.dayjs(value, valueFormat, true).isValid();
10552
+ if (!isTimeValid) {
10553
+ return value;
10447
10554
  }
10448
- return value;
10555
+ if (mask && initialMask) {
10556
+ if (inputFormat) {
10557
+ return core.dayjs(value, valueFormat).format(inputFormat);
10558
+ }
10559
+ let valueToUnmask = value;
10560
+ if (isSimpleDisplay) {
10561
+ valueToUnmask = core.dayjs(value, valueFormat).format(displayFormat);
10562
+ }
10563
+ const unmasked = core.Mask.getValueWithoutMask(valueToUnmask);
10564
+ const masked = core.Mask.getValueWithMask(unmasked, mask);
10565
+ return masked;
10566
+ }
10567
+ return core.dayjs(value, valueFormat).format(displayFormat);
10449
10568
  });
10450
- core.FormatterParserProvider.registerParser('ZdTime', (value, { displayFormat = core.Config.displayFormat, valueFormat = core.Config.valueTimeFormat, } = {}) => {
10569
+ core.FormatterParserProvider.registerParser('ZdTime', (value, { displayFormat = core.Config.displayTimeFormat, valueFormat = core.Config.valueTimeFormat, mask = '', initialMask, } = {}) => {
10451
10570
  if (!value) {
10452
10571
  return null;
10453
10572
  }
10454
- const uppecaseValue = value.toUpperCase();
10455
- if (core.dayjs(uppecaseValue, displayFormat, true).isValid()) {
10456
- return core.dayjs(uppecaseValue, displayFormat).format(valueFormat);
10573
+ if (core.dayjs(value, displayFormat, true).isValid()) {
10574
+ return core.dayjs(value, displayFormat).format(valueFormat);
10575
+ }
10576
+ if (mask && core.Mask.checkMask(value, mask)) {
10577
+ const unmasked = core.Mask.getValueWithoutMask(value);
10578
+ let masked;
10579
+ if (!initialMask) {
10580
+ const displayFmtMask = displayFormat.replace(/[A-Za-z]/gi, '#');
10581
+ masked = core.Mask.getValueWithMask(unmasked, displayFmtMask);
10582
+ }
10583
+ const timeFmtMask = valueFormat.replace(/[A-Za-z]/gi, '#');
10584
+ masked = core.Mask.getValueWithMask(unmasked, timeFmtMask);
10585
+ if (core.dayjs(masked, valueFormat, true).format(valueFormat) === masked) {
10586
+ return masked;
10587
+ }
10457
10588
  }
10458
- return uppecaseValue;
10589
+ return value;
10459
10590
  });
10460
10591
 
10461
10592
  /**
@@ -10597,6 +10728,7 @@
10597
10728
  this.checkedField = this.getInitValue('checkedField', props.checkedField, this.checkedField);
10598
10729
  this.openLevelOnLoad = this.getInitValue('openLevelOnLoad', props.openLevelOnLoad, this.openLevelOnLoad);
10599
10730
  this.checkbox = this.getInitValue('checkbox', props.checkbox, this.checkbox);
10731
+ this.disableCheckbox = this.getInitValue('disableCheckbox', props.disableCheckbox, this.disableCheckbox);
10600
10732
  this.afterTitleSlot = props.afterTitleSlot || this.afterTitleSlot;
10601
10733
  this.toolbarSlot = props.toolbarSlot || this.toolbarSlot;
10602
10734
  this.titleSlot = props.titleSlot || this.titleSlot;
@@ -10832,16 +10964,13 @@
10832
10964
  const compName = component.name;
10833
10965
  const instanceName = `${compName}_${nodePath}`;
10834
10966
  const path = parentPath ? `${parentPath}.${compName}` : compName;
10835
- const newComponent = merge__default["default"]({}, component, (_a = this.appliedConditions[nodePath]) === null || _a === void 0 ? void 0 : _a[path]);
10967
+ const newInstances = core.Metadata.getInstances(instanceName);
10968
+ const newInstance = newInstances[0];
10969
+ const appliedConditions = (_a = this.appliedConditions[nodePath]) === null || _a === void 0 ? void 0 : _a[path];
10970
+ const newComponent = merge__default["default"]({}, component, newInstance, appliedConditions);
10836
10971
  const newChildren = this.getSlotComponent(newComponent.children || [], node, path);
10837
10972
  newComponent.name = instanceName;
10838
10973
  newComponent.children = newChildren;
10839
- try {
10840
- core.Metadata.updateInstance(instanceName, newComponent);
10841
- }
10842
- catch (e) {
10843
- // do nothing
10844
- }
10845
10974
  newComponents.push(newComponent);
10846
10975
  });
10847
10976
  return newComponents;
@@ -10903,6 +11032,10 @@
10903
11032
  return this.searchPath(currentNode.children || [], path.slice(1));
10904
11033
  return currentNode;
10905
11034
  }
11035
+ callDisableCheckbox(node) {
11036
+ return !!this.disableCheckbox && typeof this.disableCheckbox === 'function'
11037
+ && this.disableCheckbox({ node, component: this });
11038
+ }
10906
11039
  }
10907
11040
 
10908
11041
  /**
@@ -11049,6 +11182,8 @@
11049
11182
  const rows = [row, ...this.treeDataStructure.getChildren(row)];
11050
11183
  if (isSelected) {
11051
11184
  this.selectedRows = Array.from(new Set(this.selectedRows.concat(rows))); // remove duplicates
11185
+ // check if all the children of the parent are selected.
11186
+ this.selectParents(rows, row);
11052
11187
  }
11053
11188
  else {
11054
11189
  rows.forEach((item) => {
@@ -11056,6 +11191,31 @@
11056
11191
  if (index > -1)
11057
11192
  this.selectedRows.splice(index, 1);
11058
11193
  });
11194
+ this.unselectParents(row);
11195
+ }
11196
+ }
11197
+ selectParents(rows, row) {
11198
+ if (row[this.parentField]) {
11199
+ const parentRow = this.treeDataStructure.getRowData(row).tree__parent;
11200
+ const every = this.treeDataStructure.getChildren(parentRow).every((item) => {
11201
+ const index = this.treeDataStructure.findDataIndex(this.selectedRows, item[this.datasource.uniqueKey]);
11202
+ if (index > -1)
11203
+ return true;
11204
+ return false;
11205
+ });
11206
+ if (every)
11207
+ rows.push(parentRow);
11208
+ this.selectedRows = Array.from(new Set(this.selectedRows.concat(rows))); // remove duplicates
11209
+ this.selectParents(rows, parentRow);
11210
+ }
11211
+ }
11212
+ unselectParents(row) {
11213
+ if (row[this.parentField]) {
11214
+ const index = this.treeDataStructure.findDataIndex(this.selectedRows, row[this.parentField]);
11215
+ if (index > -1)
11216
+ this.selectedRows.splice(index, 1);
11217
+ const parentRow = this.treeDataStructure.getRowData(row).tree__parent;
11218
+ this.unselectParents(parentRow);
11059
11219
  }
11060
11220
  }
11061
11221
  }
@@ -11090,6 +11250,7 @@
11090
11250
  },
11091
11251
  };
11092
11252
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
11253
+ this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
11093
11254
  this.noDataSlot = this.changeDefaultSlotNames(this.noDataSlot);
11094
11255
  this.createAccessors();
11095
11256
  }
@@ -11143,10 +11304,10 @@
11143
11304
  * @param event DOM event
11144
11305
  * @param element DOM Element
11145
11306
  */
11146
- cellClick(row, column, event, element) {
11307
+ cellClick(row, column, event, element, canEdit = true) {
11147
11308
  if (this.editing)
11148
11309
  return;
11149
- if (column.editable) {
11310
+ if (column.editable && canEdit) {
11150
11311
  this.editing = true;
11151
11312
  this.preventRowClick = true;
11152
11313
  this.datasource.currentRow = row;
@@ -11463,6 +11624,9 @@
11463
11624
  throw e;
11464
11625
  }
11465
11626
  }
11627
+ callCanEditRow(row) {
11628
+ return !this.canEditRow || typeof this.canEditRow !== 'function' || this.canEditRow({ row, component: this });
11629
+ }
11466
11630
  }
11467
11631
 
11468
11632
  class Icons {
@@ -11906,9 +12070,9 @@
11906
12070
  };
11907
12071
  this.colunmXLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
11908
12072
  }
11909
- buildColumns(columns) {
12073
+ getColumnsWidth(columns) {
11910
12074
  const widths = {};
11911
- let totalWidth;
12075
+ let totalWidth = 0;
11912
12076
  try {
11913
12077
  totalWidth = columns.reduce((sum, col) => {
11914
12078
  widths[col.name] = col.getWidth();
@@ -11920,6 +12084,10 @@
11920
12084
  throw e;
11921
12085
  }
11922
12086
  }
12087
+ return { widths, totalWidth };
12088
+ }
12089
+ buildColumns(columns) {
12090
+ const { widths, totalWidth } = this.getColumnsWidth(columns);
11923
12091
  return columns.reduce((result, col, index) => {
11924
12092
  let size;
11925
12093
  if (!totalWidth) {
@@ -11932,58 +12100,12 @@
11932
12100
  align: col.align || 'left',
11933
12101
  description: col.label,
11934
12102
  sequence: index,
11935
- format: this.getFormatOfColumn(col),
11936
12103
  size: `${size}%`,
11937
12104
  xlsType: col.xlsType,
11938
12105
  };
11939
12106
  return Object.assign(Object.assign({}, result), { [col.name]: row });
11940
12107
  }, {});
11941
12108
  }
11942
- isNumberComponent(component) {
11943
- return ['ZdNumber', 'ZdCurrency', 'ZdIncrement'].indexOf(component) !== -1;
11944
- }
11945
- checkAccessor(value) {
11946
- if (core.Accessor.isAccessorDefinition(value)) {
11947
- const [controller, accessor] = core.Accessor.getAccessor(value);
11948
- return core.Loader.getInstance(controller)[accessor];
11949
- }
11950
- return value;
11951
- }
11952
- getFormatOfColumn(column) {
11953
- let format;
11954
- let { mask } = column;
11955
- if (mask) {
11956
- format = {
11957
- type: 'fix',
11958
- params: {
11959
- mask,
11960
- },
11961
- };
11962
- }
11963
- else if (column.componentProps && Object.keys(column.componentProps).length) {
11964
- const { component } = column.componentProps;
11965
- if (this.isNumberComponent(component)) {
11966
- format = { type: 'float' };
11967
- mask = this.checkAccessor(column.componentProps.mask);
11968
- if (mask) {
11969
- format.params = {};
11970
- if (mask.currencySymbol) {
11971
- format.type = 'currency';
11972
- format.symbol = mask.currencySymbol;
11973
- format.decimal = mask.decimalCharacter;
11974
- format.thousands = mask.digitGroupSeparator;
11975
- format.precision = mask.decimalPlaces;
11976
- }
11977
- else {
11978
- format.params.decimal = mask.decimalCharacter;
11979
- format.params.thousands = mask.digitGroupSeparator;
11980
- format.params.precision = mask.decimalPlaces;
11981
- }
11982
- }
11983
- }
11984
- }
11985
- return format;
11986
- }
11987
12109
  buildFilter(filter) {
11988
12110
  return Object.keys(filter).map((key) => ({
11989
12111
  label: key,
@@ -12051,6 +12173,72 @@
12051
12173
  buildDataset(data) {
12052
12174
  return JSON.stringify(data);
12053
12175
  }
12176
+ buildColumns(columns) {
12177
+ const { widths, totalWidth } = this.getColumnsWidth(columns);
12178
+ return columns.reduce((result, col, index) => {
12179
+ let size;
12180
+ if (!totalWidth) {
12181
+ size = Math.floor(100 / columns.length);
12182
+ }
12183
+ else {
12184
+ size = Math.floor((widths[col.name] * 100) / totalWidth);
12185
+ }
12186
+ const row = {
12187
+ align: col.align || 'left',
12188
+ description: col.label,
12189
+ sequence: index,
12190
+ format: this.getFormatOfColumn(col),
12191
+ size: `${size}%`,
12192
+ xlsType: col.xlsType,
12193
+ };
12194
+ return Object.assign(Object.assign({}, result), { [col.name]: row });
12195
+ }, {});
12196
+ }
12197
+ getFormatOfColumn(column) {
12198
+ let format;
12199
+ let { mask } = column;
12200
+ if (mask) {
12201
+ format = {
12202
+ type: 'fix',
12203
+ params: {
12204
+ mask,
12205
+ },
12206
+ };
12207
+ }
12208
+ else if (column.componentProps && Object.keys(column.componentProps).length) {
12209
+ const { component } = column.componentProps;
12210
+ if (this.isNumberComponent(component)) {
12211
+ format = { type: 'float' };
12212
+ mask = this.checkAccessor(column.componentProps.mask);
12213
+ if (mask) {
12214
+ format.params = {};
12215
+ if (mask.currencySymbol) {
12216
+ format.type = 'currency';
12217
+ format.symbol = mask.currencySymbol;
12218
+ format.decimal = mask.decimalCharacter;
12219
+ format.thousands = mask.digitGroupSeparator;
12220
+ format.precision = mask.decimalPlaces;
12221
+ }
12222
+ else {
12223
+ format.params.decimal = mask.decimalCharacter;
12224
+ format.params.thousands = mask.digitGroupSeparator;
12225
+ format.params.precision = mask.decimalPlaces;
12226
+ }
12227
+ }
12228
+ }
12229
+ }
12230
+ return format;
12231
+ }
12232
+ isNumberComponent(component) {
12233
+ return ['ZdNumber', 'ZdCurrency', 'ZdIncrement'].indexOf(component) !== -1;
12234
+ }
12235
+ checkAccessor(value) {
12236
+ if (core.Accessor.isAccessorDefinition(value)) {
12237
+ const [controller, accessor] = core.Accessor.getAccessor(value);
12238
+ return core.Loader.getInstance(controller)[accessor];
12239
+ }
12240
+ return value;
12241
+ }
12054
12242
  buildMetadata(name, title, columns, filter, portrait = true) {
12055
12243
  return __awaiter(this, void 0, void 0, function* () {
12056
12244
  const builtCols = this.buildColumns(columns);
@@ -12132,6 +12320,7 @@
12132
12320
  }
12133
12321
  }
12134
12322
 
12323
+ // XLS without groups (formatXLS = 'F3')
12135
12324
  class XLSReport extends BaseReport {
12136
12325
  constructor() {
12137
12326
  super(...arguments);
@@ -12178,13 +12367,14 @@
12178
12367
  columns: builtCols,
12179
12368
  filter: builtFilters,
12180
12369
  reportXLS: true,
12370
+ formatXLS: 'F3',
12181
12371
  xlsMergedCell: [],
12182
12372
  };
12183
12373
  return Promise.resolve(JSON.stringify(metadataObj));
12184
12374
  }
12185
12375
  }
12186
12376
 
12187
- // XLS with groups
12377
+ // XLS with groups (formatXLS = 'F1')
12188
12378
  class XLS2Report extends BaseReport {
12189
12379
  constructor() {
12190
12380
  super(...arguments);
@@ -12222,6 +12412,7 @@
12222
12412
  columns: builtCols,
12223
12413
  filter: builtFilters,
12224
12414
  reportXLS: true,
12415
+ formatXLS: 'F1',
12225
12416
  xlsMergedCell: [],
12226
12417
  };
12227
12418
  return Promise.resolve(JSON.stringify(metadataObj));
@@ -12380,7 +12571,7 @@
12380
12571
  }
12381
12572
  }
12382
12573
 
12383
- // Grid mirror (with groups)
12574
+ // Grid mirror (with groups) (formatXLS = 'F2')
12384
12575
  class XLS3Report extends BaseReport {
12385
12576
  constructor() {
12386
12577
  super(...arguments);
@@ -12418,6 +12609,7 @@
12418
12609
  columns: builtCols,
12419
12610
  filter: builtFilters,
12420
12611
  reportXLS: true,
12612
+ formatXLS: 'F2',
12421
12613
  xlsMergedCell: [],
12422
12614
  };
12423
12615
  return Promise.resolve(JSON.stringify(metadataObj));
@@ -12622,7 +12814,7 @@
12622
12814
  const { route } = reportType;
12623
12815
  const { name, columns, datasource } = this.iterable;
12624
12816
  const { groupedData } = Object.assign({}, this.iterable);
12625
- const formattedColumns = this.removeActionColumns(columns);
12817
+ const formattedColumns = this.removeColumns(columns);
12626
12818
  const metadataObj = yield reportType.buildMetadata(name, this.title, formattedColumns, datasource.filter, portrait);
12627
12819
  let dataset;
12628
12820
  if ((reportType instanceof XLS2Report || reportType instanceof XLS3Report) && groupedData) {
@@ -12664,8 +12856,8 @@
12664
12856
  return new URL(reportFile, this.fileEndPoint).href;
12665
12857
  });
12666
12858
  }
12667
- removeActionColumns(columns) {
12668
- return columns.filter((item) => item.type !== 'action');
12859
+ removeColumns(columns) {
12860
+ return columns.filter((item) => (item.type !== 'action' && item.isVisible));
12669
12861
  }
12670
12862
  }
12671
12863