@colijnit/corecomponents_v12 300.1.0 → 300.1.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,6 +1,6 @@
1
1
  import { __decorate } from 'tslib';
2
2
  import * as i0 from '@angular/core';
3
- import { Input, Injectable, HostBinding, ViewEncapsulation, Component, Directive, ElementRef, Pipe, EventEmitter, Output, ViewChildren, ViewContainerRef, HostListener, ViewChild, Optional, NgModule, SkipSelf, InjectionToken, Inject, forwardRef, ChangeDetectionStrategy, ContentChildren, NO_ERRORS_SCHEMA, Injector, QueryList } from '@angular/core';
3
+ import { Input, Injectable, HostBinding, ViewEncapsulation, Component, Directive, ElementRef, Pipe, EventEmitter, Output, ViewChildren, ViewContainerRef, HostListener, ViewChild, Optional, NgModule, SkipSelf, InjectionToken, Inject, forwardRef, ChangeDetectionStrategy, ContentChildren, LOCALE_ID, NO_ERRORS_SCHEMA, Injector, QueryList } from '@angular/core';
4
4
  import * as i5 from '@angular/forms';
5
5
  import { NgModel, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
6
6
  import * as i1 from '@angular/platform-browser';
@@ -532,6 +532,28 @@ class NumberUtils {
532
532
  return { isOk: false, nearestOkNr: nearestOkNr };
533
533
  }
534
534
  }
535
+ /**
536
+ * Decides whether typing one more digit onto the given numeric text would exceed the configured
537
+ * digit limits. When `decimals` (scale) is set, `maxLength` is treated as the total precision: the
538
+ * integer part is capped at (maxLength - decimals) digits and the fractional part at `decimals`
539
+ * digits. When `decimals` is not set, `maxLength` caps the total number of digits.
540
+ *
541
+ * Note: assumes the digit is appended at the end of the value, because native number inputs expose
542
+ * no caret/selection information to constrain mid-string edits.
543
+ */
544
+ static WouldExceedDigitLimits(currentValue, maxLength, decimals) {
545
+ const digits = ('' + (currentValue ?? '')).replace('-', '');
546
+ if (decimals > 0) {
547
+ const separatorIndex = digits.search(/[.,]/);
548
+ if (separatorIndex === -1) {
549
+ const maxIntegerDigits = maxLength > 0 ? maxLength - decimals : Number.POSITIVE_INFINITY;
550
+ return digits.length >= maxIntegerDigits;
551
+ }
552
+ const decimalDigits = digits.length - separatorIndex - 1;
553
+ return decimalDigits >= decimals;
554
+ }
555
+ return maxLength > 0 && digits.length >= maxLength;
556
+ }
535
557
  static _GetLargestDecimalPrecisionOf(...args) {
536
558
  return ArrayUtils.GetMaxCalculatedValue(args, (arg) => {
537
559
  return NumberUtils.GetDecimalPlaces(arg);
@@ -934,8 +956,12 @@ function requiredValidator(control) {
934
956
  function precisionScaleValidator(precision, scale) {
935
957
  return function (control) {
936
958
  let isValid = true;
937
- if (control) {
938
- isValid = NumberUtils.CheckPrecisionAndScale(control.value, precision, scale).isOk;
959
+ if (control && control.value !== null && control.value !== undefined && control.value !== '') {
960
+ // The value may be a locale display string (e.g. "1234567,89"); normalize it to a number so the
961
+ // decimal separator is not counted as an integer digit by CheckPrecisionAndScale.
962
+ const raw = control.value;
963
+ const numeric = typeof raw === 'string' ? Number(raw.replace(',', '.')) : raw;
964
+ isValid = isNaN(numeric) || NumberUtils.CheckPrecisionAndScale(numeric, precision, scale).isOk;
939
965
  }
940
966
  return isValid ? null : { 'precision-scale': "MESSAGE_FIELD_PRECISION_OVERRIDDEN||" + precision };
941
967
  };
@@ -1107,6 +1133,7 @@ var CoreComponentsIcon;
1107
1133
  CoreComponentsIcon["Linechart"] = "linechart";
1108
1134
  CoreComponentsIcon["LinkedProducts"] = "linked_products";
1109
1135
  CoreComponentsIcon["LinkCircle"] = "link_circle";
1136
+ CoreComponentsIcon["ListRegular"] = "list_regular";
1110
1137
  CoreComponentsIcon["ListView"] = "list_view";
1111
1138
  CoreComponentsIcon["Location"] = "location";
1112
1139
  CoreComponentsIcon["Lock"] = "lock";
@@ -1413,6 +1440,7 @@ const CoreComponentsIconSvg = {
1413
1440
  "linechart": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 50 50\"><path d=\"M11,12.17v25H40v1H10v-26Z\" fill=\"#4c5050\" opacity=\"0.75\"/><polygon points=\"11.76 33.18 11 32.53 15.16 26.48 19.66 24.3 24.26 27.19 28.07 22.25 35.3 19.53 37.01 21.7 38.92 17.28 39.84 17.68 37.26 23.64 34.97 20.72 28.69 23.09 24.5 28.52 19.6 25.44 15.7 27.34 11.76 33.18\" fill=\"#4c5050\"/><polygon points=\"39.84 17.68 37.26 23.64 34.97 20.72 28.69 23.09 24.5 28.52 19.6 25.44 15.7 27.34 11.76 33.18 11 32.53 11 37.17 40 37.17 39.84 17.68\" fill=\"#4c5050\" opacity=\"0.25\"/></svg>",
1414
1441
  "linked_products": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 50 50\"><g opacity=\"0.5\"><path d=\"M20.2,14.71h2.15V26.2l.76-.77V14.71H24.4v9.43l.77-.77V14.71h1.29V22.1l.08-.09,1.29-1.3v-6h1.29v4.71l1.68-1.67a6.28,6.28,0,0,1,.54-.49V14.71h1.29v1.77a7.15,7.15,0,0,1,.77-.29V14.71H36V16a6.71,6.71,0,0,1,1,.21V14.71h1.29v2a6,6,0,0,1,1.31,1l.09.08c.11.11.21.23.31.35v-3a2.57,2.57,0,0,0-2.57-2.57H12.57A2.57,2.57,0,0,0,10,15.14V29.72a2.57,2.57,0,0,0,2.57,2.57h5.95a6.13,6.13,0,0,1,1.68-3.93ZM14.29,30.14H12.15V14.71h2.14Zm2,0H15V14.71h1.29Zm1.28,0V14.71h1.29V30.14Z\" fill=\"#484f60\"/><path d=\"M39.68,26.63,38.29,28v2.11H37v-.83l-2.92,2.92v-.1s-.09.1-.13.16h3.48A2.57,2.57,0,0,0,40,29.72V26.28A3.49,3.49,0,0,1,39.68,26.63Z\" fill=\"#484f60\"/></g><path d=\"M38.62,18.89l-.08-.08a4.73,4.73,0,0,0-6.68,0L27.6,23.07a4.73,4.73,0,0,0,0,6.68l.08.08a3.8,3.8,0,0,0,.48.42l1.56-1.56a2.38,2.38,0,0,1-.51-.39l-.08-.08a2.56,2.56,0,0,1,0-3.62l4.26-4.26a2.56,2.56,0,0,1,3.62,0l.08.08a2.56,2.56,0,0,1,0,3.62L35.16,26a6.53,6.53,0,0,1,.48,2.58l3-3A4.73,4.73,0,0,0,38.62,18.89ZM32.33,25a3.77,3.77,0,0,0-.49-.42l-1.56,1.56a2.1,2.1,0,0,1,.51.39l.08.08a2.56,2.56,0,0,1,0,3.62l-4.26,4.26a2.56,2.56,0,0,1-3.62,0l-.08-.08a2.56,2.56,0,0,1,0-3.62l1.93-1.93a6.6,6.6,0,0,1-.48-2.58l-3,3a4.73,4.73,0,0,0,0,6.68l.08.08a4.73,4.73,0,0,0,6.68,0l4.26-4.26a4.74,4.74,0,0,0,0-6.69Z\" fill=\"#484f60\"/></svg>",
1415
1442
  "link_circle": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 50 50\"><path d=\"M25,45A20,20,0,1,1,45,25,20,20,0,0,1,25,45ZM25,6.29A18.71,18.71,0,1,0,43.71,25,18.73,18.73,0,0,0,25,6.29Z\" fill=\"#484f60\"/><path d=\"M34.48,15.6l-.08-.08a5.21,5.21,0,0,0-7.36,0L22.36,20.2a5.21,5.21,0,0,0,0,7.36l.08.08c.17.17.35.32.53.47l1.72-1.72a2.88,2.88,0,0,1-.56-.43L24,25.87a2.81,2.81,0,0,1,0-4l4.69-4.69a2.81,2.81,0,0,1,4,0l.09.09a2.81,2.81,0,0,1,0,4l-2.12,2.12a7.17,7.17,0,0,1,.52,2.85L34.48,23A5.21,5.21,0,0,0,34.48,15.6Zm-6.92,6.76A5.62,5.62,0,0,0,27,21.9l-1.72,1.71a2.88,2.88,0,0,1,.56.43l.09.09a2.81,2.81,0,0,1,0,4L21.27,32.8a2.81,2.81,0,0,1-4,0l-.09-.09a2.81,2.81,0,0,1,0-4l2.12-2.12a7.17,7.17,0,0,1-.52-2.85L15.52,27a5.21,5.21,0,0,0,0,7.36l.08.08a5.21,5.21,0,0,0,7.36,0l4.68-4.68a5.21,5.21,0,0,0,0-7.36Z\" fill=\"#484f60\"/></svg>",
1443
+ "list_regular": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M88 48C101.3 48 112 58.75 112 72V120C112 133.3 101.3 144 88 144H40C26.75 144 16 133.3 16 120V72C16 58.75 26.75 48 40 48H88zM488 72C501.3 72 512 82.75 512 96C512 109.3 501.3 120 488 120H184C170.7 120 160 109.3 160 96C160 82.75 170.7 72 184 72H488zM488 232C501.3 232 512 242.7 512 256C512 269.3 501.3 280 488 280H184C170.7 280 160 269.3 160 256C160 242.7 170.7 232 184 232H488zM488 392C501.3 392 512 402.7 512 416C512 429.3 501.3 440 488 440H184C170.7 440 160 429.3 160 416C160 402.7 170.7 392 184 392H488zM16 232C16 218.7 26.75 208 40 208H88C101.3 208 112 218.7 112 232V280C112 293.3 101.3 304 88 304H40C26.75 304 16 293.3 16 280V232zM88 368C101.3 368 112 378.7 112 392V440C112 453.3 101.3 464 88 464H40C26.75 464 16 453.3 16 440V392C16 378.7 26.75 368 40 368H88z\"/></svg>",
1416
1444
  "list_view": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 51 51\"><rect x=\"26.5\" y=\"13\" width=\"14\" height=\"7\" fill=\"#4d5050\"/><rect x=\"10.5\" y=\"13\" width=\"14\" height=\"7\" fill=\"#4d5050\"/><rect x=\"10.5\" y=\"22\" width=\"14\" height=\"7\" fill=\"#4d5050\"/><rect x=\"26.5\" y=\"22\" width=\"14\" height=\"7\" fill=\"#4d5050\"/><rect x=\"10.5\" y=\"31\" width=\"14\" height=\"7\" fill=\"#4d5050\"/><rect x=\"26.5\" y=\"31\" width=\"14\" height=\"7\" fill=\"#4d5050\"/></svg>",
1417
1445
  "location": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 50 50\"><path d=\"M25,12.67A8.33,8.33,0,0,0,16.67,21c0,4.6,8.33,16.67,8.33,16.67S33.33,25.6,33.33,21A8.33,8.33,0,0,0,25,12.67Zm0,10.41A2.08,2.08,0,1,1,27.08,21,2.08,2.08,0,0,1,25,23.08Z\" fill=\"#484f60\"/></svg>",
1418
1446
  "lock": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 50 50\"><path d=\"M32.65,21.67H17.35c-2.81,0-3.06,2.29-3.06,5.12v8.09c0,2.83.25,5.12,3.06,5.12h15.3c2.81,0,3.06-2.29,3.06-5.12V26.79C35.71,24,35.46,21.67,32.65,21.67ZM20.22,37.49l2.61-6.32a3.82,3.82,0,1,1,4.35,0l2.6,6.32Z\" fill=\"#484f60\"/><path d=\"M29.51,16.64c0-3.6-2-4.07-4.51-4.07h0c-2.49,0-4.51.47-4.51,4.07v3h-2.7v-3C17.79,11.62,21,10,25,10h0c4,0,7.21,1.62,7.21,6.64v3h-2.7Z\" fill=\"#484f60\"/></svg>",
@@ -2031,27 +2059,28 @@ class CommitButtonsComponent {
2031
2059
  event.currentTarget.removeEventListener('animationiteration', this._handleAnimationIteration);
2032
2060
  };
2033
2061
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: CommitButtonsComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
2034
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CommitButtonsComponent, isStandalone: false, selector: "co-commit-buttons", inputs: { committing: "committing", commitFinished: "commitFinished", parentForOverlay: "parentForOverlay" }, outputs: { cancelClick: "cancelClick", commitClick: "commitClick" }, host: { properties: { "class.co-commit-buttons": "this.showClass" } }, viewQueries: [{ propertyName: "content", predicate: ["animatediv"], descendants: true, read: ElementRef }], ngImport: i0, template: `
2035
- <div class="commit-buttons-wrapper" [overlay]="parentForOverlay" [rightAlign]="true" @showHideSaveCancel>
2036
- <div class="commit-buttons-button save" [class.finished]="commitFinished"
2037
- (click)="commitClick.emit($event)">
2038
- @if (committing) {
2039
- <div class="save-button-spinner">
2040
- <div #animatediv></div>
2041
- <div #animatediv></div>
2042
- <div #animatediv></div>
2043
- <div #animatediv></div>
2044
- </div>
2045
- }
2046
- @if (firstShow || commitFinished) {
2047
- <svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
2048
- <path class="checkmark-check" [class.first-show]="firstShow" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/></svg>
2049
- }
2050
- </div>
2051
- <div class="commit-buttons-button cancel" (mousedown)="$event.preventDefault()" (click)="cancelClick.emit($event)">
2052
- <div class="cancel-button"></div>
2053
- </div>
2054
- </div>
2062
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: CommitButtonsComponent, isStandalone: false, selector: "co-commit-buttons", inputs: { committing: "committing", commitFinished: "commitFinished", parentForOverlay: "parentForOverlay" }, outputs: { cancelClick: "cancelClick", commitClick: "commitClick" }, host: { properties: { "class.co-commit-buttons": "this.showClass" } }, viewQueries: [{ propertyName: "content", predicate: ["animatediv"], descendants: true, read: ElementRef }], ngImport: i0, template: `
2063
+ <div class="commit-buttons-wrapper" [overlay]="parentForOverlay" [rightAlign]="true" @showHideSaveCancel>
2064
+ <div class="commit-buttons-button save" [class.finished]="commitFinished"
2065
+ (mousedown)="$event.preventDefault()"
2066
+ (click)="commitClick.emit($event)">
2067
+ @if (committing) {
2068
+ <div class="save-button-spinner">
2069
+ <div #animatediv></div>
2070
+ <div #animatediv></div>
2071
+ <div #animatediv></div>
2072
+ <div #animatediv></div>
2073
+ </div>
2074
+ }
2075
+ @if (firstShow || commitFinished) {
2076
+ <svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
2077
+ <path class="checkmark-check" [class.first-show]="firstShow" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/></svg>
2078
+ }
2079
+ </div>
2080
+ <div class="commit-buttons-button cancel" (mousedown)="$event.preventDefault()" (click)="cancelClick.emit($event)">
2081
+ <div class="cancel-button"></div>
2082
+ </div>
2083
+ </div>
2055
2084
  `, isInline: true, dependencies: [{ kind: "directive", type: OverlayDirective, selector: "[overlay]", inputs: ["overlay", "view", "inline", "keepInView", "inheritWidth", "rightAlign", "fullSize"] }], animations: [
2056
2085
  trigger('showHideSaveCancel', [
2057
2086
  state('*', style({ transform: 'scaleY(1)', opacity: 1 })),
@@ -2064,27 +2093,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2064
2093
  type: Component,
2065
2094
  args: [{
2066
2095
  selector: 'co-commit-buttons',
2067
- template: `
2068
- <div class="commit-buttons-wrapper" [overlay]="parentForOverlay" [rightAlign]="true" @showHideSaveCancel>
2069
- <div class="commit-buttons-button save" [class.finished]="commitFinished"
2070
- (click)="commitClick.emit($event)">
2071
- @if (committing) {
2072
- <div class="save-button-spinner">
2073
- <div #animatediv></div>
2074
- <div #animatediv></div>
2075
- <div #animatediv></div>
2076
- <div #animatediv></div>
2077
- </div>
2078
- }
2079
- @if (firstShow || commitFinished) {
2080
- <svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
2081
- <path class="checkmark-check" [class.first-show]="firstShow" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/></svg>
2082
- }
2083
- </div>
2084
- <div class="commit-buttons-button cancel" (mousedown)="$event.preventDefault()" (click)="cancelClick.emit($event)">
2085
- <div class="cancel-button"></div>
2086
- </div>
2087
- </div>
2096
+ template: `
2097
+ <div class="commit-buttons-wrapper" [overlay]="parentForOverlay" [rightAlign]="true" @showHideSaveCancel>
2098
+ <div class="commit-buttons-button save" [class.finished]="commitFinished"
2099
+ (mousedown)="$event.preventDefault()"
2100
+ (click)="commitClick.emit($event)">
2101
+ @if (committing) {
2102
+ <div class="save-button-spinner">
2103
+ <div #animatediv></div>
2104
+ <div #animatediv></div>
2105
+ <div #animatediv></div>
2106
+ <div #animatediv></div>
2107
+ </div>
2108
+ }
2109
+ @if (firstShow || commitFinished) {
2110
+ <svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
2111
+ <path class="checkmark-check" [class.first-show]="firstShow" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/></svg>
2112
+ }
2113
+ </div>
2114
+ <div class="commit-buttons-button cancel" (mousedown)="$event.preventDefault()" (click)="cancelClick.emit($event)">
2115
+ <div class="cancel-button"></div>
2116
+ </div>
2117
+ </div>
2088
2118
  `,
2089
2119
  animations: [
2090
2120
  trigger('showHideSaveCancel', [
@@ -2267,7 +2297,7 @@ class BaseInputComponent {
2267
2297
  get model() {
2268
2298
  return this._model;
2269
2299
  }
2270
- label;
2300
+ label = '';
2271
2301
  noValidation = false;
2272
2302
  initFocus;
2273
2303
  noClickFocus;
@@ -2517,7 +2547,6 @@ class BaseInputComponent {
2517
2547
  // @implements ConfigurationAdapterComponent
2518
2548
  objectConfigName;
2519
2549
  validationError = '';
2520
- shouldCommit = true;
2521
2550
  _markedAsUserTouched = false;
2522
2551
  _destroyed = false;
2523
2552
  _hasOnPushCdStrategy = false;
@@ -2543,6 +2572,7 @@ class BaseInputComponent {
2543
2572
  _formReadonlyChangeSub;
2544
2573
  _clearMarkedAsUserTouchedSub;
2545
2574
  _canSaveOrCancel = false;
2575
+ _committing = false;
2546
2576
  _commitButtonsComponentRef;
2547
2577
  _validationComponentRef;
2548
2578
  constructor(changeDetector, overlayService, formUserChangeListener, ngZoneWrapper, elementRef) {
@@ -2614,7 +2644,6 @@ class BaseInputComponent {
2614
2644
  return Promise.resolve(true);
2615
2645
  };
2616
2646
  cancelClick(event) {
2617
- this.shouldCommit = false;
2618
2647
  this.keepFocus = true;
2619
2648
  if (this._initialModelSet) {
2620
2649
  this.model = this._initialModel;
@@ -2669,7 +2698,7 @@ class BaseInputComponent {
2669
2698
  this.focus.next();
2670
2699
  }
2671
2700
  async doBlur(event, handleCommit = true) {
2672
- if (this.showSaveCancel && handleCommit && this._modelDirtyForCommit && this.shouldCommit) {
2701
+ if (this.showSaveCancel && handleCommit && this._modelDirtyForCommit) {
2673
2702
  await this._handleCommit(event, false);
2674
2703
  }
2675
2704
  setTimeout(() => {
@@ -2799,23 +2828,37 @@ class BaseInputComponent {
2799
2828
  }
2800
2829
  }
2801
2830
  async _handleCommit(event, doBlur = true) {
2802
- if (!this.showSaveCancel || (!this._modelDirtyForCommit)) {
2831
+ if (!this.showSaveCancel || !this._modelDirtyForCommit || this._committing) {
2803
2832
  return true;
2804
2833
  }
2834
+ this._committing = true;
2805
2835
  this.keepFocus = true;
2806
- this.shouldCommit = true;
2807
2836
  if (this._commitButtonsComponentRef) {
2808
2837
  this._commitButtonsComponentRef.instance.commitFinished = false;
2809
2838
  this._commitButtonsComponentRef.instance.committing = true;
2810
2839
  }
2811
2840
  this._modelDirtyForCommit = false;
2812
- const success = await this.commit(this.model);
2813
- this.keepFocus = false;
2814
- await this._commitFinished();
2815
- if (success && doBlur) {
2816
- this.doBlur(event, false);
2841
+ try {
2842
+ const success = await this.commit(this.model);
2843
+ if (success) {
2844
+ // keep the committed value as the new baseline, otherwise a later model re-emission
2845
+ // would compare against a stale _initialModel and re-open the commit guard.
2846
+ this._initialModel = this._model;
2847
+ this._modelDirtyForCommit = false;
2848
+ }
2849
+ else {
2850
+ this._modelDirtyForCommit = true;
2851
+ }
2852
+ this.keepFocus = false;
2853
+ await this._commitFinished();
2854
+ if (success && doBlur) {
2855
+ this.doBlur(event, false);
2856
+ }
2857
+ return success;
2858
+ }
2859
+ finally {
2860
+ this._committing = false;
2817
2861
  }
2818
- return success;
2819
2862
  }
2820
2863
  _commitFinished() {
2821
2864
  return new Promise((resolve) => {
@@ -2848,6 +2891,8 @@ class BaseInputComponent {
2848
2891
  this.input.disabled = disabled;
2849
2892
  }
2850
2893
  }
2894
+ // protected so numeric components can suppress the native maxlength (which, on a text input, would
2895
+ // wrongly count the decimal separator/sign as characters); they enforce precision/scale in keydown.
2851
2896
  _setNativeMaxLength(maxlength) {
2852
2897
  if (this.input && !isNaN(maxlength)) {
2853
2898
  this.input.maxLength = maxlength;
@@ -5802,48 +5847,40 @@ class GridToolbarComponent {
5802
5847
  }
5803
5848
  }
5804
5849
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: GridToolbarComponent, deps: [{ token: IconCacheService }], target: i0.ɵɵFactoryTarget.Component });
5805
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: GridToolbarComponent, isStandalone: false, selector: "co-grid-toolbar", inputs: { showEdit: "showEdit", showAdd: "showAdd", showDelete: "showDelete", deleteEnabled: "deleteEnabled" }, outputs: { editClick: "editClick", cancelClick: "cancelClick", saveClick: "saveClick", addClick: "addClick", deleteClick: "deleteClick" }, host: { properties: { "class.co-grid-toolbar": "this.showClass" } }, ngImport: i0, template: `
5806
- <div class="grid-toolbar-wrapper">
5807
- @if (showEdit) {
5808
- <co-icon [iconData]="iconsService.getIcon(icons.PenToSquareSolid)" [title]="'edit'" (click)="editClick.emit($event)"></co-icon>
5809
- }
5810
- @if (showEdit) {
5811
- <co-icon [iconData]="iconsService.getIcon(icons.RotateLeftSolid)" [title]="'cancel'" (click)="cancelClick.emit()"></co-icon>
5812
- }
5813
- @if (showEdit) {
5814
- <co-icon [iconData]="iconsService.getIcon(icons.FloppyDiskSolid)" [title]="'save'" (click)="saveClick.emit()"></co-icon>
5815
- }
5816
- @if (showAdd || showEdit) {
5817
- <co-icon [iconData]="iconsService.getIcon(icons.PlusSolid)" [title]="'add'" (click)="addClick.emit()"></co-icon>
5818
- }
5819
- @if (showDelete) {
5820
- <co-icon [iconData]="iconsService.getIcon(icons.TrashCanSolid)" [title]="'delete'" [class.disabled]="!deleteEnabled" (click)="handleDeleteClick()"></co-icon>
5821
- }
5822
- </div>
5850
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: GridToolbarComponent, isStandalone: false, selector: "co-grid-toolbar", inputs: { showEdit: "showEdit", showAdd: "showAdd", showDelete: "showDelete", deleteEnabled: "deleteEnabled" }, outputs: { editClick: "editClick", cancelClick: "cancelClick", saveClick: "saveClick", addClick: "addClick", deleteClick: "deleteClick" }, host: { properties: { "class.co-grid-toolbar": "this.showClass" } }, ngImport: i0, template: `
5851
+ <div class="grid-toolbar-wrapper">
5852
+ @if (showEdit) {
5853
+ <co-icon [iconData]="iconsService.getIcon(icons.PenToSquareSolid)" [title]="'edit'" (click)="editClick.emit($event)"></co-icon>
5854
+ <co-icon [iconData]="iconsService.getIcon(icons.RotateLeftSolid)" [title]="'cancel'" (click)="cancelClick.emit()"></co-icon>
5855
+ <co-icon [iconData]="iconsService.getIcon(icons.FloppyDiskSolid)" [title]="'save'" (click)="saveClick.emit()"></co-icon>
5856
+ }
5857
+ @if (showAdd || showEdit) {
5858
+ <co-icon [iconData]="iconsService.getIcon(icons.PlusSolid)" [title]="'add'" (click)="addClick.emit()"></co-icon>
5859
+ }
5860
+ @if (showDelete) {
5861
+ <co-icon [iconData]="iconsService.getIcon(icons.TrashCanSolid)" [title]="'delete'" [class.disabled]="!deleteEnabled" (click)="handleDeleteClick()"></co-icon>
5862
+ }
5863
+ </div>
5823
5864
  `, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }], encapsulation: i0.ViewEncapsulation.None });
5824
5865
  }
5825
5866
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: GridToolbarComponent, decorators: [{
5826
5867
  type: Component,
5827
5868
  args: [{
5828
5869
  selector: "co-grid-toolbar",
5829
- template: `
5830
- <div class="grid-toolbar-wrapper">
5831
- @if (showEdit) {
5832
- <co-icon [iconData]="iconsService.getIcon(icons.PenToSquareSolid)" [title]="'edit'" (click)="editClick.emit($event)"></co-icon>
5833
- }
5834
- @if (showEdit) {
5835
- <co-icon [iconData]="iconsService.getIcon(icons.RotateLeftSolid)" [title]="'cancel'" (click)="cancelClick.emit()"></co-icon>
5836
- }
5837
- @if (showEdit) {
5838
- <co-icon [iconData]="iconsService.getIcon(icons.FloppyDiskSolid)" [title]="'save'" (click)="saveClick.emit()"></co-icon>
5839
- }
5840
- @if (showAdd || showEdit) {
5841
- <co-icon [iconData]="iconsService.getIcon(icons.PlusSolid)" [title]="'add'" (click)="addClick.emit()"></co-icon>
5842
- }
5843
- @if (showDelete) {
5844
- <co-icon [iconData]="iconsService.getIcon(icons.TrashCanSolid)" [title]="'delete'" [class.disabled]="!deleteEnabled" (click)="handleDeleteClick()"></co-icon>
5845
- }
5846
- </div>
5870
+ template: `
5871
+ <div class="grid-toolbar-wrapper">
5872
+ @if (showEdit) {
5873
+ <co-icon [iconData]="iconsService.getIcon(icons.PenToSquareSolid)" [title]="'edit'" (click)="editClick.emit($event)"></co-icon>
5874
+ <co-icon [iconData]="iconsService.getIcon(icons.RotateLeftSolid)" [title]="'cancel'" (click)="cancelClick.emit()"></co-icon>
5875
+ <co-icon [iconData]="iconsService.getIcon(icons.FloppyDiskSolid)" [title]="'save'" (click)="saveClick.emit()"></co-icon>
5876
+ }
5877
+ @if (showAdd || showEdit) {
5878
+ <co-icon [iconData]="iconsService.getIcon(icons.PlusSolid)" [title]="'add'" (click)="addClick.emit()"></co-icon>
5879
+ }
5880
+ @if (showDelete) {
5881
+ <co-icon [iconData]="iconsService.getIcon(icons.TrashCanSolid)" [title]="'delete'" [class.disabled]="!deleteEnabled" (click)="handleDeleteClick()"></co-icon>
5882
+ }
5883
+ </div>
5847
5884
  `,
5848
5885
  encapsulation: ViewEncapsulation.None,
5849
5886
  standalone: false
@@ -7164,10 +7201,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
7164
7201
  args: ["class.co-calendar"]
7165
7202
  }] } });
7166
7203
 
7204
+ /**
7205
+ * Resolves the locale-specific decimal separator (e.g. ',' for nl-NL) from the app-wide LOCALE_ID and
7206
+ * converts between a numeric model value and its user-facing display string. Injected app-wide, so no
7207
+ * component has to be given a locale explicitly.
7208
+ *
7209
+ * The model always stays a real number (dot-based / JSON-safe); the separator only affects the display
7210
+ * string shown in the input, never the stored value.
7211
+ */
7212
+ class NumberLocaleService {
7213
+ _decimalSeparator;
7214
+ constructor(localeId) {
7215
+ // Intl uses the locale string directly, so this works without registerLocaleData().
7216
+ const parts = new Intl.NumberFormat(localeId).formatToParts(1.1);
7217
+ const decimalPart = parts.find((part) => part.type === 'decimal');
7218
+ this._decimalSeparator = decimalPart ? decimalPart.value : '.';
7219
+ }
7220
+ get decimalSeparator() {
7221
+ return this._decimalSeparator;
7222
+ }
7223
+ // Parses a user-typed display string to a number. Accepts both ',' and '.' as decimal separator so the
7224
+ // field is forgiving. Returns NaN when the text is not a parsable number.
7225
+ parse(text) {
7226
+ if (text === null || text === undefined) {
7227
+ return NaN;
7228
+ }
7229
+ const normalized = ('' + text).trim().replace(',', '.');
7230
+ if (normalized === '') {
7231
+ return NaN;
7232
+ }
7233
+ return Number(normalized);
7234
+ }
7235
+ // Formats a numeric model value to a display string using the locale decimal separator. Returns '' for
7236
+ // null/undefined/NaN. No grouping (thousands) separators are added, as this targets an editable field.
7237
+ format(value) {
7238
+ if (value === null || value === undefined || isNaN(value)) {
7239
+ return '';
7240
+ }
7241
+ return ('' + value).replace('.', this._decimalSeparator);
7242
+ }
7243
+ // Inserts the locale decimal separator at the input's caret and notifies Angular via an 'input' event.
7244
+ // Used to normalize a typed '.' to the locale separator (e.g. numpad '.' -> ',' for nl-NL).
7245
+ insertDecimalSeparator(input) {
7246
+ const start = input.selectionStart ?? input.value.length;
7247
+ const end = input.selectionEnd ?? input.value.length;
7248
+ input.value = input.value.slice(0, start) + this._decimalSeparator + input.value.slice(end);
7249
+ const caret = start + this._decimalSeparator.length;
7250
+ input.setSelectionRange(caret, caret);
7251
+ input.dispatchEvent(new Event('input', { bubbles: true }));
7252
+ }
7253
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NumberLocaleService, deps: [{ token: LOCALE_ID }], target: i0.ɵɵFactoryTarget.Injectable });
7254
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NumberLocaleService, providedIn: 'root' });
7255
+ }
7256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NumberLocaleService, decorators: [{
7257
+ type: Injectable,
7258
+ args: [{ providedIn: 'root' }]
7259
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
7260
+ type: Inject,
7261
+ args: [LOCALE_ID]
7262
+ }] }] });
7263
+
7167
7264
  class InputTextComponent extends BaseInputComponent {
7168
7265
  formComponent;
7169
7266
  changeDetector;
7170
7267
  overlayService;
7268
+ _numberLocale;
7171
7269
  formUserChangeListener;
7172
7270
  ngZoneWrapper;
7173
7271
  elementRef;
@@ -7243,6 +7341,26 @@ class InputTextComponent extends BaseInputComponent {
7243
7341
  get model() {
7244
7342
  return super.model;
7245
7343
  }
7344
+ // keep the display string in sync when the model changes from outside typing (init / programmatic)
7345
+ modelSet() {
7346
+ if (this.digitsOnly && !this._userTyping) {
7347
+ this._displayValue = this._numberLocale.format(this.model);
7348
+ }
7349
+ }
7350
+ // For digitsOnly the input is a text field showing a locale-formatted string; parse it back to a number
7351
+ // before emitting so the model (and thus what is stored) stays numeric. Other types emit the raw value.
7352
+ handleInputModelChange(value) {
7353
+ if (this.digitsOnly) {
7354
+ this._userTyping = true;
7355
+ this._displayValue = value === null || value === undefined ? '' : '' + value;
7356
+ const parsed = this._numberLocale.parse(value);
7357
+ this.modelChange.emit(isNaN(parsed) ? null : parsed);
7358
+ this._userTyping = false;
7359
+ }
7360
+ else {
7361
+ this.modelChange.emit(value);
7362
+ }
7363
+ }
7246
7364
  get pipedModel() {
7247
7365
  if (this.formatPipe) {
7248
7366
  try {
@@ -7254,16 +7372,23 @@ class InputTextComponent extends BaseInputComponent {
7254
7372
  }
7255
7373
  return this.model;
7256
7374
  }
7375
+ // Locale-formatted string bound to the input when digitsOnly (comma for nl-NL); the model stays numeric.
7376
+ get displayValue() {
7377
+ return this._displayValue;
7378
+ }
7257
7379
  isFocusedOnDate = false;
7258
7380
  weekInputBuffer = '';
7259
7381
  isWeekInputMode = false;
7260
7382
  _isLeftIconMouseDown = false;
7261
7383
  _isRightIconMouseDown = false;
7262
- constructor(formComponent, changeDetector, overlayService, formUserChangeListener, ngZoneWrapper, elementRef) {
7384
+ _userTyping = false;
7385
+ _displayValue = '';
7386
+ constructor(formComponent, changeDetector, overlayService, _numberLocale, formUserChangeListener, ngZoneWrapper, elementRef) {
7263
7387
  super(changeDetector, overlayService, formUserChangeListener, ngZoneWrapper, elementRef);
7264
7388
  this.formComponent = formComponent;
7265
7389
  this.changeDetector = changeDetector;
7266
7390
  this.overlayService = overlayService;
7391
+ this._numberLocale = _numberLocale;
7267
7392
  this.formUserChangeListener = formUserChangeListener;
7268
7393
  this.ngZoneWrapper = ngZoneWrapper;
7269
7394
  this.elementRef = elementRef;
@@ -7343,6 +7468,10 @@ class InputTextComponent extends BaseInputComponent {
7343
7468
  if (this.type === 'date') {
7344
7469
  this.isFocusedOnDate = false;
7345
7470
  }
7471
+ if (this.digitsOnly) {
7472
+ // normalize the display once editing stops (e.g. "12," -> "12")
7473
+ this._displayValue = this._numberLocale.format(this.model);
7474
+ }
7346
7475
  this.isFocused.emit(false);
7347
7476
  }
7348
7477
  handleDoFocus(event) {
@@ -7350,14 +7479,21 @@ class InputTextComponent extends BaseInputComponent {
7350
7479
  this.doFocus(event);
7351
7480
  }
7352
7481
  }
7482
+ // For digitsOnly the field is a text input and precision/scale is enforced in keydown; the native
7483
+ // maxlength would wrongly count the decimal separator as a character. Plain text keeps native maxlength.
7484
+ _setNativeMaxLength(maxlength) {
7485
+ if (this.digitsOnly) {
7486
+ return;
7487
+ }
7488
+ super._setNativeMaxLength(maxlength);
7489
+ }
7353
7490
  clearInput(event) {
7354
7491
  this.setModel(null);
7355
7492
  this.keepFocus = true;
7356
- this.shouldCommit = false;
7357
7493
  this.clearIconClick.emit(event);
7358
7494
  }
7359
7495
  handleKeyDownInput(event) {
7360
- const key = event.key.toLowerCase();
7496
+ const key = event.key ? event.key.toLowerCase() : '';
7361
7497
  if (this.type === 'date') {
7362
7498
  if (key === 'w') {
7363
7499
  event.preventDefault();
@@ -7389,16 +7525,39 @@ class InputTextComponent extends BaseInputComponent {
7389
7525
  }
7390
7526
  }
7391
7527
  if (this.digitsOnly && !this.isWeekInputMode) {
7392
- const excludedKeys = this.excludePlusMinus ? ['e', '-', '+'] : ['e'];
7393
- if (excludedKeys.includes(event.key)) {
7394
- event.preventDefault();
7528
+ // the field is a text input (so a locale comma is allowed), so actively permit only numeric characters
7529
+ if (key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
7530
+ const isDigit = /\d/.test(event.key);
7531
+ const isSeparator = event.key === '.' || event.key === ',';
7532
+ const isSign = !this.excludePlusMinus && (event.key === '-' || event.key === '+');
7533
+ if (!isDigit && !isSeparator && !isSign) {
7534
+ event.preventDefault();
7535
+ return;
7536
+ }
7537
+ if (isSeparator) {
7538
+ // only one decimal separator, and only the locale one: normalize a foreign '.'/',' to it
7539
+ if (/[.,]/.test(this.input?.value ?? '')) {
7540
+ event.preventDefault();
7541
+ return;
7542
+ }
7543
+ if (key !== this._numberLocale.decimalSeparator) {
7544
+ event.preventDefault();
7545
+ if (this.input) {
7546
+ this._numberLocale.insertDecimalSeparator(this.input);
7547
+ }
7548
+ return;
7549
+ }
7550
+ }
7395
7551
  }
7396
7552
  }
7397
- const value = String(this.model ?? "");
7398
- if (this.type === "number" &&
7399
- this.maxLength > 0 &&
7400
- value.length >= this.maxLength &&
7401
- /^\d$/.test(key)) {
7553
+ // Native <input> ignores maxlength on numeric inputs, so enforce maxLength (as precision) and
7554
+ // decimals (as scale) ourselves for digit keys. Non-numeric text inputs keep the native maxlength.
7555
+ // Read the live element value (not this.model): a numeric input reports "" for an in-progress value
7556
+ // like "1234567.", so this.model would still hold "1234567" and wrongly block the first decimal digit.
7557
+ const currentText = this.input ? this.input.value : String(this.model ?? "");
7558
+ if ((this.digitsOnly || this.type === "number") &&
7559
+ /^\d$/.test(key) &&
7560
+ NumberUtils.WouldExceedDigitLimits(currentText, this.maxLength, this.decimals)) {
7402
7561
  event.preventDefault();
7403
7562
  }
7404
7563
  }
@@ -7448,7 +7607,7 @@ class InputTextComponent extends BaseInputComponent {
7448
7607
  const day = String(date.getDate()).padStart(2, '0');
7449
7608
  return `${year}-${month}-${day}`;
7450
7609
  }
7451
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputTextComponent, deps: [{ token: FormComponent, optional: true }, { token: i0.ChangeDetectorRef }, { token: OverlayService }, { token: FormInputUserModelChangeListenerService }, { token: NgZoneWrapperService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
7610
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputTextComponent, deps: [{ token: FormComponent, optional: true }, { token: i0.ChangeDetectorRef }, { token: OverlayService }, { token: NumberLocaleService }, { token: FormInputUserModelChangeListenerService }, { token: NgZoneWrapperService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
7452
7611
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: InputTextComponent, isStandalone: false, selector: "co-input-text", inputs: { useContent: "useContent", placeholder: "placeholder", align: "align", type: "type", formatPipe: "formatPipe", min: "min", max: "max", pattern: "pattern", digitsOnly: "digitsOnly", excludePlusMinus: "excludePlusMinus", showClearButton: "showClearButton", keyDownWhiteList: "keyDownWhiteList", showPlaceholderOnFocus: "showPlaceholderOnFocus", leftIcon: "leftIcon", rightIcon: "rightIcon", leftIconData: "leftIconData", rightIconData: "rightIconData", selectOnFocus: "selectOnFocus", emptyPlace: "emptyPlace", firstDayOfWeek: "firstDayOfWeek", noStyle: "noStyle", hideArrowButtons: "hideArrowButtons", model: "model" }, outputs: { leftIconClick: "leftIconClick", leftIconMouseDown: "leftIconMouseDown", leftIconMouseUp: "leftIconMouseUp", rightIconClick: "rightIconClick", rightIconMouseDown: "rightIconMouseDown", rightIconMouseUp: "rightIconMouseUp", clearIconClick: "clearIconClick", isFocused: "isFocused" }, host: { listeners: { "document:pointerup": "handleDocumentPointerUp($event)", "document:pointercancel": "handleDocumentPointerUp($event)" }, properties: { "class.no-style": "this.noStyle", "class.hide-arrows": "this.hideArrowButtons", "class.isDate": "this.isDate", "class.co-input-text": "this.showClass", "class.has-left-icon": "this.hasLeftIcon", "class.has-right-icon": "this.hasRightIcon", "class.has-own-label": "this.hasOwnLabel" } }, providers: [
7453
7612
  OverlayService, {
7454
7613
  provide: SCREEN_CONFIG_ADAPTER_COMPONENT_INTERFACE_NAME,
@@ -7483,15 +7642,16 @@ class InputTextComponent extends BaseInputComponent {
7483
7642
  <input [class.show]="focused || !formatPipe" #input
7484
7643
  [class.input-input-hidden]="useContent"
7485
7644
  [ngClass]="align"
7486
- [type]="isWeekInputMode ? 'text' : (isFocusedOnDate || (hasValue && emptyPlace)) ? 'date' : (digitsOnly ? 'number' : (type === 'date' ? 'text' : type))"
7645
+ [type]="isWeekInputMode ? 'text' : (isFocusedOnDate || (hasValue && emptyPlace)) ? 'date' : (digitsOnly ? 'text' : (type === 'date' ? 'text' : type))"
7646
+ [attr.inputmode]="digitsOnly ? 'decimal' : null"
7487
7647
  [placeholder]="type === 'date' && !isFocusedOnDate ? '' : placeholder"
7488
7648
  [pattern]="type === 'date' ? pattern : undefined"
7489
- [ngModel]="model"
7649
+ [ngModel]="digitsOnly ? displayValue : model"
7490
7650
  [min]="(type === 'number' || type === 'date') && this.min ? this.min : undefined"
7491
7651
  [max]="(type === 'number' || type === 'date') && this.max ? this.max : undefined"
7492
7652
  [readonly]="readonly"
7493
7653
  [required]="required"
7494
- (ngModelChange)="modelChange.emit($event)"
7654
+ (ngModelChange)="handleInputModelChange($event)"
7495
7655
  (keydown)="handleKeyDownInput($event)"
7496
7656
  (keyup)="keyUp.emit($event)"
7497
7657
  (focusin)="handleInputFocus($event)"
@@ -7559,15 +7719,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
7559
7719
  <input [class.show]="focused || !formatPipe" #input
7560
7720
  [class.input-input-hidden]="useContent"
7561
7721
  [ngClass]="align"
7562
- [type]="isWeekInputMode ? 'text' : (isFocusedOnDate || (hasValue && emptyPlace)) ? 'date' : (digitsOnly ? 'number' : (type === 'date' ? 'text' : type))"
7722
+ [type]="isWeekInputMode ? 'text' : (isFocusedOnDate || (hasValue && emptyPlace)) ? 'date' : (digitsOnly ? 'text' : (type === 'date' ? 'text' : type))"
7723
+ [attr.inputmode]="digitsOnly ? 'decimal' : null"
7563
7724
  [placeholder]="type === 'date' && !isFocusedOnDate ? '' : placeholder"
7564
7725
  [pattern]="type === 'date' ? pattern : undefined"
7565
- [ngModel]="model"
7726
+ [ngModel]="digitsOnly ? displayValue : model"
7566
7727
  [min]="(type === 'number' || type === 'date') && this.min ? this.min : undefined"
7567
7728
  [max]="(type === 'number' || type === 'date') && this.max ? this.max : undefined"
7568
7729
  [readonly]="readonly"
7569
7730
  [required]="required"
7570
- (ngModelChange)="modelChange.emit($event)"
7731
+ (ngModelChange)="handleInputModelChange($event)"
7571
7732
  (keydown)="handleKeyDownInput($event)"
7572
7733
  (keyup)="keyUp.emit($event)"
7573
7734
  (focusin)="handleInputFocus($event)"
@@ -7618,7 +7779,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
7618
7779
  }]
7619
7780
  }], ctorParameters: () => [{ type: FormComponent, decorators: [{
7620
7781
  type: Optional
7621
- }] }, { type: i0.ChangeDetectorRef }, { type: OverlayService }, { type: FormInputUserModelChangeListenerService }, { type: NgZoneWrapperService }, { type: i0.ElementRef }], propDecorators: { useContent: [{
7782
+ }] }, { type: i0.ChangeDetectorRef }, { type: OverlayService }, { type: NumberLocaleService }, { type: FormInputUserModelChangeListenerService }, { type: NgZoneWrapperService }, { type: i0.ElementRef }], propDecorators: { useContent: [{
7622
7783
  type: Input
7623
7784
  }], placeholder: [{
7624
7785
  type: Input
@@ -9054,16 +9215,25 @@ class InputNumberPickerComponent extends BaseInputComponent {
9054
9215
  iconCacheService;
9055
9216
  overlayService;
9056
9217
  _ngZone;
9218
+ _numberLocale;
9057
9219
  ngZoneWrapper;
9058
9220
  elementRef;
9059
9221
  // @override
9060
9222
  set model(model) {
9061
9223
  this.setValue(model, true);
9062
9224
  super.model = model;
9225
+ // keep the display string in sync, unless the user is mid-typing (then their raw text is preserved)
9226
+ if (!this._userTyping) {
9227
+ this._displayValue = this._numberLocale.format(model);
9228
+ }
9063
9229
  }
9064
9230
  get model() {
9065
9231
  return super.model;
9066
9232
  }
9233
+ // Locale-formatted string bound to the native text input (comma for nl-NL); the model stays numeric.
9234
+ get displayValue() {
9235
+ return this._displayValue;
9236
+ }
9067
9237
  modelChangeOnEnter = true;
9068
9238
  showPermanentLabel = false;
9069
9239
  leftIconData;
@@ -9084,8 +9254,14 @@ class InputNumberPickerComponent extends BaseInputComponent {
9084
9254
  // @override Default true for us.
9085
9255
  noValidation = true;
9086
9256
  set decimals(decimals) {
9257
+ // Also store on the base so its precision/scale validator picks it up; a setter-only override
9258
+ // would otherwise shadow the inherited getter and make this.decimals read as undefined.
9259
+ super.decimals = decimals;
9087
9260
  this.numberLogic.decimals = decimals;
9088
9261
  }
9262
+ get decimals() {
9263
+ return super.decimals;
9264
+ }
9089
9265
  // @override
9090
9266
  modelChange = new EventEmitter();
9091
9267
  iconClick = new EventEmitter();
@@ -9105,6 +9281,8 @@ class InputNumberPickerComponent extends BaseInputComponent {
9105
9281
  plusSelected = false;
9106
9282
  _numberInputHasFocus = false;
9107
9283
  _changeFromButton = false;
9284
+ _userTyping = false;
9285
+ _displayValue = '';
9108
9286
  _numberLogicValueChangeSub;
9109
9287
  _delayBeforeStartAutoCountMs = 666;
9110
9288
  // the 'speed gears' for auto counting
@@ -9119,12 +9297,13 @@ class InputNumberPickerComponent extends BaseInputComponent {
9119
9297
  _autoCountTimeout;
9120
9298
  _stepIncrementTimeout;
9121
9299
  _startAutocountTimeout;
9122
- constructor(formComponent, iconCacheService, overlayService, _ngZone, changeDetector, formUserChangeListener, ngZoneWrapper, elementRef) {
9300
+ constructor(formComponent, iconCacheService, overlayService, _ngZone, changeDetector, formUserChangeListener, _numberLocale, ngZoneWrapper, elementRef) {
9123
9301
  super(changeDetector, overlayService, formUserChangeListener, ngZoneWrapper, elementRef);
9124
9302
  this.formComponent = formComponent;
9125
9303
  this.iconCacheService = iconCacheService;
9126
9304
  this.overlayService = overlayService;
9127
9305
  this._ngZone = _ngZone;
9306
+ this._numberLocale = _numberLocale;
9128
9307
  this.ngZoneWrapper = ngZoneWrapper;
9129
9308
  this.elementRef = elementRef;
9130
9309
  this._numberLogicValueChangeSub = this.numberLogic.valueChange.subscribe((value) => {
@@ -9174,13 +9353,40 @@ class InputNumberPickerComponent extends BaseInputComponent {
9174
9353
  if (this.myKeyDownWhiteList.find((k) => k === event.keyCode) === undefined) {
9175
9354
  return false;
9176
9355
  }
9356
+ const currentText = this.input ? this.input.value : String(this.model ?? '');
9357
+ if (event.key === '.' || event.key === ',') {
9358
+ // only one decimal separator, and only the locale one: normalize a foreign '.'/',' to it
9359
+ if (/[.,]/.test(currentText)) {
9360
+ return false;
9361
+ }
9362
+ if (event.key !== this._numberLocale.decimalSeparator) {
9363
+ if (this.input) {
9364
+ this._numberLocale.insertDecimalSeparator(this.input);
9365
+ }
9366
+ return false;
9367
+ }
9368
+ }
9369
+ // native text/number inputs ignore maxlength, so enforce maxLength (precision) and decimals (scale) here
9370
+ if (/^\d$/.test(event.key) && NumberUtils.WouldExceedDigitLimits(currentText, this.maxLength, this.decimals)) {
9371
+ return false;
9372
+ }
9373
+ }
9374
+ // precision/scale is enforced in keydown; the native maxlength on this text input would wrongly count
9375
+ // the decimal separator as a character (e.g. blocking "1234567,89" at maxLength 9), so don't set it.
9376
+ _setNativeMaxLength() {
9177
9377
  }
9178
9378
  handleBlur() {
9379
+ // normalize the display once editing stops (e.g. "12," -> "12", trailing zeros dropped)
9380
+ this._displayValue = this._numberLocale.format(this.model);
9179
9381
  this.modelChange.next(this.model);
9180
9382
  }
9181
- handleChangeModel(value) {
9383
+ handleChangeModel(text) {
9182
9384
  this._changeFromButton = false;
9183
- this.numberLogic.setValue(value);
9385
+ // preserve exactly what the user typed while they are typing (avoids caret jumps / eating the separator)
9386
+ this._userTyping = true;
9387
+ this._displayValue = text === null || text === undefined ? '' : '' + text;
9388
+ this.numberLogic.setValue(this._numberLocale.parse(text));
9389
+ this._userTyping = false;
9184
9390
  }
9185
9391
  // Note: recursive through setTimeout().
9186
9392
  doDecrementAuto() {
@@ -9282,7 +9488,7 @@ class InputNumberPickerComponent extends BaseInputComponent {
9282
9488
  break;
9283
9489
  }
9284
9490
  }
9285
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputNumberPickerComponent, deps: [{ token: FormComponent, optional: true }, { token: IconCacheService }, { token: OverlayService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: FormInputUserModelChangeListenerService }, { token: NgZoneWrapperService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
9491
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: InputNumberPickerComponent, deps: [{ token: FormComponent, optional: true }, { token: IconCacheService }, { token: OverlayService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: FormInputUserModelChangeListenerService }, { token: NumberLocaleService }, { token: NgZoneWrapperService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
9286
9492
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: InputNumberPickerComponent, isStandalone: false, selector: "co-input-number-picker", inputs: { model: "model", modelChangeOnEnter: "modelChangeOnEnter", showPermanentLabel: "showPermanentLabel", leftIconData: "leftIconData", min: "min", step: "step", max: "max", ngModelOptions: "ngModelOptions", minusIcon: "minusIcon", plusIcon: "plusIcon", buttonShowMode: "buttonShowMode", noValidation: "noValidation", decimals: "decimals" }, outputs: { modelChange: "modelChange", iconClick: "iconClick" }, host: { properties: { "class.has-icon": "this.leftIconData", "class.show-buttons-on-focus-only": "this.showButtonsOnFocusOnly", "class.has-label": "this.hasLabel", "class.co-input-number-picker": "this.showClass" } }, providers: [
9287
9493
  OverlayService, {
9288
9494
  provide: SCREEN_CONFIG_ADAPTER_COMPONENT_INTERFACE_NAME, useExisting: forwardRef(() => InputNumberPickerComponent)
@@ -9308,15 +9514,15 @@ class InputNumberPickerComponent extends BaseInputComponent {
9308
9514
  </div>
9309
9515
  <div class="input-wrapper">
9310
9516
  @if (showPermanentLabel) {
9311
- <span class='permanent-label' [textContent]="label"></span>
9517
+ <span class='permanent-label' [textContent]="label ?? ''"></span>
9312
9518
  }
9313
- <input type="number"
9519
+ <input type="text" inputmode="decimal"
9314
9520
  [tabIndex]="readonly ? -1 : 0"
9315
- [ngModel]="model"
9521
+ [ngModel]="displayValue"
9316
9522
  [readonly]="readonly"
9317
9523
  [disabled]="disabled"
9318
9524
  [required]="required"
9319
- [placeholder]="label"
9525
+ [placeholder]="label ?? ''"
9320
9526
  (ngModelChange)="handleChangeModel($event)"
9321
9527
  (keydown)="handleInputKeyDown($event)"
9322
9528
  (blur)="handleBlur()"/>
@@ -9330,7 +9536,7 @@ class InputNumberPickerComponent extends BaseInputComponent {
9330
9536
  (mouseup)="stopAutoCounting()" (mouseleave)="stopAutoCounting()"></co-button>
9331
9537
  }
9332
9538
  </div>
9333
- `, isInline: true, dependencies: [{ kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "component", type: IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
9539
+ `, isInline: true, dependencies: [{ kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "co-button", inputs: ["label", "iconData", "iconDataRight", "isToggleButton", "isToggled", "hidden", "disabled"], outputs: ["onClick", "clickedWhileDisabled", "isToggledChange"] }, { kind: "component", type: IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
9334
9540
  }
9335
9541
  __decorate([
9336
9542
  InputBoolean()
@@ -9357,15 +9563,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
9357
9563
  </div>
9358
9564
  <div class="input-wrapper">
9359
9565
  @if (showPermanentLabel) {
9360
- <span class='permanent-label' [textContent]="label"></span>
9566
+ <span class='permanent-label' [textContent]="label ?? ''"></span>
9361
9567
  }
9362
- <input type="number"
9568
+ <input type="text" inputmode="decimal"
9363
9569
  [tabIndex]="readonly ? -1 : 0"
9364
- [ngModel]="model"
9570
+ [ngModel]="displayValue"
9365
9571
  [readonly]="readonly"
9366
9572
  [disabled]="disabled"
9367
9573
  [required]="required"
9368
- [placeholder]="label"
9574
+ [placeholder]="label ?? ''"
9369
9575
  (ngModelChange)="handleChangeModel($event)"
9370
9576
  (keydown)="handleInputKeyDown($event)"
9371
9577
  (blur)="handleBlur()"/>
@@ -9397,7 +9603,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
9397
9603
  }] }, { type: IconCacheService, decorators: [{
9398
9604
  type: Inject,
9399
9605
  args: [IconCacheService]
9400
- }] }, { type: OverlayService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: FormInputUserModelChangeListenerService }, { type: NgZoneWrapperService }, { type: i0.ElementRef }], propDecorators: { model: [{
9606
+ }] }, { type: OverlayService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: FormInputUserModelChangeListenerService }, { type: NumberLocaleService }, { type: NgZoneWrapperService }, { type: i0.ElementRef }], propDecorators: { model: [{
9401
9607
  type: Input
9402
9608
  }], modelChangeOnEnter: [{
9403
9609
  type: Input
@@ -14110,7 +14316,7 @@ class ListOfValuesComponent extends BaseInputComponent {
14110
14316
  collectionLoadFn;
14111
14317
  collectionLoadFnProp;
14112
14318
  leftIconData;
14113
- searchPlaceholder;
14319
+ searchPlaceholder = '';
14114
14320
  searchDisabled = false;
14115
14321
  showChips = true;
14116
14322
  showClass() {
@@ -19483,8 +19689,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
19483
19689
  class HourSchedulingExpandableComponent {
19484
19690
  cdRef;
19485
19691
  eRef;
19692
+ iconCacheService;
19693
+ icons = CoreComponentsIcon;
19486
19694
  hourLabels = [];
19487
19695
  scheduledObjects = [];
19696
+ selectedHour;
19488
19697
  resizing = false;
19489
19698
  resizeDirection;
19490
19699
  initialY;
@@ -19513,6 +19722,7 @@ class HourSchedulingExpandableComponent {
19513
19722
  idProp; // Input for unique identifier property
19514
19723
  timeChangeEvent = new EventEmitter();
19515
19724
  newObjectPlanEvent = new EventEmitter();
19725
+ taskCreationEvent = new EventEmitter();
19516
19726
  moveBetweenCalendarsEvent = new EventEmitter();
19517
19727
  showClass = true;
19518
19728
  onResize(event) {
@@ -19523,9 +19733,10 @@ class HourSchedulingExpandableComponent {
19523
19733
  this.handleDeselectAll();
19524
19734
  }
19525
19735
  }
19526
- constructor(cdRef, eRef) {
19736
+ constructor(cdRef, eRef, iconCacheService) {
19527
19737
  this.cdRef = cdRef;
19528
19738
  this.eRef = eRef;
19739
+ this.iconCacheService = iconCacheService;
19529
19740
  }
19530
19741
  ngOnInit() {
19531
19742
  this.generateTimeBlocks();
@@ -19756,22 +19967,44 @@ class HourSchedulingExpandableComponent {
19756
19967
  }
19757
19968
  });
19758
19969
  }
19759
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HourSchedulingExpandableComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
19760
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: HourSchedulingExpandableComponent, isStandalone: false, selector: "co-hour-scheduling-expandable", inputs: { schedule: "schedule", startTimeProp: "startTimeProp", endTimeProp: "endTimeProp", objectsProp: "objectsProp", childProp: "childProp", customTemplate: "customTemplate", idProp: "idProp" }, outputs: { timeChangeEvent: "timeChangeEvent", newObjectPlanEvent: "newObjectPlanEvent", moveBetweenCalendarsEvent: "moveBetweenCalendarsEvent" }, host: { listeners: { "window:resize": "onResize($event)", "document:click": "clickOut($event)" }, properties: { "class.co-hour-scheduling-expandable": "this.showClass" } }, ngImport: i0, template: `
19970
+ selectHalfHourBlock(mouseEvent, hour, first = true) {
19971
+ mouseEvent.stopPropagation();
19972
+ if (!first) {
19973
+ hour = this.addHalfHour(hour);
19974
+ }
19975
+ this.selectedHour = hour;
19976
+ }
19977
+ handleHourTaskCreate(mouseEvent, hour, first = true) {
19978
+ mouseEvent.stopPropagation();
19979
+ if (!first) {
19980
+ hour = this.addHalfHour(hour);
19981
+ }
19982
+ this.taskCreationEvent.emit(hour);
19983
+ this.selectedHour = "";
19984
+ }
19985
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HourSchedulingExpandableComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: IconCacheService }], target: i0.ɵɵFactoryTarget.Component });
19986
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: HourSchedulingExpandableComponent, isStandalone: false, selector: "co-hour-scheduling-expandable", inputs: { schedule: "schedule", startTimeProp: "startTimeProp", endTimeProp: "endTimeProp", objectsProp: "objectsProp", childProp: "childProp", customTemplate: "customTemplate", idProp: "idProp" }, outputs: { timeChangeEvent: "timeChangeEvent", newObjectPlanEvent: "newObjectPlanEvent", taskCreationEvent: "taskCreationEvent", moveBetweenCalendarsEvent: "moveBetweenCalendarsEvent" }, host: { listeners: { "window:resize": "onResize($event)", "document:click": "clickOut($event)" }, properties: { "class.co-hour-scheduling-expandable": "this.showClass" } }, ngImport: i0, template: `
19761
19987
  <div class="wrapper">
19762
19988
  @for (hour of hourLabels; track hour) {
19763
19989
  <div class="time-block">
19764
19990
  <div class="hour-label"><span [textContent]="hour"></span></div>
19765
19991
  <div class="object-display">
19766
19992
  <div class="first-half-hour object-half"
19993
+ [class.selected]="selectedHour === hour"
19994
+ (click)="selectHalfHourBlock($event, hour)"
19767
19995
  (dragover)="allowDrop($event, hour)"
19768
19996
  (dragleave)="handleDragLeave($event)"
19769
19997
  (drop)="handleDrop($event, hour)">
19998
+ <co-icon class="toggle-icon" [class.visible]="selectedHour === hour" [icon]="icons.ListRegular" (click)="handleHourTaskCreate($event, hour)"></co-icon>
19770
19999
  </div>
19771
20000
  <div class="second-half-hour object-half"
20001
+ [class.selected]="selectedHour === this.addHalfHour(hour)"
19772
20002
  (dragover)="allowDrop($event, addHalfHour(hour))"
19773
20003
  (dragleave)="handleDragLeave($event)"
20004
+ (click)="selectHalfHourBlock($event, hour, false)"
19774
20005
  (drop)="handleDrop($event, addHalfHour(hour))">
20006
+ <co-icon class="toggle-icon" [class.visible]="selectedHour === this.addHalfHour(hour)" [icon]="icons.ListRegular" (click)="handleHourTaskCreate($event, hour, false)"></co-icon>
20007
+
19775
20008
  </div>
19776
20009
  </div>
19777
20010
  </div>
@@ -19797,7 +20030,7 @@ class HourSchedulingExpandableComponent {
19797
20030
 
19798
20031
  </div>
19799
20032
 
19800
- `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
20033
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "co-icon", inputs: ["icon", "iconData"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
19801
20034
  }
19802
20035
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HourSchedulingExpandableComponent, decorators: [{
19803
20036
  type: Component,
@@ -19810,14 +20043,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
19810
20043
  <div class="hour-label"><span [textContent]="hour"></span></div>
19811
20044
  <div class="object-display">
19812
20045
  <div class="first-half-hour object-half"
20046
+ [class.selected]="selectedHour === hour"
20047
+ (click)="selectHalfHourBlock($event, hour)"
19813
20048
  (dragover)="allowDrop($event, hour)"
19814
20049
  (dragleave)="handleDragLeave($event)"
19815
20050
  (drop)="handleDrop($event, hour)">
20051
+ <co-icon class="toggle-icon" [class.visible]="selectedHour === hour" [icon]="icons.ListRegular" (click)="handleHourTaskCreate($event, hour)"></co-icon>
19816
20052
  </div>
19817
20053
  <div class="second-half-hour object-half"
20054
+ [class.selected]="selectedHour === this.addHalfHour(hour)"
19818
20055
  (dragover)="allowDrop($event, addHalfHour(hour))"
19819
20056
  (dragleave)="handleDragLeave($event)"
20057
+ (click)="selectHalfHourBlock($event, hour, false)"
19820
20058
  (drop)="handleDrop($event, addHalfHour(hour))">
20059
+ <co-icon class="toggle-icon" [class.visible]="selectedHour === this.addHalfHour(hour)" [icon]="icons.ListRegular" (click)="handleHourTaskCreate($event, hour, false)"></co-icon>
20060
+
19821
20061
  </div>
19822
20062
  </div>
19823
20063
  </div>
@@ -19848,7 +20088,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
19848
20088
  encapsulation: ViewEncapsulation.None,
19849
20089
  standalone: false
19850
20090
  }]
19851
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { schedule: [{
20091
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: IconCacheService }], propDecorators: { schedule: [{
19852
20092
  type: Input
19853
20093
  }], startTimeProp: [{
19854
20094
  type: Input
@@ -19866,6 +20106,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
19866
20106
  type: Output
19867
20107
  }], newObjectPlanEvent: [{
19868
20108
  type: Output
20109
+ }], taskCreationEvent: [{
20110
+ type: Output
19869
20111
  }], moveBetweenCalendarsEvent: [{
19870
20112
  type: Output
19871
20113
  }], showClass: [{
@@ -20053,10 +20295,12 @@ class HourSchedulingExpandableComponentModule {
20053
20295
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HourSchedulingExpandableComponentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
20054
20296
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: HourSchedulingExpandableComponentModule, declarations: [HourSchedulingExpandableComponent], imports: [CommonModule,
20055
20297
  HourSchedulingComponentModule,
20056
- HourSchedulingExpandableTemplateModule], exports: [HourSchedulingExpandableComponent] });
20298
+ HourSchedulingExpandableTemplateModule,
20299
+ IconModule], exports: [HourSchedulingExpandableComponent] });
20057
20300
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HourSchedulingExpandableComponentModule, providers: [DatePipe], imports: [CommonModule,
20058
20301
  HourSchedulingComponentModule,
20059
- HourSchedulingExpandableTemplateModule] });
20302
+ HourSchedulingExpandableTemplateModule,
20303
+ IconModule] });
20060
20304
  }
20061
20305
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: HourSchedulingExpandableComponentModule, decorators: [{
20062
20306
  type: NgModule,
@@ -20064,7 +20308,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
20064
20308
  imports: [
20065
20309
  CommonModule,
20066
20310
  HourSchedulingComponentModule,
20067
- HourSchedulingExpandableTemplateModule
20311
+ HourSchedulingExpandableTemplateModule,
20312
+ IconModule
20068
20313
  ],
20069
20314
  declarations: [
20070
20315
  HourSchedulingExpandableComponent,