@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.
@@ -2317,7 +2317,12 @@ class Container extends ComponentRender {
2317
2317
  * Removes viewport maximum-width size breakpoints.
2318
2318
  */
2319
2319
  this.fluid = true;
2320
+ /**
2321
+ * Define if the container is a scroll view
2322
+ */
2323
+ this.scrollView = false;
2320
2324
  this.fluid = this.getInitValue('fluid', props.fluid, this.fluid);
2325
+ this.scrollView = this.getInitValue('scrollView', props.scrollView, this.scrollView);
2321
2326
  this.fillHeight = this.getInitValue('fillHeight', props.fillHeight, this.fillHeight);
2322
2327
  this.height = this.getInitValue('height', props.height, this.height);
2323
2328
  this.maxHeight = this.getInitValue('maxHeight', props.maxHeight, this.maxHeight);
@@ -4797,6 +4802,23 @@ class ColumnNotFoundError extends Error {
4797
4802
  }
4798
4803
  }
4799
4804
 
4805
+ class IterableController {
4806
+ constructor(iterable) {
4807
+ this.searchInValue = undefined;
4808
+ this.columns = iterable.columns;
4809
+ }
4810
+ get searchIn() {
4811
+ return this.searchInValue || this.columns.reduce((result, column) => {
4812
+ if (column.type !== 'action' && column.isVisible)
4813
+ result.push(column.name);
4814
+ return result;
4815
+ }, []);
4816
+ }
4817
+ set searchIn(value) {
4818
+ this.searchInValue = value;
4819
+ }
4820
+ }
4821
+
4800
4822
  /**
4801
4823
  * Base class for Iterable components.
4802
4824
  */
@@ -4832,16 +4854,14 @@ class Iterable extends ComponentRender {
4832
4854
  */
4833
4855
  this.actionsApplied = {};
4834
4856
  this.columns = this.getColumns(props.columns || this.columns);
4835
- this.datasource = DatasourceFactory.factory(Object.assign(Object.assign({}, props.datasource), { searchIn: ((_a = props.datasource) === null || _a === void 0 ? void 0 : _a.searchIn) || this.getSearchColumns() }));
4857
+ this.createController();
4858
+ this.datasource = DatasourceFactory.factory(Object.assign(Object.assign({}, props.datasource), { searchIn: ((_a = props.datasource) === null || _a === void 0 ? void 0 : _a.searchIn) || `{{IterableController_${this.name}.searchIn}}` }));
4836
4859
  this.pageSizes = this.getInitValue('pageSizes', props.pageSizes, this.pageSizes);
4837
4860
  this.virtualScroll = this.getInitValue('virtualScroll', props.virtualScroll, this.virtualScroll);
4838
4861
  }
4839
- getSearchColumns() {
4840
- return this.columns.reduce((result, column) => {
4841
- if (column.type !== 'action')
4842
- result.push(column.name);
4843
- return result;
4844
- }, []);
4862
+ createController() {
4863
+ const controller = new IterableController(this);
4864
+ Loader.addController(`IterableController_${this.name}`, controller);
4845
4865
  }
4846
4866
  /**
4847
4867
  * Retrieves columns instances
@@ -5498,6 +5518,7 @@ class GridEditable extends Grid {
5498
5518
  };
5499
5519
  this.newRowIdentifier = '__added_row';
5500
5520
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
5521
+ this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
5501
5522
  this.createAccessors();
5502
5523
  }
5503
5524
  onMounted(element) {
@@ -5550,10 +5571,10 @@ class GridEditable extends Grid {
5550
5571
  * @param event DOM event
5551
5572
  * @param element DOM Element
5552
5573
  */
5553
- cellClick(row, column, event, element) {
5574
+ cellClick(row, column, event, element, canEdit = true) {
5554
5575
  if (this.editing)
5555
5576
  return;
5556
- if (column.editable) {
5577
+ if (column.editable && canEdit) {
5557
5578
  this.editing = true;
5558
5579
  this.preventRowClick = true;
5559
5580
  this.datasource.currentRow = row;
@@ -5902,6 +5923,9 @@ class GridEditable extends Grid {
5902
5923
  throw e;
5903
5924
  }
5904
5925
  }
5926
+ callCanEditRow(row) {
5927
+ return !this.canEditRow || typeof this.canEditRow !== 'function' || this.canEditRow({ row, component: this });
5928
+ }
5905
5929
  }
5906
5930
 
5907
5931
  /**
@@ -10209,7 +10233,7 @@ class Time extends TextInput {
10209
10233
  /**
10210
10234
  * Defines the format of a time displayed in picker. Available options are ampm and 24hr.
10211
10235
  */
10212
- this.timeFormat = Config.timeFormat || 'ampm';
10236
+ this.timeFormat = Config.timeFormat || 'ampm'; // change props to pickerFormat
10213
10237
  /**
10214
10238
  * Forces 100% width.
10215
10239
  */
@@ -10240,29 +10264,18 @@ class Time extends TextInput {
10240
10264
  this.width = 290;
10241
10265
  this.formatterFn = FormatterParserProvider.getFormatter('ZdTime');
10242
10266
  this.parserFn = FormatterParserProvider.getParser('ZdTime');
10267
+ this.isoFormatValue = 'HH:mm';
10268
+ this.valueFormatInternal = Config.valueTimeFormat;
10269
+ this.displayFormatInternal = Config.displayTimeFormat;
10243
10270
  /**
10244
- * Map of the mask functions
10245
- */
10246
- this.maskFunctions = {
10247
- ampm: () => this.ampmMask(),
10248
- '24hr': (value) => this.fullTimeMask(value),
10249
- };
10250
- /**
10251
- * Format used in time value
10271
+ * Defines the time input format.
10252
10272
  */
10253
- this.valueFormat = Config.valueTimeFormat;
10254
- /**
10255
- * Format used to display the value
10256
- */
10257
- this.displayFormat = Config.displayTimeFormat;
10273
+ this.inputFormat = Config.timeInputFormat;
10258
10274
  /**
10259
10275
  * True when displayValue is valid
10260
10276
  */
10261
10277
  this.isDisplayValid = true;
10262
- /**
10263
- * Last invalid value passed to formatter
10264
- */
10265
- this.lastInvalid = '';
10278
+ this.timeError = false;
10266
10279
  this.allowedHours = this.getInitValue('allowedHours', props.allowedHours, this.allowedHours);
10267
10280
  this.allowedMinutes = this.getInitValue('allowedMinutes', props.allowedMinutes, this.allowedMinutes);
10268
10281
  this.allowedSeconds = this.getInitValue('allowedSeconds', props.allowedSeconds, this.allowedSeconds);
@@ -10276,40 +10289,40 @@ class Time extends TextInput {
10276
10289
  this.useSeconds = this.getInitValue('useSeconds', props.useSeconds, this.useSeconds);
10277
10290
  this.width = this.getInitValue('width', props.width, this.width);
10278
10291
  this.autofill = this.getInitValue('autofill', props.autofill, this.autofill);
10279
- this.mask = this.getInitValue('mask', props.mask, this.getMask);
10280
10292
  this.timeValidation = this.timeValidation.bind(this);
10293
+ this.valueFormat = this.getInitValue('valueFormat', props.valueFormat, this.valueFormatInternal);
10294
+ this.displayFormat = this.getInitValue('displayFormat', props.displayFormat, this.displayFormatInternal);
10295
+ this.inputFormat = this.getInitValue('inputFormat', props.inputFormat, this.inputFormat);
10281
10296
  this.timeAllowedValidation = this.timeAllowedValidation.bind(this);
10282
10297
  this.rules.push(this.timeValidation, this.timeAllowedValidation);
10283
- this.valueFormat = this.getInitValue('valueFormat', props.valueFormat, this.valueFormat);
10284
- this.displayFormat = this.getInitValue('displayFormat', props.displayFormat, this.displayFormat);
10298
+ this.mask = this.getInitValue('mask', props.mask, undefined);
10285
10299
  this.createAccessors();
10286
- this.createFormatAccessors();
10287
- }
10288
- createFormatAccessors() {
10289
- if (!this.valueFormat) {
10290
- Object.defineProperty(this, 'valueFormat', {
10291
- get: () => this.defaultValueFmt,
10292
- set: (valueFormat) => {
10293
- delete this.valueFormat;
10294
- this.valueFormat = valueFormat;
10295
- },
10296
- });
10300
+ this.initialMask = this.getInitialMask();
10301
+ this.isSimpleDisplay = this.isSimpleFormat(this.displayFormat);
10302
+ }
10303
+ get displayFormat() {
10304
+ const commonsDisplay = ['hh:mm A', 'hh:mm:ss A', 'HH:mm:ss', 'HH:mm'];
10305
+ if (commonsDisplay.includes(this.displayFormatInternal)) {
10306
+ this.displayFormatInternal = this.defaultFormats[this.timeFormat];
10297
10307
  }
10298
- if (!this.displayFormat) {
10299
- Object.defineProperty(this, 'displayFormat', {
10300
- get: () => this.defaultDisplayFmt,
10301
- set: (displayFormat) => {
10302
- delete this.displayFormat;
10303
- this.displayFormat = displayFormat;
10304
- },
10305
- });
10308
+ return this.displayFormatInternal;
10309
+ }
10310
+ set displayFormat(value) {
10311
+ this.displayFormatInternal = value;
10312
+ }
10313
+ get valueFormat() {
10314
+ const commonsDisplay = ['hh:mm A', 'hh:mm:ss A', 'HH:mm:ss', 'HH:mm'];
10315
+ if (commonsDisplay.includes(this.valueFormatInternal)) {
10316
+ this.valueFormatInternal = this.defaultFormats['24hr'];
10306
10317
  }
10318
+ return this.valueFormatInternal;
10307
10319
  }
10308
- get defaultValueFmt() {
10309
- return this.defaultFormats['24hr'];
10320
+ set valueFormat(value) {
10321
+ this.valueFormatInternal = value;
10310
10322
  }
10311
- get defaultDisplayFmt() {
10312
- return this.defaultFormats[this.timeFormat];
10323
+ get isoFormat() {
10324
+ this.isoFormatValue = this.useSeconds ? 'HH:mm:ss' : 'HH:mm';
10325
+ return this.isoFormatValue;
10313
10326
  }
10314
10327
  get defaultFormats() {
10315
10328
  const seconds = this.useSeconds ? ':ss' : '';
@@ -10318,59 +10331,172 @@ class Time extends TextInput {
10318
10331
  '24hr': `HH:mm${seconds}`,
10319
10332
  };
10320
10333
  }
10321
- ampmMask() {
10322
- const ampmValue = this.displayValue || '';
10323
- const hours = [/[0-1]/];
10324
- if (ampmValue[0] === '1') {
10325
- hours.push(/[0-2]/);
10334
+ getInitialMask() {
10335
+ if (isUndefined(this.mask)) {
10336
+ this.mask = this.inputFormat && this.maskFormat(this.inputFormat);
10326
10337
  }
10327
- else if (ampmValue[0] === '0') {
10328
- hours.push(/[1-9]/);
10338
+ return this.mask;
10339
+ }
10340
+ formatter(value) { return this.formatterFn(value, this); }
10341
+ parser(value) { return this.parserFn(value, this); }
10342
+ /**
10343
+ * Triggered when date is clicked.
10344
+ * @param event
10345
+ * @param element
10346
+ */
10347
+ selectTime(time, event, element) {
10348
+ if (this.events.onSelectTime && typeof this.events.onSelectTime === 'function') {
10349
+ this.events.onSelectTime({
10350
+ time, event, element, component: this,
10351
+ });
10352
+ }
10353
+ }
10354
+ get displayValue() {
10355
+ return this.internalDisplayValue;
10356
+ }
10357
+ set displayValue(newValue) {
10358
+ this.timeError = false;
10359
+ this.internalDisplayValue = newValue;
10360
+ this.internalValue = this.parser(newValue);
10361
+ this.value = this.internalValue; // forces value accessor to be called if necessary
10362
+ }
10363
+ /**
10364
+ * Assign the updated mask to mask property
10365
+ */
10366
+ updateMask() {
10367
+ this.isSimpleDisplay = this.isSimpleFormat(this.displayFormat);
10368
+ this.mask = this.getUpdatedMask();
10369
+ return this.mask;
10370
+ }
10371
+ /**
10372
+ * Gets the updated masked, based on displayFormat if the initial mask is undefined
10373
+ */
10374
+ getUpdatedMask() {
10375
+ if (isUndefined(this.initialMask)) {
10376
+ return this.maskFormat(this.displayFormat);
10377
+ }
10378
+ return this.mask;
10379
+ }
10380
+ maskFormat(format) {
10381
+ return format.replace(/[A-Za-z]/gi, '#');
10382
+ }
10383
+ setTimeValue(displayValue) {
10384
+ const lastValue = this.displayValue;
10385
+ if (this.isValidTime(displayValue, this.displayFormat)) {
10386
+ this.internalDisplayValue = displayValue;
10387
+ this.internalValue = this.parser(displayValue);
10388
+ this.timeError = false;
10389
+ if (lastValue !== this.displayValue)
10390
+ this.change(this.value);
10329
10391
  }
10330
10392
  else {
10331
- hours.push(/[0-9]/);
10393
+ if (!displayValue) {
10394
+ this.internalDisplayValue = displayValue;
10395
+ this.internalValue = null;
10396
+ if (lastValue !== this.displayValue)
10397
+ this.change(this.value);
10398
+ }
10399
+ this.timeError = !!displayValue;
10332
10400
  }
10333
- const minutes = [/[0-5]/, /[0-9]/];
10334
- const seconds = this.useSeconds ? [':', ...minutes] : [];
10335
- const ampm = /(A|P)/;
10336
- return [...hours, ':', ...minutes, ...seconds, ' ', ampm, 'M'];
10401
+ this.value = this.internalValue; // forces value accessor to be called if necessary
10337
10402
  }
10338
- fullTimeMask(value) {
10339
- const hours = [
10340
- /[0-2]/,
10341
- value[0] === '2' ? /[0-3]/ : /[0-9]/,
10342
- ];
10343
- const minutes = [/[0-5]/, /[0-9]/];
10344
- const seconds = this.useSeconds ? [':', ...minutes] : [];
10345
- return [...hours, ':', ...minutes, ...seconds];
10403
+ isValidTime(value, format, strict = true) {
10404
+ return dayjs(value, format, strict).isValid();
10346
10405
  }
10347
- getMask(value) {
10348
- return this.maskFunctions[this.timeFormat](value);
10406
+ get isoValue() {
10407
+ return this.formatISOTimeValue(this.value);
10408
+ }
10409
+ set isoValue(newValue) {
10410
+ const lastValue = this.value;
10411
+ this.timeError = false;
10412
+ this.value = this.parseISOTimeValue(newValue);
10413
+ if (lastValue !== this.value)
10414
+ this.change(this.value);
10415
+ }
10416
+ formatISOTimeValue(value) {
10417
+ if (value && this.isValidTime(value, this.valueFormat)) {
10418
+ return dayjs(value, this.valueFormat).format(this.isoFormat);
10419
+ }
10420
+ return '';
10421
+ }
10422
+ parseISOTimeValue(value) {
10423
+ if (value && this.isValidTime(value, this.valueFormat)) {
10424
+ return dayjs(value, this.isoFormat).format(this.valueFormat);
10425
+ }
10426
+ return null;
10349
10427
  }
10350
10428
  /**
10351
- * Checks if value is valid according to valueFormat and if displayValue
10352
- * is true
10353
- */
10354
- isFullyValid(value = this.value) {
10355
- return this.isValidTime(value) && this.isDisplayValid;
10429
+ * Checks if a time format is simple.
10430
+ * Simple time formats are the ones that consists only of 'HH', 'mm', 'mm' or 'YYYY', and mask delimiters
10431
+ * @param format The format to be checked
10432
+ * @returns true if it is simple, false otherwise
10433
+ */
10434
+ isSimpleFormat(format) {
10435
+ const simpleTokens = ['HH', 'mm', 'ss', 'hh', 'A', 'a', 'p', 'P'];
10436
+ // remove the simple tokens from the string
10437
+ const replaced = simpleTokens.reduce((result, token) => result.replace(token, ''), format);
10438
+ const chars = replaced.split('');
10439
+ return chars.length ? chars.every((char) => Mask.isMaskDelimiter(char)) : true;
10356
10440
  }
10357
- formatter(value) {
10358
- const eq = this.lastInvalid === value;
10359
- if (eq || !this.isFullyValid(value)) {
10360
- this.isDisplayValid = true;
10361
- this.lastInvalid = value;
10362
- return value;
10441
+ timeValidation() {
10442
+ if (this.isValidTime(this.displayValue, this.displayFormat) || !this.displayValue) {
10443
+ return true;
10363
10444
  }
10364
- return this.formatterFn(value, this);
10445
+ return I18n.translate('VALIDATION_INVALID_TIME');
10365
10446
  }
10366
- parser(value) {
10367
- const parsed = this.parserFn(value, this);
10368
- this.isDisplayValid = value === null || value === '' || this.isValidTime(value, this.displayFormat);
10369
- return parsed;
10447
+ timeAllowedValidation() {
10448
+ return !this.displayValue
10449
+ || (this.isValidTime(this.displayValue, this.displayFormat)
10450
+ && this.isTimeAllowed())
10451
+ || I18n.translate('VALIDATION_TIME_NOT_ALLOWED');
10370
10452
  }
10371
- isValidTime(value, format = this.valueFormat) {
10372
- return dayjs(value, format, true).isValid();
10453
+ click(event, element) {
10454
+ const clickEvent = event || new MouseEvent('click');
10455
+ super.click(clickEvent, element);
10456
+ if (!clickEvent.defaultPrevented) {
10457
+ this.showTimePicker = !this.showTimePicker;
10458
+ }
10459
+ }
10460
+ blur(event, element) {
10461
+ this.removeTimeMask();
10462
+ this.setTimeValue(this.formatter(this.value));
10463
+ super.blur(event, element);
10464
+ this.showTimePicker = false;
10465
+ }
10466
+ focus(event, element) {
10467
+ this.addTimeMask();
10468
+ super.focus(event, element);
10469
+ }
10470
+ /**
10471
+ * Add date mask
10472
+ */
10473
+ addTimeMask() {
10474
+ if (!this.value)
10475
+ return;
10476
+ this.mask = this.initialMask;
10477
+ this.internalDisplayValue = dayjs(this.value, this.valueFormat).format(this.inputFormat || this.displayFormat);
10478
+ }
10479
+ /**
10480
+ * Removes the component mask if value is valid
10481
+ */
10482
+ removeTimeMask() {
10483
+ if (isUndefined(this.initialMask) || !this.value || this.timeError
10484
+ || !this.isValidTime(this.value, this.valueFormat)) {
10485
+ return;
10486
+ }
10487
+ this.mask = '';
10488
+ }
10489
+ /**
10490
+ * Checks if value is valid according to valueFormat and if displayValue
10491
+ * is true
10492
+ */
10493
+ isFullyValid(value = this.value) {
10494
+ return this.isValidTime(value, this.valueFormat, true) && this.isDisplayValid;
10373
10495
  }
10496
+ /**
10497
+ * Last invalid value passed to formatter
10498
+ */
10499
+ // private lastInvalid: string = '';
10374
10500
  isTimeAllowed(value = this.value) {
10375
10501
  return this.isSameOrAfterMin(value) && this.isSameOrBeforeMax(value)
10376
10502
  && this.isHourAllowed(value) && this.isMinuteAllowed(value)
@@ -10406,49 +10532,54 @@ class Time extends TextInput {
10406
10532
  const second = dayjs(value, this.valueFormat).second();
10407
10533
  return this.allowedSeconds.includes(second);
10408
10534
  }
10409
- timeValidation() {
10410
- return !this.displayValue
10411
- || this.isValidTime(this.displayValue, this.displayFormat)
10412
- || I18n.translate('VALIDATION_INVALID_TIME');
10413
- }
10414
- timeAllowedValidation() {
10415
- return !this.displayValue
10416
- || (this.isValidTime(this.displayValue, this.displayFormat)
10417
- && this.isTimeAllowed())
10418
- || I18n.translate('VALIDATION_TIME_NOT_ALLOWED');
10419
- }
10420
- click(event) {
10421
- this.callEvent('click', {
10422
- event: (event || new MouseEvent('click')),
10423
- component: this,
10424
- });
10425
- if (!(event === null || event === void 0 ? void 0 : event.defaultPrevented)) {
10426
- this.showTimePicker = !this.showTimePicker;
10427
- }
10428
- }
10429
10535
  clear() {
10430
10536
  this.value = null;
10431
10537
  this.change(this.value);
10432
10538
  }
10433
10539
  }
10434
- FormatterParserProvider.registerFormatter('ZdTime', (value, { displayFormat = Config.displayFormat, valueFormat = Config.valueTimeFormat, } = {}) => {
10540
+ FormatterParserProvider.registerFormatter('ZdTime', (value, { valueFormat = Config.valueTimeFormat, displayFormat = Config.displayTimeFormat, inputFormat = Config.timeInputFormat, mask = '', initialMask, isSimpleDisplay = false, } = {}) => {
10435
10541
  if (!value) {
10436
10542
  return '';
10437
10543
  }
10438
- if (dayjs(value, valueFormat, true).isValid()) {
10439
- return dayjs(value, valueFormat).format(displayFormat);
10544
+ const isTimeValid = dayjs(value, valueFormat, true).isValid();
10545
+ if (!isTimeValid) {
10546
+ return value;
10440
10547
  }
10441
- return value;
10548
+ if (mask && initialMask) {
10549
+ if (inputFormat) {
10550
+ return dayjs(value, valueFormat).format(inputFormat);
10551
+ }
10552
+ let valueToUnmask = value;
10553
+ if (isSimpleDisplay) {
10554
+ valueToUnmask = dayjs(value, valueFormat).format(displayFormat);
10555
+ }
10556
+ const unmasked = Mask.getValueWithoutMask(valueToUnmask);
10557
+ const masked = Mask.getValueWithMask(unmasked, mask);
10558
+ return masked;
10559
+ }
10560
+ return dayjs(value, valueFormat).format(displayFormat);
10442
10561
  });
10443
- FormatterParserProvider.registerParser('ZdTime', (value, { displayFormat = Config.displayFormat, valueFormat = Config.valueTimeFormat, } = {}) => {
10562
+ FormatterParserProvider.registerParser('ZdTime', (value, { displayFormat = Config.displayTimeFormat, valueFormat = Config.valueTimeFormat, mask = '', initialMask, } = {}) => {
10444
10563
  if (!value) {
10445
10564
  return null;
10446
10565
  }
10447
- const uppecaseValue = value.toUpperCase();
10448
- if (dayjs(uppecaseValue, displayFormat, true).isValid()) {
10449
- return dayjs(uppecaseValue, displayFormat).format(valueFormat);
10566
+ if (dayjs(value, displayFormat, true).isValid()) {
10567
+ return dayjs(value, displayFormat).format(valueFormat);
10568
+ }
10569
+ if (mask && Mask.checkMask(value, mask)) {
10570
+ const unmasked = Mask.getValueWithoutMask(value);
10571
+ let masked;
10572
+ if (!initialMask) {
10573
+ const displayFmtMask = displayFormat.replace(/[A-Za-z]/gi, '#');
10574
+ masked = Mask.getValueWithMask(unmasked, displayFmtMask);
10575
+ }
10576
+ const timeFmtMask = valueFormat.replace(/[A-Za-z]/gi, '#');
10577
+ masked = Mask.getValueWithMask(unmasked, timeFmtMask);
10578
+ if (dayjs(masked, valueFormat, true).format(valueFormat) === masked) {
10579
+ return masked;
10580
+ }
10450
10581
  }
10451
- return uppecaseValue;
10582
+ return value;
10452
10583
  });
10453
10584
 
10454
10585
  /**
@@ -10590,6 +10721,7 @@ class Tree extends ComponentRender {
10590
10721
  this.checkedField = this.getInitValue('checkedField', props.checkedField, this.checkedField);
10591
10722
  this.openLevelOnLoad = this.getInitValue('openLevelOnLoad', props.openLevelOnLoad, this.openLevelOnLoad);
10592
10723
  this.checkbox = this.getInitValue('checkbox', props.checkbox, this.checkbox);
10724
+ this.disableCheckbox = this.getInitValue('disableCheckbox', props.disableCheckbox, this.disableCheckbox);
10593
10725
  this.afterTitleSlot = props.afterTitleSlot || this.afterTitleSlot;
10594
10726
  this.toolbarSlot = props.toolbarSlot || this.toolbarSlot;
10595
10727
  this.titleSlot = props.titleSlot || this.titleSlot;
@@ -10825,16 +10957,13 @@ class Tree extends ComponentRender {
10825
10957
  const compName = component.name;
10826
10958
  const instanceName = `${compName}_${nodePath}`;
10827
10959
  const path = parentPath ? `${parentPath}.${compName}` : compName;
10828
- const newComponent = merge({}, component, (_a = this.appliedConditions[nodePath]) === null || _a === void 0 ? void 0 : _a[path]);
10960
+ const newInstances = Metadata.getInstances(instanceName);
10961
+ const newInstance = newInstances[0];
10962
+ const appliedConditions = (_a = this.appliedConditions[nodePath]) === null || _a === void 0 ? void 0 : _a[path];
10963
+ const newComponent = merge({}, component, newInstance, appliedConditions);
10829
10964
  const newChildren = this.getSlotComponent(newComponent.children || [], node, path);
10830
10965
  newComponent.name = instanceName;
10831
10966
  newComponent.children = newChildren;
10832
- try {
10833
- Metadata.updateInstance(instanceName, newComponent);
10834
- }
10835
- catch (e) {
10836
- // do nothing
10837
- }
10838
10967
  newComponents.push(newComponent);
10839
10968
  });
10840
10969
  return newComponents;
@@ -10896,6 +11025,10 @@ class Tree extends ComponentRender {
10896
11025
  return this.searchPath(currentNode.children || [], path.slice(1));
10897
11026
  return currentNode;
10898
11027
  }
11028
+ callDisableCheckbox(node) {
11029
+ return !!this.disableCheckbox && typeof this.disableCheckbox === 'function'
11030
+ && this.disableCheckbox({ node, component: this });
11031
+ }
10899
11032
  }
10900
11033
 
10901
11034
  /**
@@ -11042,6 +11175,8 @@ class TreeGrid extends Grid {
11042
11175
  const rows = [row, ...this.treeDataStructure.getChildren(row)];
11043
11176
  if (isSelected) {
11044
11177
  this.selectedRows = Array.from(new Set(this.selectedRows.concat(rows))); // remove duplicates
11178
+ // check if all the children of the parent are selected.
11179
+ this.selectParents(rows, row);
11045
11180
  }
11046
11181
  else {
11047
11182
  rows.forEach((item) => {
@@ -11049,6 +11184,31 @@ class TreeGrid extends Grid {
11049
11184
  if (index > -1)
11050
11185
  this.selectedRows.splice(index, 1);
11051
11186
  });
11187
+ this.unselectParents(row);
11188
+ }
11189
+ }
11190
+ selectParents(rows, row) {
11191
+ if (row[this.parentField]) {
11192
+ const parentRow = this.treeDataStructure.getRowData(row).tree__parent;
11193
+ const every = this.treeDataStructure.getChildren(parentRow).every((item) => {
11194
+ const index = this.treeDataStructure.findDataIndex(this.selectedRows, item[this.datasource.uniqueKey]);
11195
+ if (index > -1)
11196
+ return true;
11197
+ return false;
11198
+ });
11199
+ if (every)
11200
+ rows.push(parentRow);
11201
+ this.selectedRows = Array.from(new Set(this.selectedRows.concat(rows))); // remove duplicates
11202
+ this.selectParents(rows, parentRow);
11203
+ }
11204
+ }
11205
+ unselectParents(row) {
11206
+ if (row[this.parentField]) {
11207
+ const index = this.treeDataStructure.findDataIndex(this.selectedRows, row[this.parentField]);
11208
+ if (index > -1)
11209
+ this.selectedRows.splice(index, 1);
11210
+ const parentRow = this.treeDataStructure.getRowData(row).tree__parent;
11211
+ this.unselectParents(parentRow);
11052
11212
  }
11053
11213
  }
11054
11214
  }
@@ -11083,6 +11243,7 @@ class TreeGridEditable extends TreeGrid {
11083
11243
  },
11084
11244
  };
11085
11245
  this.doubleClickEdit = this.getInitValue('doubleClickEdit', props.doubleClickEdit, this.doubleClickEdit);
11246
+ this.canEditRow = this.getInitValue('canEditRow', props.canEditRow, this.canEditRow);
11086
11247
  this.noDataSlot = this.changeDefaultSlotNames(this.noDataSlot);
11087
11248
  this.createAccessors();
11088
11249
  }
@@ -11136,10 +11297,10 @@ class TreeGridEditable extends TreeGrid {
11136
11297
  * @param event DOM event
11137
11298
  * @param element DOM Element
11138
11299
  */
11139
- cellClick(row, column, event, element) {
11300
+ cellClick(row, column, event, element, canEdit = true) {
11140
11301
  if (this.editing)
11141
11302
  return;
11142
- if (column.editable) {
11303
+ if (column.editable && canEdit) {
11143
11304
  this.editing = true;
11144
11305
  this.preventRowClick = true;
11145
11306
  this.datasource.currentRow = row;
@@ -11456,6 +11617,9 @@ class TreeGridEditable extends TreeGrid {
11456
11617
  throw e;
11457
11618
  }
11458
11619
  }
11620
+ callCanEditRow(row) {
11621
+ return !this.canEditRow || typeof this.canEditRow !== 'function' || this.canEditRow({ row, component: this });
11622
+ }
11459
11623
  }
11460
11624
 
11461
11625
  class Icons {
@@ -11899,9 +12063,9 @@ class BaseReport {
11899
12063
  };
11900
12064
  this.colunmXLS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
11901
12065
  }
11902
- buildColumns(columns) {
12066
+ getColumnsWidth(columns) {
11903
12067
  const widths = {};
11904
- let totalWidth;
12068
+ let totalWidth = 0;
11905
12069
  try {
11906
12070
  totalWidth = columns.reduce((sum, col) => {
11907
12071
  widths[col.name] = col.getWidth();
@@ -11913,6 +12077,10 @@ class BaseReport {
11913
12077
  throw e;
11914
12078
  }
11915
12079
  }
12080
+ return { widths, totalWidth };
12081
+ }
12082
+ buildColumns(columns) {
12083
+ const { widths, totalWidth } = this.getColumnsWidth(columns);
11916
12084
  return columns.reduce((result, col, index) => {
11917
12085
  let size;
11918
12086
  if (!totalWidth) {
@@ -11925,58 +12093,12 @@ class BaseReport {
11925
12093
  align: col.align || 'left',
11926
12094
  description: col.label,
11927
12095
  sequence: index,
11928
- format: this.getFormatOfColumn(col),
11929
12096
  size: `${size}%`,
11930
12097
  xlsType: col.xlsType,
11931
12098
  };
11932
12099
  return Object.assign(Object.assign({}, result), { [col.name]: row });
11933
12100
  }, {});
11934
12101
  }
11935
- isNumberComponent(component) {
11936
- return ['ZdNumber', 'ZdCurrency', 'ZdIncrement'].indexOf(component) !== -1;
11937
- }
11938
- checkAccessor(value) {
11939
- if (Accessor.isAccessorDefinition(value)) {
11940
- const [controller, accessor] = Accessor.getAccessor(value);
11941
- return Loader.getInstance(controller)[accessor];
11942
- }
11943
- return value;
11944
- }
11945
- getFormatOfColumn(column) {
11946
- let format;
11947
- let { mask } = column;
11948
- if (mask) {
11949
- format = {
11950
- type: 'fix',
11951
- params: {
11952
- mask,
11953
- },
11954
- };
11955
- }
11956
- else if (column.componentProps && Object.keys(column.componentProps).length) {
11957
- const { component } = column.componentProps;
11958
- if (this.isNumberComponent(component)) {
11959
- format = { type: 'float' };
11960
- mask = this.checkAccessor(column.componentProps.mask);
11961
- if (mask) {
11962
- format.params = {};
11963
- if (mask.currencySymbol) {
11964
- format.type = 'currency';
11965
- format.symbol = mask.currencySymbol;
11966
- format.decimal = mask.decimalCharacter;
11967
- format.thousands = mask.digitGroupSeparator;
11968
- format.precision = mask.decimalPlaces;
11969
- }
11970
- else {
11971
- format.params.decimal = mask.decimalCharacter;
11972
- format.params.thousands = mask.digitGroupSeparator;
11973
- format.params.precision = mask.decimalPlaces;
11974
- }
11975
- }
11976
- }
11977
- }
11978
- return format;
11979
- }
11980
12102
  buildFilter(filter) {
11981
12103
  return Object.keys(filter).map((key) => ({
11982
12104
  label: key,
@@ -12044,6 +12166,72 @@ class PDFReport extends BaseReport {
12044
12166
  buildDataset(data) {
12045
12167
  return JSON.stringify(data);
12046
12168
  }
12169
+ buildColumns(columns) {
12170
+ const { widths, totalWidth } = this.getColumnsWidth(columns);
12171
+ return columns.reduce((result, col, index) => {
12172
+ let size;
12173
+ if (!totalWidth) {
12174
+ size = Math.floor(100 / columns.length);
12175
+ }
12176
+ else {
12177
+ size = Math.floor((widths[col.name] * 100) / totalWidth);
12178
+ }
12179
+ const row = {
12180
+ align: col.align || 'left',
12181
+ description: col.label,
12182
+ sequence: index,
12183
+ format: this.getFormatOfColumn(col),
12184
+ size: `${size}%`,
12185
+ xlsType: col.xlsType,
12186
+ };
12187
+ return Object.assign(Object.assign({}, result), { [col.name]: row });
12188
+ }, {});
12189
+ }
12190
+ getFormatOfColumn(column) {
12191
+ let format;
12192
+ let { mask } = column;
12193
+ if (mask) {
12194
+ format = {
12195
+ type: 'fix',
12196
+ params: {
12197
+ mask,
12198
+ },
12199
+ };
12200
+ }
12201
+ else if (column.componentProps && Object.keys(column.componentProps).length) {
12202
+ const { component } = column.componentProps;
12203
+ if (this.isNumberComponent(component)) {
12204
+ format = { type: 'float' };
12205
+ mask = this.checkAccessor(column.componentProps.mask);
12206
+ if (mask) {
12207
+ format.params = {};
12208
+ if (mask.currencySymbol) {
12209
+ format.type = 'currency';
12210
+ format.symbol = mask.currencySymbol;
12211
+ format.decimal = mask.decimalCharacter;
12212
+ format.thousands = mask.digitGroupSeparator;
12213
+ format.precision = mask.decimalPlaces;
12214
+ }
12215
+ else {
12216
+ format.params.decimal = mask.decimalCharacter;
12217
+ format.params.thousands = mask.digitGroupSeparator;
12218
+ format.params.precision = mask.decimalPlaces;
12219
+ }
12220
+ }
12221
+ }
12222
+ }
12223
+ return format;
12224
+ }
12225
+ isNumberComponent(component) {
12226
+ return ['ZdNumber', 'ZdCurrency', 'ZdIncrement'].indexOf(component) !== -1;
12227
+ }
12228
+ checkAccessor(value) {
12229
+ if (Accessor.isAccessorDefinition(value)) {
12230
+ const [controller, accessor] = Accessor.getAccessor(value);
12231
+ return Loader.getInstance(controller)[accessor];
12232
+ }
12233
+ return value;
12234
+ }
12047
12235
  buildMetadata(name, title, columns, filter, portrait = true) {
12048
12236
  return __awaiter(this, void 0, void 0, function* () {
12049
12237
  const builtCols = this.buildColumns(columns);
@@ -12125,6 +12313,7 @@ class PDFReport extends BaseReport {
12125
12313
  }
12126
12314
  }
12127
12315
 
12316
+ // XLS without groups (formatXLS = 'F3')
12128
12317
  class XLSReport extends BaseReport {
12129
12318
  constructor() {
12130
12319
  super(...arguments);
@@ -12171,13 +12360,14 @@ class XLSReport extends BaseReport {
12171
12360
  columns: builtCols,
12172
12361
  filter: builtFilters,
12173
12362
  reportXLS: true,
12363
+ formatXLS: 'F3',
12174
12364
  xlsMergedCell: [],
12175
12365
  };
12176
12366
  return Promise.resolve(JSON.stringify(metadataObj));
12177
12367
  }
12178
12368
  }
12179
12369
 
12180
- // XLS with groups
12370
+ // XLS with groups (formatXLS = 'F1')
12181
12371
  class XLS2Report extends BaseReport {
12182
12372
  constructor() {
12183
12373
  super(...arguments);
@@ -12215,6 +12405,7 @@ class XLS2Report extends BaseReport {
12215
12405
  columns: builtCols,
12216
12406
  filter: builtFilters,
12217
12407
  reportXLS: true,
12408
+ formatXLS: 'F1',
12218
12409
  xlsMergedCell: [],
12219
12410
  };
12220
12411
  return Promise.resolve(JSON.stringify(metadataObj));
@@ -12373,7 +12564,7 @@ class XLS2Report extends BaseReport {
12373
12564
  }
12374
12565
  }
12375
12566
 
12376
- // Grid mirror (with groups)
12567
+ // Grid mirror (with groups) (formatXLS = 'F2')
12377
12568
  class XLS3Report extends BaseReport {
12378
12569
  constructor() {
12379
12570
  super(...arguments);
@@ -12411,6 +12602,7 @@ class XLS3Report extends BaseReport {
12411
12602
  columns: builtCols,
12412
12603
  filter: builtFilters,
12413
12604
  reportXLS: true,
12605
+ formatXLS: 'F2',
12414
12606
  xlsMergedCell: [],
12415
12607
  };
12416
12608
  return Promise.resolve(JSON.stringify(metadataObj));
@@ -12615,7 +12807,7 @@ class Report {
12615
12807
  const { route } = reportType;
12616
12808
  const { name, columns, datasource } = this.iterable;
12617
12809
  const { groupedData } = Object.assign({}, this.iterable);
12618
- const formattedColumns = this.removeActionColumns(columns);
12810
+ const formattedColumns = this.removeColumns(columns);
12619
12811
  const metadataObj = yield reportType.buildMetadata(name, this.title, formattedColumns, datasource.filter, portrait);
12620
12812
  let dataset;
12621
12813
  if ((reportType instanceof XLS2Report || reportType instanceof XLS3Report) && groupedData) {
@@ -12657,8 +12849,8 @@ class Report {
12657
12849
  return new URL(reportFile, this.fileEndPoint).href;
12658
12850
  });
12659
12851
  }
12660
- removeActionColumns(columns) {
12661
- return columns.filter((item) => item.type !== 'action');
12852
+ removeColumns(columns) {
12853
+ return columns.filter((item) => (item.type !== 'action' && item.isVisible));
12662
12854
  }
12663
12855
  }
12664
12856