@messaia/cdk 22.0.0-rc.9 → 22.0.1-rc.1

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.
@@ -20,7 +20,7 @@ import { MatButtonModule, MatIconButton } from '@angular/material/button';
20
20
  import * as i4 from '@angular/material/icon';
21
21
  import { MatIcon, MatIconModule } from '@angular/material/icon';
22
22
  import * as i1$1 from '@angular/forms';
23
- import { FormsModule, FormArray, FormGroup, FormControl, NG_ASYNC_VALIDATORS, NG_VALUE_ACCESSOR, NG_VALIDATORS, AbstractControl, FormBuilder, ReactiveFormsModule, FormControlName, FormControlDirective, NgControl, NgForm, FormGroupDirective, ControlContainer, Validators } from '@angular/forms';
23
+ import { FormsModule, FormArray, FormGroup, FormControl, Validators, NG_ASYNC_VALIDATORS, NG_VALUE_ACCESSOR, NG_VALIDATORS, AbstractControl, FormBuilder, ReactiveFormsModule, FormControlName, FormControlDirective, NgControl, NgForm, FormGroupDirective, ControlContainer } from '@angular/forms';
24
24
  import * as i2$1 from '@angular/material/form-field';
25
25
  import { MatFormFieldModule, MatFormFieldControl } from '@angular/material/form-field';
26
26
  import * as i3 from '@angular/material/progress-bar';
@@ -67,6 +67,8 @@ import * as i4$2 from '@angular/material/autocomplete';
67
67
  import { MatAutocompleteModule, MatAutocomplete, MatAutocompleteTrigger, MAT_AUTOCOMPLETE_DEFAULT_OPTIONS } from '@angular/material/autocomplete';
68
68
  import * as i6 from '@angular/material/divider';
69
69
  import { MatDividerModule, MatDivider } from '@angular/material/divider';
70
+ import * as i10$1 from '@angular/material/progress-spinner';
71
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
70
72
  import { ENTER, COMMA } from '@angular/cdk/keycodes';
71
73
  import * as i3$4 from '@angular/material/radio';
72
74
  import { MatRadioModule } from '@angular/material/radio';
@@ -3837,6 +3839,10 @@ class ApplicationUtil {
3837
3839
  return regex;
3838
3840
  }
3839
3841
  static configureControl(control, config, type) {
3842
+ if (control && typeof control.setValidatorConfig === 'function') {
3843
+ control.setValidatorConfig(type, config);
3844
+ return;
3845
+ }
3840
3846
  if (!control.validatorConfig) {
3841
3847
  let jObject = {};
3842
3848
  jObject[type] = config;
@@ -4437,9 +4443,9 @@ class RxFormControl extends FormControl {
4437
4443
  _baseObject;
4438
4444
  _sanitizers;
4439
4445
  /**
4440
- * Current language used for error message localization.
4441
- * @type {string | undefined}
4442
- */
4446
+ * Current language used for error message localization.
4447
+ * @type {string | undefined}
4448
+ */
4443
4449
  _language;
4444
4450
  /**
4445
4451
  * The key or name of the control.
@@ -4521,6 +4527,16 @@ class RxFormControl extends FormControl {
4521
4527
  * @type {{ [key: string]: string }}
4522
4528
  */
4523
4529
  backEndErrors = {};
4530
+ /**
4531
+ * Persisted validator metadata indexed by validator name.
4532
+ * @type {{ [key: string]: any }}
4533
+ */
4534
+ _validatorConfigStore = {};
4535
+ /**
4536
+ * Runtime validator metadata consumed by existing template validation flow.
4537
+ * @type {{ [key: string]: any } | undefined}
4538
+ */
4539
+ validatorConfig;
4524
4540
  /**
4525
4541
  * Indicates if updating the control element's class should be performed.
4526
4542
  * @type {boolean | Function | undefined}
@@ -4542,16 +4558,26 @@ class RxFormControl extends FormControl {
4542
4558
  * @type {string[]}
4543
4559
  */
4544
4560
  get errorMessages() {
4561
+ /* If no message expression is configured, rely on standard error generation. */
4545
4562
  if (!this._messageExpression) {
4546
- if (this._errorMessages.length == 0 && this.errors)
4563
+ /* Build messages on demand when errors exist and cache is empty. */
4564
+ if (this._errorMessages.length == 0 && this.errors) {
4547
4565
  this.setControlErrorMessages();
4566
+ }
4548
4567
  }
4549
- else if (this._messageExpression && !this._isPassedExpression)
4568
+ /* If expression mode is enabled but not passed, hide all messages. */
4569
+ else if (this._messageExpression && !this._isPassedExpression) {
4550
4570
  return [];
4551
- if (!this.errors && this._errorMessages.length > 0)
4571
+ }
4572
+ /* If errors were cleared, reset message cache accordingly. */
4573
+ if (!this.errors && this._errorMessages.length > 0) {
4552
4574
  this.setControlErrorMessages();
4553
- if (this._language != this.getLanguage())
4575
+ }
4576
+ /* If language changed, rebuild translated messages. */
4577
+ if (this._language != this.getLanguage()) {
4554
4578
  this.setControlErrorMessages();
4579
+ }
4580
+ /* Return the computed error message list. */
4555
4581
  return this._errorMessages;
4556
4582
  }
4557
4583
  /**
@@ -4561,32 +4587,53 @@ class RxFormControl extends FormControl {
4561
4587
  * @type {string | undefined}
4562
4588
  */
4563
4589
  get errorMessage() {
4590
+ /* If no message expression is configured, rely on standard error generation. */
4564
4591
  if (!this._messageExpression) {
4592
+ /* Build single message lazily when errors exist and cache is empty. */
4565
4593
  if (this._errorMessage == undefined && this.errors) {
4566
4594
  this.setControlErrorMessages();
4567
4595
  }
4568
4596
  }
4597
+ /* If expression mode is enabled but not passed, hide message output. */
4569
4598
  else if (this._messageExpression && !this._isPassedExpression) {
4570
4599
  return undefined;
4571
4600
  }
4601
+ /* If errors were cleared, reset single-message cache accordingly. */
4572
4602
  if (!this.errors && this._errorMessage) {
4573
4603
  this.setControlErrorMessages();
4574
4604
  }
4605
+ /* If language changed, rebuild translated single message. */
4575
4606
  if (this._language != this.getLanguage()) {
4576
4607
  this.setControlErrorMessages();
4577
4608
  }
4609
+ /* Return the computed single error message. */
4578
4610
  return this._errorMessage;
4579
4611
  }
4580
4612
  /**
4581
4613
  * Gets the associated entity object.
4582
4614
  * @type {any}
4583
4615
  */
4584
- get entityObject() { return this._entityObject; }
4616
+ get entityObject() {
4617
+ /* Return the entity object linked to this control instance. */
4618
+ return this._entityObject;
4619
+ }
4585
4620
  /**
4586
4621
  * Gets the base object for comparison or reset.
4587
4622
  * @type {any}
4588
4623
  */
4589
- get baseObject() { return this._baseObject; }
4624
+ get baseObject() {
4625
+ /* Return the base object used for dirty/modified comparisons. */
4626
+ return this._baseObject;
4627
+ }
4628
+ /**
4629
+ * @method isModified
4630
+ * @description Gets whether the control value is modified compared to its base value.
4631
+ * @returns {boolean} True when the control has been modified.
4632
+ */
4633
+ get isModified() {
4634
+ /* Return whether the current control value differs from the stored base value. */
4635
+ return this._isModified;
4636
+ }
4590
4637
  /**
4591
4638
  * Constructor to initialize RxFormControl.
4592
4639
  * @param formState Initial state or value of the control.
@@ -4597,301 +4644,715 @@ class RxFormControl extends FormControl {
4597
4644
  * @param _sanitizers Array of data sanitizers to preprocess values.
4598
4645
  */
4599
4646
  constructor(formState, validatorOrOpts, _entityObject, _baseObject, controlName, _sanitizers) {
4647
+ /* Delegate base control construction to Angular FormControl. */
4600
4648
  super(formState, validatorOrOpts);
4601
4649
  this._entityObject = _entityObject;
4602
4650
  this._baseObject = _baseObject;
4603
4651
  this._sanitizers = _sanitizers;
4652
+ /* Patch errors property behavior for localization-aware recalculation. */
4604
4653
  this.defineErrorsProperty();
4654
+ /* Capture initial/base value snapshot for modified-state comparisons. */
4605
4655
  this._baseValue = formState === undefined ? null : this.getFormState(formState);
4656
+ /* Initialize modified-state flag. */
4606
4657
  this._isModified = false;
4658
+ /* Store control key name. */
4607
4659
  this.keyName = controlName;
4660
+ /* Cache synchronous validators for later probing and metadata checks. */
4608
4661
  this._validators = validatorOrOpts.validators;
4662
+ /* Cache asynchronous validators for later inspection. */
4609
4663
  this._asyncValidators = validatorOrOpts.asyncValidators;
4664
+ /* Resolve configured error-message binding strategy. */
4610
4665
  this._errorMessageBindingStrategy = ReactiveFormConfig.get("reactiveForm.errorMessageBindingStrategy");
4666
+ /* Apply number-format bootstrap conversion when float sanitizer is configured. */
4611
4667
  if (this._sanitizers) {
4668
+ /* Find float sanitizer configuration. */
4612
4669
  var floatSanitizer = this._sanitizers.filter(t => t.name == "toFloat")[0];
4670
+ /* Convert decimal symbol in base value if locale uses commas. */
4613
4671
  if (floatSanitizer && this._baseValue && ReactiveFormConfig.number && ReactiveFormConfig.number["decimalSymbol"] == ",") {
4672
+ /* Stringify base value for symbol replacement. */
4614
4673
  let baseValue = String(this._baseValue);
4674
+ /* Replace decimal point only when present. */
4615
4675
  if (baseValue.indexOf('.') != -1) {
4676
+ /* Store converted base value using configured decimal symbol. */
4616
4677
  this._baseValue = baseValue.replace(".", ReactiveFormConfig.number["decimalSymbol"]);
4678
+ /* Keep underlying FormControl value synchronized with converted base value. */
4617
4679
  super.setValue(this._baseValue);
4618
4680
  }
4619
4681
  }
4620
4682
  }
4621
4683
  }
4684
+ /**
4685
+ * Defines a getter and setter for the 'errors' property to handle dynamic error message updates.
4686
+ * This allows the control to re-evaluate its errors when the language changes or when validation is triggered.
4687
+ * @returns {void}
4688
+ */
4622
4689
  defineErrorsProperty() {
4690
+ /* Redefine errors access so language changes can force validator re-evaluation lazily. */
4623
4691
  Object.defineProperty(this, "errors", {
4624
4692
  configurable: true,
4625
4693
  get() {
4694
+ /* Recompute errors when language changes and validator exists. */
4626
4695
  if (this._language && this._language != this.getLanguage() && this.validator) {
4627
4696
  this["errors"] = this.validator(this);
4628
4697
  }
4698
+ /* Return backing error store value. */
4629
4699
  return this._errors;
4630
4700
  },
4701
+ /* Persist assigned errors into backing store. */
4631
4702
  set(value) { this._errors = value; },
4632
4703
  });
4633
4704
  }
4705
+ /**
4706
+ * Gets the current language for error message localization.
4707
+ * @param value Optional value to determine the language context.
4708
+ * @returns {string | undefined} The current language code.
4709
+ */
4634
4710
  getFormState(value) {
4711
+ /* Clone arrays to avoid mutating the original form-state reference. */
4712
+ /* Start from incoming value. */
4635
4713
  let baseValue = value;
4714
+ /* Clone arrays to prevent shared reference mutation. */
4636
4715
  if (Array.isArray(value)) {
4637
4716
  baseValue = [];
4717
+ /* Copy each array item into new base-value array. */
4638
4718
  value.forEach(t => baseValue.push(t));
4639
4719
  }
4720
+ /* Return normalized base-state value. */
4640
4721
  return baseValue;
4641
4722
  }
4642
- get isModified() {
4643
- return this._isModified;
4644
- }
4723
+ /**
4724
+ * @method getValidators
4725
+ * @description Returns a shallow copy of synchronous validators.
4726
+ * @returns {ValidatorFn[]} Synchronous validator functions.
4727
+ */
4645
4728
  getValidators() {
4729
+ /* Return a normalized copy of synchronous validators. */
4646
4730
  return this.getValidatorSource(this._validators);
4647
4731
  }
4732
+ /**
4733
+ * @method getAsyncValidators
4734
+ * @description Returns a shallow copy of asynchronous validators.
4735
+ * @returns {AsyncValidatorFn[]} Asynchronous validator functions.
4736
+ */
4648
4737
  getAsyncValidators() {
4738
+ /* Return a normalized copy of asynchronous validators. */
4649
4739
  return this.getValidatorSource(this._asyncValidators);
4650
4740
  }
4741
+ /**
4742
+ * @method setValidatorConfig
4743
+ * @description Persists validator configuration metadata by validator type.
4744
+ * @param {string} type Validator name.
4745
+ * @param {any} config Validator configuration object.
4746
+ */
4747
+ setValidatorConfig(type, config) {
4748
+ /* Persist normalized validator configuration and keep compatibility with validatorConfig consumers. */
4749
+ const normalizedConfig = config === '' || config === undefined || config === null ? true : config;
4750
+ this._validatorConfigStore[type] = normalizedConfig;
4751
+ this.validatorConfig = this._validatorConfigStore;
4752
+ }
4753
+ /**
4754
+ * @method getValidatorConfig
4755
+ * @description Returns persisted validator configuration by validator name.
4756
+ * @param {string} type Validator name.
4757
+ * @returns {any} Validator configuration value.
4758
+ */
4759
+ getValidatorConfig(type) {
4760
+ /* Return persisted metadata for a specific validator type. */
4761
+ return this._validatorConfigStore[type];
4762
+ }
4763
+ /**
4764
+ * @method isRequiredActive
4765
+ * @description Evaluates whether required validation is currently active, including dynamic conditional expressions.
4766
+ * @returns {boolean} True when required is active for this control.
4767
+ */
4768
+ isRequiredActive() {
4769
+ /* Check if the control has a native required validator. */
4770
+ const nativeRequired = typeof this.hasValidator === 'function' ? this.hasValidator(Validators.required) : false;
4771
+ /* Check if the control has a persisted required configuration. If not, probe the validators to determine if required is active. */
4772
+ const requiredConfig = this.getValidatorConfig('required');
4773
+ /* If no persisted configuration exists, probe the validators to determine if required is active. */
4774
+ if (requiredConfig === undefined) {
4775
+ /* Get the list of synchronous validators for this control. */
4776
+ const validators = this.getValidators();
4777
+ /* Check if any of the validators return a required error when evaluated with a probe control. */
4778
+ const requiredByProbe = validators.some((validator) => {
4779
+ try {
4780
+ /* Create a probe control to evaluate the validator without affecting the actual control state. */
4781
+ const probe = Object.create(this);
4782
+ /* Define a temporary value for the probe control to evaluate the validator. */
4783
+ Object.defineProperty(probe, 'value', {
4784
+ configurable: true,
4785
+ enumerable: true,
4786
+ value: null,
4787
+ writable: true
4788
+ });
4789
+ /* Evaluate the validator with the probe control and check if it returns a required error. */
4790
+ const result = validator(probe);
4791
+ /* Return true if the validator indicates that required validation is active. */
4792
+ return !!(result && result['required']);
4793
+ }
4794
+ catch {
4795
+ return false;
4796
+ }
4797
+ });
4798
+ /* Return true if either the native required validator is present or if any of the validators indicate that required validation is active. */
4799
+ return nativeRequired || requiredByProbe;
4800
+ }
4801
+ /* If a persisted required configuration exists, evaluate it to determine if required validation is active. */
4802
+ if (typeof requiredConfig === 'boolean') {
4803
+ return nativeRequired || requiredConfig;
4804
+ }
4805
+ /* If the persisted required configuration is an object, evaluate it using the FormProvider to determine if required validation is active. */
4806
+ if (requiredConfig && typeof requiredConfig === 'object') {
4807
+ return nativeRequired || !!FormProvider.processRule(this, requiredConfig);
4808
+ }
4809
+ /* Fallback to return true if either the native required validator is present or if the persisted required configuration is truthy. */
4810
+ return nativeRequired || !!requiredConfig;
4811
+ }
4812
+ /**
4813
+ * @method getValidatorSource
4814
+ * @description Normalizes validator input to an array copy.
4815
+ * @param {any[]} validators Validator value or array to normalize.
4816
+ * @returns {any[]} Array of validators.
4817
+ */
4651
4818
  getValidatorSource(validators) {
4652
- if (validators)
4819
+ /* Normalize validators into an array to simplify downstream iteration. */
4820
+ if (validators) {
4653
4821
  return Array.isArray(validators) ? [...validators] : [validators];
4822
+ }
4654
4823
  return [];
4655
4824
  }
4825
+ /**
4826
+ * @method setValidators
4827
+ * @description Sets synchronous validators and stores the source list.
4828
+ * @param {ValidatorFn | ValidatorFn[] | null} newValidator Validator or validators to assign.
4829
+ * @returns {void}
4830
+ */
4656
4831
  setValidators(newValidator) {
4832
+ /* Cache synchronous validators locally before delegating to Angular base implementation. */
4657
4833
  this._validators = newValidator;
4658
4834
  super.setValidators(newValidator);
4659
4835
  }
4836
+ /**
4837
+ * @method setAsyncValidators
4838
+ * @description Sets asynchronous validators and stores the source list.
4839
+ * @param {AsyncValidatorFn | AsyncValidatorFn[] | null} newValidator Async validator or validators to assign.
4840
+ * @returns {void}
4841
+ */
4660
4842
  setAsyncValidators(newValidator) {
4843
+ /* Cache asynchronous validators locally before delegating to Angular base implementation. */
4661
4844
  this._asyncValidators = newValidator;
4662
4845
  super.setAsyncValidators(newValidator);
4663
4846
  }
4847
+ /**
4848
+ * @method setValue
4849
+ * @description Sets control value, synchronizes entity/base objects, and runs expression hooks.
4850
+ * @param {any} value New control value.
4851
+ * @param {{ dirty?: boolean; updateChanged?: boolean; onlySelf?: boolean; emitEvent?: boolean; isThroughDynamic?: boolean; }} options Optional behavior flags.
4852
+ * @returns {void}
4853
+ */
4664
4854
  setValue(value, options) {
4855
+ /* Synchronize value into entity/base structures, then run expression and patch hooks. */
4856
+ /* Mark parent as currently changing to avoid recursive side effects. */
4665
4857
  this.parent.changing = true;
4858
+ /* Sanitize incoming value before storing into bound entity object. */
4666
4859
  let parsedValue = this.getSanitizedValue(value);
4667
- if (options && options.dirty)
4860
+ /* If requested, update the base object snapshot with raw value. */
4861
+ if (options && options.dirty) {
4668
4862
  this._baseObject[this.keyName] = value;
4863
+ }
4864
+ /* Store sanitized value into bound entity model. */
4669
4865
  this._entityObject[this.keyName] = parsedValue;
4866
+ /* Delegate actual control value update to base class implementation. */
4670
4867
  super.setValue(value, options);
4868
+ /* Recompute and bind error messages after value change. */
4671
4869
  this.bindError();
4870
+ /* Recompute and bind dynamic class output after value change. */
4672
4871
  this.bindClassName();
4872
+ /* Execute conditional decorator expressions tied to this control. */
4673
4873
  this.executeExpressions();
4874
+ /* Recompute modified state and invoke parent patch callback. */
4674
4875
  this.callPatch();
4876
+ /* Notify root value-changed synchronization hook when enabled. */
4675
4877
  if (options && !options.updateChanged && this.root[VALUE_CHANGED_SYNC]) {
4676
4878
  this.root[VALUE_CHANGED_SYNC]();
4677
4879
  }
4880
+ /* Clear parent changing marker after update pipeline completes. */
4678
4881
  this.parent.changing = false;
4679
4882
  }
4883
+ /**
4884
+ * @method getControlValue
4885
+ * @description Returns the sanitized current control value.
4886
+ * @returns {any} Sanitized control value.
4887
+ */
4680
4888
  getControlValue() {
4889
+ /* Return sanitized value representation for external consumers. */
4681
4890
  return this.getSanitizedValue(this.value);
4682
4891
  }
4892
+ /**
4893
+ * @method bindError
4894
+ * @description Re-evaluates message expression and refreshes computed errors.
4895
+ * @returns {void}
4896
+ */
4683
4897
  bindError() {
4684
- if (this._messageExpression)
4898
+ /* Evaluate error expression gates and refresh computed errors cache. */
4899
+ if (this._messageExpression) {
4685
4900
  this._isPassedExpression = this.executeExpression(this._messageExpression, this);
4901
+ }
4902
+ /* Recompute error messages based on current errors and language context. */
4686
4903
  this.setControlErrorMessages();
4687
- var t = this;
4688
- t["errors"] = this.errors;
4904
+ /* Update the language cache to reflect current language context. */
4905
+ var self = this;
4906
+ /* Update the errors property to trigger any dependent bindings or observers. */
4907
+ self["errors"] = this.errors;
4689
4908
  }
4909
+ /**
4910
+ * @method bindClassName
4911
+ * @description Evaluates and applies dynamic CSS class output for the control element.
4912
+ * @returns {void}
4913
+ */
4690
4914
  bindClassName() {
4915
+ /* Evaluate and publish dynamic class-name output when a callback is configured. */
4691
4916
  if (this.updateOnElementClass && typeof this.updateOnElementClass === "function") {
4692
4917
  let className = this.executeExpression(this._classNameExpression, this);
4693
4918
  let updateElement = this.updateOnElementClass;
4694
4919
  updateElement(className);
4695
4920
  }
4696
4921
  }
4922
+ /**
4923
+ * @method setBackEndErrors
4924
+ * @description Assigns backend validation errors to the control and updates visible messages.
4925
+ * @param {{ [key: string]: string }} error Backend error map.
4926
+ * @returns {void}
4927
+ */
4697
4928
  setBackEndErrors(error) {
4929
+ /* Merge backend errors into local storage and recompute visible messages. */
4698
4930
  Object.keys(error).forEach(key => this.backEndErrors[key] = error[key]);
4931
+ /* Recompute visible error messages after backend error assignment. */
4699
4932
  this.setControlErrorMessages();
4700
4933
  }
4934
+ /**
4935
+ * @method clearBackEndErrors
4936
+ * @description Clears all backend errors or selected backend error keys.
4937
+ * @param {{ [key: string]: any } | undefined} errors Optional map of keys to remove.
4938
+ * @returns {void}
4939
+ */
4701
4940
  clearBackEndErrors(errors) {
4702
- if (!errors)
4941
+ /* Remove all or selected backend errors, then refresh message state. */
4942
+ if (!errors) {
4703
4943
  this.backEndErrors = {};
4704
- else
4944
+ }
4945
+ else {
4705
4946
  Object.keys(errors).forEach(t => delete this.backEndErrors[t]);
4947
+ }
4948
+ /* Recompute visible error messages after backend error clearance. */
4706
4949
  this.setControlErrorMessages();
4707
4950
  }
4951
+ /**
4952
+ * @method markAsTouched
4953
+ * @description Marks control as touched and triggers dependent expression refreshes on state change.
4954
+ * @param {{ onlySelf?: boolean } | undefined} opts Angular control options.
4955
+ * @returns {void}
4956
+ */
4708
4957
  markAsTouched(opts) {
4958
+ /* Trigger dependent expression updates only when touched state actually changes. */
4709
4959
  let currentState = this.touched;
4710
4960
  super.markAsTouched(opts);
4711
- if (currentState != this.touched)
4961
+ if (currentState != this.touched) {
4712
4962
  this.runControlPropChangeExpression([TOUCHED, UNTOUCHED]);
4963
+ }
4713
4964
  }
4965
+ /**
4966
+ * @method markAsUntouched
4967
+ * @description Marks control as untouched and triggers dependent expression refreshes on state change.
4968
+ * @param {{ onlySelf?: boolean } | undefined} opts Angular control options.
4969
+ * @returns {void}
4970
+ */
4714
4971
  markAsUntouched(opts) {
4972
+ /* Trigger dependent expression updates only when untouched state actually changes. */
4715
4973
  let currentState = this.untouched;
4716
4974
  super.markAsUntouched(opts);
4717
- if (currentState != this.untouched)
4975
+ if (currentState != this.untouched) {
4718
4976
  this.runControlPropChangeExpression([UNTOUCHED, TOUCHED]);
4977
+ }
4719
4978
  }
4979
+ /**
4980
+ * @method markAsDirty
4981
+ * @description Marks control as dirty and triggers dependent expression refreshes on state change.
4982
+ * @param {{ onlySelf?: boolean } | undefined} opts Angular control options.
4983
+ * @returns {void}
4984
+ */
4720
4985
  markAsDirty(opts) {
4986
+ /* Keep custom dirty flag in sync and propagate expression updates when needed. */
4721
4987
  let currentState = this._dirty;
4722
4988
  super.markAsDirty(opts);
4723
4989
  this._dirty = true;
4724
- if (currentState != this._dirty)
4990
+ if (currentState != this._dirty) {
4725
4991
  this.runControlPropChangeExpression([DIRTY]);
4992
+ }
4726
4993
  }
4994
+ /**
4995
+ * @method markAsPristine
4996
+ * @description Marks control as pristine and triggers dependent expression refreshes on state change.
4997
+ * @param {{ onlySelf?: boolean } | undefined} opts Angular control options.
4998
+ * @returns {void}
4999
+ */
4727
5000
  markAsPristine(opts) {
5001
+ /* Propagate expression updates only when pristine state actually changes. */
4728
5002
  let currentState = this.pristine;
4729
5003
  super.markAsPristine(opts);
4730
- if (currentState != this.pristine)
5004
+ if (currentState != this.pristine) {
4731
5005
  this.runControlPropChangeExpression([PRISTINE]);
5006
+ }
4732
5007
  }
5008
+ /**
5009
+ * @method markAsPending
5010
+ * @description Marks control pending via base flow and triggers dependent expression refreshes on state change.
5011
+ * @param {{ onlySelf?: boolean; emitEvent?: boolean } | undefined} opts Angular control options.
5012
+ * @returns {void}
5013
+ */
4733
5014
  markAsPending(opts) {
5015
+ /* Propagate expression updates only when pending state actually changes. */
4734
5016
  let currentState = this.pending;
4735
5017
  super.markAsDirty(opts);
4736
- if (currentState != this.pending)
5018
+ if (currentState != this.pending) {
4737
5019
  this.runControlPropChangeExpression([PENDING]);
5020
+ }
4738
5021
  }
5022
+ /**
5023
+ * @method runControlPropChangeExpression
5024
+ * @description Executes error/class expression updates for changed control state flags.
5025
+ * @param {string[]} propNames State property names to evaluate.
5026
+ * @returns {void}
5027
+ */
4739
5028
  runControlPropChangeExpression(propNames) {
5029
+ /* Re-run mapped error/class expressions for each changed control-state property. */
4740
5030
  propNames.forEach(name => {
4741
- if ((this._controlProp && this._messageExpression && this._controlProp[name]) || (!this._messageExpression && this.checkErrorMessageStrategy()))
5031
+ /* Refresh errors when property is tracked by message-expression dependencies. */
5032
+ if ((this._controlProp && this._messageExpression && this._controlProp[name]) || (!this._messageExpression && this.checkErrorMessageStrategy())) {
4742
5033
  this.bindError();
4743
- if (this._classNameControlProp && this._classNameControlProp[name])
5034
+ }
5035
+ /* Refresh class names when property is tracked by class-expression dependencies. */
5036
+ if (this._classNameControlProp && this._classNameControlProp[name]) {
4744
5037
  this.bindClassName();
5038
+ }
4745
5039
  });
4746
5040
  }
5041
+ /**
5042
+ * @method refresh
5043
+ * @description Rebuilds decorator expressions and refreshes current error state.
5044
+ * @returns {void}
5045
+ */
4747
5046
  refresh() {
5047
+ /* Rebind expressions and conditional controls, then refresh current error state. */
5048
+ /* Reload expression metadata from model container. */
4748
5049
  this.getMessageExpression(this.parent, this.keyName);
5050
+ /* Rebuild disabled-expression control references. */
4749
5051
  this.bindConditionalControls(DECORATORS["disabled"], "_refDisableControls");
5052
+ /* Rebuild error-expression control references. */
4750
5053
  this.bindConditionalControls(DECORATORS["error"], "_refMessageControls");
5054
+ /* Rebuild class-expression control references. */
4751
5055
  this.bindConditionalControls(DECORATORS["elementClass"], "_refClassNameControls");
5056
+ /* Execute all expression pipelines with current state. */
4752
5057
  this.executeExpressions();
5058
+ /* Rebind errors once references and expressions are refreshed. */
4753
5059
  this.bindError();
4754
5060
  }
5061
+ /**
5062
+ * @method reset
5063
+ * @description Resets control value to provided value or stored base value and clears dirty flag.
5064
+ * @param {any} value Optional value to reset to.
5065
+ * @param {any} options Reset options passed to setValue.
5066
+ * @returns {void}
5067
+ */
4755
5068
  reset(value, options = {}) {
4756
- if (value !== undefined)
5069
+ /* Reset to provided value or base snapshot and clear local dirty tracker. */
5070
+ /* If a value is provided, reset using that value. */
5071
+ if (value !== undefined) {
4757
5072
  this.setValue(value, options);
4758
- else
5073
+ }
5074
+ else {
5075
+ /* Otherwise reset to stored base-value snapshot. */
4759
5076
  this.setValue(this.getFormState(this._baseValue), options);
5077
+ }
5078
+ /* Clear custom dirty state after reset. */
4760
5079
  this._dirty = false;
4761
5080
  }
5081
+ /**
5082
+ * @method commit
5083
+ * @description Commits current value as base value and re-evaluates modification state.
5084
+ * @returns {void}
5085
+ */
4762
5086
  commit() {
5087
+ /* Accept current value as new baseline and recompute modified state. */
4763
5088
  this._baseValue = this.value;
4764
5089
  this.callPatch();
4765
5090
  }
5091
+ /**
5092
+ * @method callPatch
5093
+ * @description Updates modification flag and notifies parent patch hook when available.
5094
+ * @returns {void}
5095
+ */
4766
5096
  callPatch() {
5097
+ /* Update modified flag and notify parent patch callback when available. */
5098
+ /* Compare normalized base/current values to compute modified state. */
4767
5099
  this._isModified = this.getValue(this._baseValue) != this.getValue(this.value);
4768
- if (this.parent && this.parent[PATCH])
5100
+ /* Notify parent patch callback when parent exposes it. */
5101
+ if (this.parent && this.parent[PATCH]) {
4769
5102
  this.parent[PATCH](this.keyName);
5103
+ }
4770
5104
  }
5105
+ /**
5106
+ * @method checkErrorMessageStrategy
5107
+ * @description Evaluates whether error messages should be bound according to strategy and state.
5108
+ * @returns {boolean} True when error binding is currently enabled.
5109
+ */
4771
5110
  checkErrorMessageStrategy() {
5111
+ /* Resolve whether error messages should bind under the configured strategy. */
5112
+ /* Initialize with bind-enabled default. */
4772
5113
  let isBind = true;
5114
+ /* Switch by configured error-binding strategy. */
4773
5115
  switch (this._errorMessageBindingStrategy) {
4774
5116
  case ErrorMessageBindingStrategy.OnSubmit:
5117
+ /* Bind only after form submission. */
4775
5118
  isBind = this.parent.submitted;
4776
5119
  break;
4777
5120
  case ErrorMessageBindingStrategy.OnDirty:
5121
+ /* Bind only when control is dirty. */
4778
5122
  isBind = this._dirty;
4779
5123
  break;
4780
5124
  case ErrorMessageBindingStrategy.OnTouched:
5125
+ /* Bind only when control is touched. */
4781
5126
  isBind = this.touched;
4782
5127
  break;
4783
5128
  case ErrorMessageBindingStrategy.OnDirtyOrTouched:
5129
+ /* Bind when control is dirty or touched. */
4784
5130
  isBind = this._dirty || this.touched;
4785
5131
  break;
4786
5132
  case ErrorMessageBindingStrategy.OnDirtyOrSubmit:
5133
+ /* Bind when control is dirty or form is submitted. */
4787
5134
  isBind = this._dirty || this.parent.submitted;
4788
5135
  break;
4789
5136
  case ErrorMessageBindingStrategy.OnTouchedOrSubmit:
5137
+ /* Bind when control is touched or form is submitted. */
4790
5138
  isBind = this.touched || this.parent.submitted;
4791
5139
  break;
4792
5140
  default:
5141
+ /* Fallback strategy keeps binding enabled. */
4793
5142
  isBind = true;
4794
5143
  }
5144
+ /* Return final strategy decision. */
4795
5145
  return isBind;
4796
5146
  }
5147
+ /**
5148
+ * @method executeExpressions
5149
+ * @description Executes conditional decorator expressions for disabled state, errors, and element classes.
5150
+ * @returns {void}
5151
+ */
4797
5152
  executeExpressions() {
5153
+ /* Execute conditional expressions for disabled, error, and class-name behaviors. */
4798
5154
  this.processExpression("_refDisableControls", "disabled");
4799
5155
  this.processExpression("_refMessageControls", "bindError");
4800
5156
  this.processExpression("_refClassNameControls", "bindClassName");
4801
5157
  }
5158
+ /**
5159
+ * @method getMessageExpression
5160
+ * @description Loads message/class expression metadata from the model container.
5161
+ * @param {FormGroup} formGroup Parent form group.
5162
+ * @param {string} keyName Control key name.
5163
+ * @returns {void}
5164
+ */
4802
5165
  getMessageExpression(formGroup, keyName) {
5166
+ /* Load decorator metadata that drives conditional error and class bindings. */
5167
+ /* Proceed only when form group contains model instance metadata. */
4803
5168
  if (formGroup[MODEL_INSTANCE]) {
5169
+ /* Resolve metadata container for the model instance constructor. */
4804
5170
  let instanceContainer = defaultContainer.get(formGroup[MODEL_INSTANCE].constructor);
5171
+ /* Apply metadata only when a container is found. */
4805
5172
  if (instanceContainer) {
5173
+ /* Load conditional message expression for this control key. */
4806
5174
  this._messageExpression = instanceContainer.nonValidationDecorators.error.conditionalExpressions[keyName];
5175
+ /* Load control-property dependencies for message updates. */
4807
5176
  this._controlProp = instanceContainer.nonValidationDecorators.error.controlProp[this.keyName];
5177
+ /* Load conditional class-name expression for this control key. */
4808
5178
  this._classNameExpression = instanceContainer.nonValidationDecorators.elementClass.conditionalExpressions[keyName];
5179
+ /* Load control-property dependencies for class-name updates. */
4809
5180
  this._classNameControlProp = instanceContainer.nonValidationDecorators.elementClass.controlProp[keyName];
4810
- if (this._classNameExpression)
5181
+ /* Enable element-class update mode when class expression exists. */
5182
+ if (this._classNameExpression) {
4811
5183
  this.updateOnElementClass = true;
5184
+ }
4812
5185
  }
4813
5186
  }
4814
5187
  }
5188
+ /**
5189
+ * @method getSanitizedValue
5190
+ * @description Applies configured sanitizers to a value in declaration order.
5191
+ * @param {any} value Raw value.
5192
+ * @returns {any} Sanitized value.
5193
+ */
4815
5194
  getSanitizedValue(value) {
5195
+ /* Apply configured sanitizers in order to normalize outgoing values. */
5196
+ /* Iterate all configured sanitizers if available. */
4816
5197
  if (this._sanitizers) {
4817
5198
  for (let sanitizer of this._sanitizers) {
5199
+ /* Apply sanitizer transformation with its configuration. */
4818
5200
  value = SANITIZERS[sanitizer.name](value, sanitizer.config);
4819
5201
  }
4820
5202
  }
5203
+ /* Return sanitized value result. */
4821
5204
  return value;
4822
5205
  }
5206
+ /**
5207
+ * @method bindConditionalControls
5208
+ * @description Builds and stores control references for conditional decorator expressions.
5209
+ * @param {string} decoratorType Decorator type key.
5210
+ * @param {string} refName Property name that stores computed references.
5211
+ * @returns {void}
5212
+ */
4823
5213
  bindConditionalControls(decoratorType, refName) {
5214
+ /* Create provider for requested decorator type and entity context. */
4824
5215
  this._disableProvider = new DisableProvider(decoratorType, this._entityObject);
5216
+ /* Load zero-argument expression control references. */
4825
5217
  this[refName] = this._disableProvider.zeroArgumentProcess(this, this.keyName);
5218
+ /* Append one-argument expression control references. */
4826
5219
  this._disableProvider.oneArgumentProcess(this, `${this.keyName}${RXCODE}1`).forEach(t => this[refName].push(t));
4827
5220
  }
5221
+ /**
5222
+ * @method setControlErrorMessages
5223
+ * @description Computes and stores control error messages from validation and backend sources.
5224
+ * @returns {void}
5225
+ */
4828
5226
  setControlErrorMessages() {
5227
+ /* Build error messages when strategy allows binding or expression passes. */
4829
5228
  if ((!this._messageExpression && this.checkErrorMessageStrategy()) || this._isPassedExpression) {
5229
+ /* Reset error-message collection before rebuild. */
4830
5230
  this._errorMessages = [];
5231
+ /* Process validation errors when present. */
4831
5232
  if (this.errors) {
4832
5233
  Object.keys(this.errors).forEach(t => {
5234
+ /* If parent exists, also sync into parent control-error registry. */
4833
5235
  if (this.parent) {
4834
5236
  this.parent[CONTROLS_ERROR][this.keyName] = this._errorMessage = this.getErrorMessage(this.errors, t);
5237
+ /* Fallback to shaped error object when direct message is missing. */
4835
5238
  if (!this._errorMessage) {
4836
5239
  let errorObject = ObjectMaker.toJson(t, undefined, this.errors[t] && this.errors[t][t] ? [this.errors[t][t]] : []);
4837
5240
  this.parent[CONTROLS_ERROR][this.keyName] = this._errorMessage = this.getErrorMessage(errorObject, t);
4838
5241
  }
4839
5242
  }
4840
5243
  else {
5244
+ /* Resolve message directly when parent context is not available. */
4841
5245
  this._errorMessage = this.getErrorMessage(this.errors, t);
4842
5246
  }
5247
+ /* Append resolved message to message list. */
4843
5248
  this._errorMessages.push(this._errorMessage);
4844
5249
  });
4845
5250
  }
4846
5251
  else {
5252
+ /* Clear current message when no validation errors remain. */
4847
5253
  this._errorMessage = undefined;
5254
+ /* Remove parent control-error registry value when parent exists. */
4848
5255
  if (this.parent) {
4849
5256
  this.parent[CONTROLS_ERROR][this.keyName] = undefined;
4850
5257
  delete this.parent[CONTROLS_ERROR][this.keyName];
4851
5258
  }
4852
5259
  }
5260
+ /* Merge backend error messages after validator-message build. */
4853
5261
  let backEndErrors = Object.keys(this.backEndErrors);
4854
- if (backEndErrors.length > 0)
5262
+ if (backEndErrors.length > 0) {
4855
5263
  backEndErrors.forEach(t => { this._errorMessages.push(this._errorMessage = this.backEndErrors[t]); });
5264
+ }
4856
5265
  }
4857
5266
  else {
5267
+ /* Expression/strategy says hide errors, so clear caches. */
4858
5268
  this._errorMessages = [];
4859
5269
  this._errorMessage = undefined;
4860
5270
  }
5271
+ /* Store language snapshot used for current error-message cache. */
4861
5272
  this._language = this.getLanguage();
4862
5273
  }
5274
+ /**
5275
+ * @method getLanguage
5276
+ * @description Gets active language from reactive form i18n config.
5277
+ * @returns {string | undefined} Active language code.
5278
+ */
4863
5279
  getLanguage() {
5280
+ /* Return the current reactive-form language code when i18n is configured. */
4864
5281
  return (ReactiveFormConfig.i18n && ReactiveFormConfig.i18n.language) ? ReactiveFormConfig.i18n.language : undefined;
4865
5282
  }
5283
+ /**
5284
+ * @method getErrorMessage
5285
+ * @description Reads a formatted error message for a validation key.
5286
+ * @param {{ [key: string]: string }} errorObject Validation error object.
5287
+ * @param {string} keyName Validation key.
5288
+ * @returns {string | undefined} Resolved error message.
5289
+ */
4866
5290
  getErrorMessage(errorObject, keyName) {
5291
+ /* Return resolved message when payload is present for key. */
4867
5292
  if (errorObject[keyName] && errorObject[keyName][MESSAGE]) {
4868
5293
  return errorObject[keyName][MESSAGE];
4869
5294
  }
5295
+ /* Return undefined when no message payload exists. */
4870
5296
  return;
4871
5297
  }
5298
+ /**
5299
+ * @method processExpression
5300
+ * @description Applies a conditional operation to referenced controls.
5301
+ * @param {string} propName Reference property name.
5302
+ * @param {string} operationType Operation identifier.
5303
+ * @returns {void}
5304
+ */
4872
5305
  processExpression(propName, operationType) {
4873
- if (this[propName])
5306
+ /* Proceed only when expression reference list exists. */
5307
+ if (this[propName]) {
4874
5308
  for (var controlInfo of this[propName]) {
5309
+ /* Resolve target control either from root scope or relative scope. */
4875
5310
  let control = controlInfo.isRoot ? ApplicationUtil.getControl(controlInfo.controlPath, ApplicationUtil.getRootFormGroup(this)) : ApplicationUtil.getFormControl(controlInfo.controlPath, this);
5311
+ /* Execute operation only when target control is resolved. */
4876
5312
  if (control) {
4877
5313
  if (operationType == "disabled") {
5314
+ /* Evaluate conditional expression to determine disabled state. */
4878
5315
  let result = this.executeExpression(controlInfo.conditionalExpression, control);
4879
- if (result)
5316
+ if (result) {
5317
+ /* Disable target control when expression evaluates truthy. */
4880
5318
  control.disable();
4881
- else
5319
+ }
5320
+ else {
5321
+ /* Enable target control when expression evaluates falsy. */
4882
5322
  control.enable();
5323
+ }
4883
5324
  }
4884
- else if (operationType == "bindError")
5325
+ else if (operationType == "bindError") {
5326
+ /* Trigger error binding pipeline on target control. */
4885
5327
  control.bindError();
4886
- else if (operationType == "bindClassName")
5328
+ }
5329
+ else if (operationType == "bindClassName") {
5330
+ /* Trigger class-name binding pipeline on target control. */
4887
5331
  control.bindClassName();
5332
+ }
4888
5333
  }
4889
5334
  }
5335
+ }
4890
5336
  }
5337
+ /**
5338
+ * @method executeExpression
5339
+ * @description Executes a conditional expression using model instance context.
5340
+ * @param {Function} expression Expression function.
5341
+ * @param {AbstractControl} control Control used as expression argument.
5342
+ * @returns {Boolean} Expression result.
5343
+ */
4891
5344
  executeExpression(expression, control) {
5345
+ /* Execute expression with model instance context and parent-model helpers. */
4892
5346
  return expression.call(control.parent[MODEL_INSTANCE], control, ApplicationUtil.getParentModelInstanceValue(this), control.parent[MODEL_INSTANCE]);
4893
5347
  }
5348
+ /**
5349
+ * @method getValue
5350
+ * @description Normalizes nullable/empty values for comparison.
5351
+ * @param {any} value Source value.
5352
+ * @returns {any} Normalized comparable value.
5353
+ */
4894
5354
  getValue(value) {
5355
+ /* Normalize nullable and empty values for stable comparisons. */
4895
5356
  return value !== undefined && value !== null && value !== "" ? value : "";
4896
5357
  }
4897
5358
  }
@@ -11390,7 +11851,7 @@ function rangeAsyncValidatorExtension(config) {
11390
11851
  }
11391
11852
 
11392
11853
  function requiredValidatorExtension(config) {
11393
- return baseValidator(config, AnnotationTypes["required"], requiredValidator(config));
11854
+ return baseValidator(config ?? true, AnnotationTypes["required"], requiredValidator(config));
11394
11855
  }
11395
11856
 
11396
11857
  function timeValidatorExtension(config) {
@@ -12392,15 +12853,16 @@ function getEndpoint(origin) {
12392
12853
  /* Retrieve and return the endpoint metadata associated with the given class */
12393
12854
  return Reflect.getMetadata(endpointMetadataKey, origin);
12394
12855
  }
12856
+
12395
12857
  /**
12396
- * Gets the display header metadata from a class.
12397
- *
12398
- * @param origin - The class from which to retrieve the header metadata.
12399
- * @returns The display header as a string.
12858
+ * Retrieves the display name for a given property of an instance using metadata.
12859
+ * @template T - The type of the instance.
12860
+ * @param {T} instance - The instance from which to retrieve the display name.
12861
+ * @param {string | symbol} propertyKey - The property key for which to retrieve the display name.
12862
+ * @returns {string | undefined} - The display name if found; otherwise, undefined.
12400
12863
  */
12401
- function getDisplay(origin) {
12402
- /* Retrieve and return the display header metadata associated with the given class */
12403
- return Reflect.getMetadata(headerMetadataKey, origin);
12864
+ function getDisplay(instance, propertyKey) {
12865
+ return Reflect.getMetadata(headerMetadataKey, instance, propertyKey);
12404
12866
  }
12405
12867
 
12406
12868
  /**
@@ -12517,6 +12979,9 @@ class AppEvent {
12517
12979
  }
12518
12980
  }
12519
12981
 
12982
+ const TABLE_DEFINITION_METADATA_KEY = Symbol('msa-ng-cdk:table-definition');
12983
+ const TABLE_COLUMNS_METADATA_KEY = Symbol('msa-ng-cdk:table-columns');
12984
+
12520
12985
  var Grid;
12521
12986
  (function (Grid) {
12522
12987
  Grid[Grid["All"] = 0] = "All";
@@ -12529,9 +12994,6 @@ var Grid;
12529
12994
  Grid[Grid["None"] = 7] = "None";
12530
12995
  })(Grid || (Grid = {}));
12531
12996
 
12532
- const tableDefinitionMetadataKey = 'custom:vdTableDefinition';
12533
- const tableColumnsMetadataKey = 'custom:vdTableColumns';
12534
-
12535
12997
  var TableColumnType;
12536
12998
  (function (TableColumnType) {
12537
12999
  TableColumnType[TableColumnType["None"] = 0] = "None";
@@ -12595,6 +13057,11 @@ class TableColumn {
12595
13057
  * @property
12596
13058
  */
12597
13059
  display;
13060
+ /**
13061
+ * Cached classes for responsive display visibility.
13062
+ * @property
13063
+ */
13064
+ displayNgClass;
12598
13065
  /**
12599
13066
  * Endpoint for additional data retrieval.
12600
13067
  * @property
@@ -12826,360 +13293,145 @@ class TableColumn {
12826
13293
  }
12827
13294
 
12828
13295
  /**
12829
- * Class representing the structure and behavior of a table definition.
12830
- * It defines various configurations such as column settings, actions,
12831
- * and callbacks for rows and data handling.
12832
- *
13296
+ * Manual creator function to define a column in a table programmatically.
13297
+ * It sets various properties and behaviors for the column without using decorators.
12833
13298
  * @template T - The type of data represented in the table rows.
13299
+ * @param {string} propertyKey - The property key to bind the column to.
13300
+ * @param {Partial<TableColumn<T>>} [args] - Partial configuration for the table column.
13301
+ * @param {string} [propertyType] - Optional explicit type (e.g., 'string', 'number', 'date', 'boolean', 'array') to drive defaults.
13302
+ * @param {any} [target] - Optional target prototype object for custom display text extraction.
13303
+ * @returns {TableColumn<T>} - The fully constructed and initialized TableColumn instance.
12834
13304
  */
12835
- class TableDefinition {
12836
- /**
12837
- * @property endpoint
12838
- * @description API endpoint from which table data will be fetched.
12839
- * @type {string}
12840
- */
12841
- endpoint = '';
12842
- /**
12843
- * @property projection
12844
- * @description Optional projection for specifying which fields should be included
12845
- * in the fetched data. Can be a single string or an array of field names.
12846
- * @type {string | string[]}
12847
- */
12848
- projection;
13305
+ function buildColumn(propertyKey, args, propertyType, target) {
13306
+ /* Create a new instance of TableColumn with the provided arguments */
13307
+ let tableColumn = new TableColumn(args);
13308
+ /* Set default values for the table column properties */
13309
+ tableColumn.name ||= propertyKey;
13310
+ tableColumn.header ||= (target ? getDisplay(target, propertyKey) : null) || tableColumn.name;
13311
+ tableColumn.filter ||= tableColumn.name;
13312
+ tableColumn.sortBy ||= tableColumn.name;
13313
+ tableColumn.content ||= (row) => {
13314
+ /* Get content using property name */
13315
+ var content = Utils.getPropertyValue(row, tableColumn.name);
13316
+ /* Truncate the text if content length is specified */
13317
+ if ((tableColumn?.contentLength ?? 0) > 0) {
13318
+ return Utils.truncateText(content, tableColumn.contentLength);
13319
+ }
13320
+ return content;
13321
+ };
13322
+ tableColumn.configurable = args?.configurable === undefined ? true : args.configurable;
13323
+ tableColumn.display ||= Grid.All;
13324
+ /* Set type to 'Menu' if menu is specified */
13325
+ if (tableColumn.menu) {
13326
+ tableColumn.type ||= TableColumnType.Menu;
13327
+ }
13328
+ /* Set type to 'Icon' if icon is specified */
13329
+ else if (tableColumn.icon) {
13330
+ tableColumn.type ||= TableColumnType.Icon;
13331
+ }
13332
+ /* Set type to 'IconButton' if iconButton is specified */
13333
+ else if (tableColumn.iconButton) {
13334
+ tableColumn.type ||= TableColumnType.IconButton;
13335
+ }
13336
+ /* Set type to enum, if enum type is specified */
13337
+ else if (tableColumn.enumType) {
13338
+ tableColumn.type ||= TableColumnType.Enum;
13339
+ tableColumn.multiple = propertyType?.trim()?.toLowerCase() == 'array';
13340
+ }
13341
+ /* Otherwise, set type depending on property type */
13342
+ else {
13343
+ switch (propertyType?.toLowerCase()) {
13344
+ case 'number':
13345
+ tableColumn.inputType ||= 'number';
13346
+ tableColumn.type ||= TableColumnType.Number;
13347
+ tableColumn.filterOperator = tableColumn.filterOperator != undefined
13348
+ ? tableColumn.filterOperator
13349
+ : FilterOperator.Contains;
13350
+ break;
13351
+ case 'date':
13352
+ tableColumn.inputType ||= 'date';
13353
+ tableColumn.type ||= TableColumnType.Date;
13354
+ tableColumn.maxWidth ||= 115;
13355
+ tableColumn.arrowBefore = tableColumn.arrowBefore !== undefined ? tableColumn.arrowBefore : true;
13356
+ break;
13357
+ case 'boolean':
13358
+ tableColumn.type ||= TableColumnType.Toggle;
13359
+ tableColumn.options ||= [{ id: false, name: $localize `:@@no:No` }, { id: true, name: $localize `:@@yes:Yes` }];
13360
+ tableColumn.maxWidth ||= 70;
13361
+ if (tableColumn.type == TableColumnType.Text) {
13362
+ tableColumn.content = (row) => {
13363
+ /* Get content using property name */
13364
+ var content = Utils.getPropertyValue(row, tableColumn.name);
13365
+ if (content != null) {
13366
+ return content ? $localize `:@@yes:Yes` : $localize `:@@no:No`;
13367
+ }
13368
+ return null;
13369
+ };
13370
+ }
13371
+ break;
13372
+ /* Default to text type for all other property types */
13373
+ default:
13374
+ tableColumn.type ||= TableColumnType.Text;
13375
+ break;
13376
+ }
13377
+ }
13378
+ /* Set width to minWidth if width is not specified */
13379
+ return tableColumn;
13380
+ }
13381
+
13382
+ /**
13383
+ * Property decorator to define a column in a table.
13384
+ * It sets various properties and behaviors for the column,
13385
+ * including its name, type, display settings, and associated actions.
13386
+ * @template T - The type of data represented in the table rows.
13387
+ * @param {Partial<TableColumn<T>>} args - Partial configuration for the table column.
13388
+ * @returns {Function} - A decorator function that modifies the target property.
13389
+ */
13390
+ function Column(args) {
13391
+ return function (target, propertyKey) {
13392
+ /* Resolve the design:type metadata from the decorator target */
13393
+ const designType = Reflect.getMetadata("design:type", target, propertyKey)?.name;
13394
+ /* Get old table columns */
13395
+ let previousTableColumns = Reflect.getMetadata(TABLE_COLUMNS_METADATA_KEY, target);
13396
+ /* Override the field with the args, if exists */
13397
+ const previousTableColumn = previousTableColumns?.find(x => x.name == propertyKey);
13398
+ const tableColumnArgs = previousTableColumn
13399
+ ? Object.assign({}, previousTableColumn, args)
13400
+ : args;
13401
+ /* Build the structural column using the factory method */
13402
+ let tableColumn = buildColumn(propertyKey, tableColumnArgs, designType, target);
13403
+ /* Override the field, if exists */
13404
+ previousTableColumns = previousTableColumns?.filter(x => x.name != tableColumn.name);
13405
+ /* Create a copy of the result */
13406
+ let tableColumns = previousTableColumns ? previousTableColumns.concat([tableColumn]) : [tableColumn];
13407
+ /* Set column index */
13408
+ tableColumns.forEach((x, i) => x.index ??= i);
13409
+ /* Sort the columns by index */
13410
+ Utils.sortArray(tableColumns, 'index');
13411
+ /* Override the result in the metadata */
13412
+ Reflect.defineMetadata(TABLE_COLUMNS_METADATA_KEY, tableColumns, target);
13413
+ };
13414
+ }
13415
+
13416
+ /**
13417
+ * Abstract class representing a base entity with common properties and functionality.
13418
+ */
13419
+ class BaseEntity {
12849
13420
  /**
12850
- * @property includes
12851
- * @description Optional array of related data entities (includes) to be retrieved along
12852
- * with the main data set.
12853
- * @type {string[]}
13421
+ * @property ID
13422
+ * @description Represents the unique identifier of the entity.
13423
+ * @type {number}
12854
13424
  */
12855
- includes;
13425
+ id;
12856
13426
  /**
12857
- * @property showAction
12858
- * @description Flag to indicate if action columns (e.g., edit, delete buttons)
12859
- * should be displayed in the table. Defaults to `true`.
12860
- * @type {boolean}
13427
+ * @property Version
13428
+ * @description Represents the version number of the entity for concurrency control.
13429
+ * @type {number}
12861
13430
  */
12862
- showAction = true;
13431
+ version;
12863
13432
  /**
12864
- * @property selectable
12865
- * @description Flag to indicate if rows can be selected (e.g., with checkboxes).
12866
- * Defaults to `true`.
12867
- * @type {boolean}
12868
- */
12869
- selectable = true;
12870
- /**
12871
- * @property addable
12872
- * @description Flag to indicate if new items can be added to the table.
12873
- * Defaults to `true`.
12874
- * @type {boolean}
12875
- */
12876
- addable = true;
12877
- /**
12878
- * @property editable
12879
- * @description Flag to indicate if rows can be edited. Defaults to `true`.
12880
- * @type {boolean}
12881
- */
12882
- editable = true;
12883
- /**
12884
- * @property deletable
12885
- * @description Flag to indicate if rows can be deleted. Defaults to `true`.
12886
- * @type {boolean}
12887
- */
12888
- deletable = true;
12889
- /**
12890
- * @property downloadable
12891
- * @description Flag to indicate if table data can be downloaded (e.g., as CSV or Excel).
12892
- * @type {boolean}
12893
- */
12894
- downloadable;
12895
- /**
12896
- * @property duplicable
12897
- * @description Flag to indicate if rows can be duplicated.
12898
- * @type {boolean}
12899
- */
12900
- duplicable;
12901
- /**
12902
- * @property exportable
12903
- * @description Determines if the table is exportable.
12904
- * @type {boolean}
12905
- */
12906
- exportable = true;
12907
- /**
12908
- * @property exportFileName
12909
- * @description The name of the file to export.
12910
- * @type {string}
12911
- */
12912
- exportFileName;
12913
- /**
12914
- * @property sticky
12915
- * @description Flag to indicate whether the table headers or columns should stick
12916
- * to the viewport during scrolling. Defaults to `false`.
12917
- * @type {boolean}
12918
- */
12919
- sticky = false;
12920
- /**
12921
- * @property columns
12922
- * @description Array of table columns that define the structure and data types
12923
- * of each column in the table.
12924
- * @type {TableColumn<T>[]}
12925
- */
12926
- columns = [];
12927
- /**
12928
- * @property hideColumns
12929
- * @description Optional array of column keys that should be hidden from view.
12930
- * @type {string[]}
12931
- */
12932
- hideColumns;
12933
- /**
12934
- * @property rowNgClass
12935
- * @description Function to dynamically assign CSS classes to rows based on the row data
12936
- * and context. Can be used for conditional row styling.
12937
- * @type {(x?: T, ctx?: IGenericListComponent<T>) => any}
12938
- */
12939
- rowNgClass;
12940
- /**
12941
- * @property rowClick
12942
- * @description Callback function for handling row click events.
12943
- * Invoked when a row is clicked.
12944
- * @type {(x?: T, ctx?: IGenericListComponent<T>) => any}
12945
- */
12946
- rowClick;
12947
- /**
12948
- * @property onEdit
12949
- * @description Callback function for handling edit actions.
12950
- * Invoked when the edit button is clicked for a row.
12951
- * @type {(x?: T, ctx?: IGenericListComponent<T>) => any}
12952
- */
12953
- onEdit;
12954
- /**
12955
- * @property detailsTemplate
12956
- * @description Name of the template to use for displaying additional row details.
12957
- * @type {string}
12958
- */
12959
- detailsTemplate;
12960
- /**
12961
- * @property actions
12962
- * @description Array of action items (e.g., custom buttons) available for each row in the table.
12963
- * Actions can be context-sensitive based on the row data and table context.
12964
- * @type {ActionItem<T, IGenericListComponent<T>>[]}
12965
- */
12966
- actions = [];
12967
- /**
12968
- * @property columnSets
12969
- * @description Used to display specific columns in the table.
12970
- * This array defines sets of columns that can be shown
12971
- * based on the active configuration, allowing for dynamic table
12972
- * column customization.
12973
- * @type {string[]}
12974
- */
12975
- columnSets = [];
12976
- /**
12977
- * Constructor for initializing the table definition with optional values.
12978
- * Merges the provided initialization object with default properties.
12979
- *
12980
- * @param init - Optional partial table definition to initialize values.
12981
- */
12982
- constructor(init) {
12983
- Object.assign(this, init);
12984
- }
12985
- }
12986
-
12987
- /**
12988
- * Gets classes decoarated with @Table
12989
- * @param origin
12990
- * @returns
12991
- */
12992
- function getTableDefinition(origin) {
12993
- /* Save the table defintion in the metadata */
12994
- var tableDefinition = Reflect.getMetadata(tableDefinitionMetadataKey, origin) ?? new TableDefinition({});
12995
- if (tableDefinition) {
12996
- /* Set column in the table definition */
12997
- tableDefinition.columns = Reflect.getMetadata(tableColumnsMetadataKey, Reflect.construct(origin, []))
12998
- ?.filter((x) => !x.hidden && !tableDefinition.hideColumns?.some(y => y.trim() == x.name.trim()));
12999
- /* Sort the columns by index */
13000
- Utils.sortArray(tableDefinition.columns || [], 'index');
13001
- /* Set endpoint from the decorator @Api, if any */
13002
- var endpoint = Reflect.getMetadata(endpointMetadataKey, origin);
13003
- if (endpoint) {
13004
- tableDefinition.endpoint = endpoint;
13005
- }
13006
- }
13007
- return tableDefinition;
13008
- }
13009
-
13010
- /**
13011
- * Class decorator to create a mat-table
13012
- * @param tableDefinition
13013
- * @returns
13014
- */
13015
- function Table(tableDefinition) {
13016
- return function (target) {
13017
- if (tableDefinition?.columns) {
13018
- /* Add action menus from table definition, if any */
13019
- var actionColmun = tableDefinition.columns?.find(x => x.name == 'action');
13020
- if (!actionColmun) {
13021
- actionColmun = new TableColumn({
13022
- index: 2000,
13023
- name: 'action',
13024
- columnSets: ['action', 'common'],
13025
- type: TableColumnType.Action,
13026
- disabled: true,
13027
- rowMenuItems: actions,
13028
- configurable: false,
13029
- stickyEnd: true
13030
- });
13031
- /* Add the action column into the table columns */
13032
- tableDefinition.columns.push(actionColmun);
13033
- }
13034
- /* Get custom action, if any */
13035
- var actions = tableDefinition?.actions;
13036
- if (actions != null && actionColmun != null) {
13037
- actionColmun.rowMenuItems ??= [];
13038
- actions.forEach(y => actionColmun.rowMenuItems.push(y));
13039
- }
13040
- }
13041
- /* Save the table defintion in the metadata */
13042
- Reflect.defineMetadata(tableDefinitionMetadataKey, tableDefinition, target);
13043
- };
13044
- }
13045
- /**
13046
- * Property decorator to create table columns
13047
- * @param args
13048
- * @returns
13049
- */
13050
- function Column(args) {
13051
- return function (target, propertyKey) {
13052
- let tableColumn = new TableColumn(args);
13053
- tableColumn.name ||= propertyKey;
13054
- tableColumn.header ||= Reflect.getMetadata(headerMetadataKey, target, propertyKey) || tableColumn.name;
13055
- tableColumn.filter ||= tableColumn.name;
13056
- tableColumn.sortBy ||= tableColumn.name;
13057
- tableColumn.content ||= (row) => {
13058
- /* Get content using property name */
13059
- var content = Utils.getPropertyValue(row, tableColumn.name);
13060
- /* Truncate the text if content length is specified */
13061
- if ((tableColumn?.contentLength ?? 0) > 0) {
13062
- return Utils.truncateText(content, tableColumn.contentLength);
13063
- }
13064
- return content;
13065
- };
13066
- tableColumn.configurable = args?.configurable === undefined ? true : args.configurable;
13067
- tableColumn.display ||= Grid.All;
13068
- /* Set type to 'Menu' if menu is specified */
13069
- if (tableColumn.menu) {
13070
- tableColumn.type ||= TableColumnType.Menu;
13071
- }
13072
- /* Set type to 'Icon' if icon is specified */
13073
- else if (tableColumn.icon) {
13074
- tableColumn.type ||= TableColumnType.Icon;
13075
- }
13076
- /* Set type to 'IconButton' if iconButton is specified */
13077
- else if (tableColumn.iconButton) {
13078
- tableColumn.type ||= TableColumnType.IconButton;
13079
- }
13080
- /* Set type to enum, if enum type is specified */
13081
- else if (tableColumn.enumType) {
13082
- tableColumn.type ||= TableColumnType.Enum;
13083
- tableColumn.multiple = Reflect.getMetadata("design:type", target, propertyKey)?.name?.trim()?.toLowerCase() == 'array';
13084
- }
13085
- /* Otherwiese, set type depending on property type */
13086
- else {
13087
- /* Get property type */
13088
- var propertyType = Reflect.getMetadata("design:type", target, propertyKey)?.name;
13089
- switch (propertyType?.toLowerCase()) {
13090
- case 'number':
13091
- tableColumn.inputType ||= 'number';
13092
- tableColumn.type ||= TableColumnType.Number;
13093
- tableColumn.filterOperator = tableColumn.filterOperator != undefined ? tableColumn.filterOperator : FilterOperator.Contains;
13094
- break;
13095
- case 'date':
13096
- tableColumn.inputType ||= 'date';
13097
- tableColumn.type ||= TableColumnType.Date;
13098
- tableColumn.maxWidth ||= 115;
13099
- tableColumn.arrowBefore = tableColumn.arrowBefore !== undefined ? tableColumn.arrowBefore : true;
13100
- break;
13101
- case 'boolean':
13102
- tableColumn.type ||= TableColumnType.Toggle;
13103
- tableColumn.options ||= [{ id: false, name: $localize `:@@no:No` }, { id: true, name: $localize `:@@yes:Yes` }];
13104
- tableColumn.maxWidth ||= 70;
13105
- if (tableColumn.type == TableColumnType.Text) {
13106
- tableColumn.content = (row) => {
13107
- /* Get content using property name */
13108
- var content = Utils.getPropertyValue(row, tableColumn.name);
13109
- if (content != null) {
13110
- return content ? $localize `:@@yes:Yes` : $localize `:@@no:No`;
13111
- }
13112
- return null;
13113
- };
13114
- }
13115
- break;
13116
- default:
13117
- tableColumn.type ||= TableColumnType.Text;
13118
- break;
13119
- }
13120
- }
13121
- if (tableColumn.maxWidth) {
13122
- tableColumn.width ||= tableColumn.maxWidth;
13123
- }
13124
- /* Get old table columns */
13125
- let previousTableColumns = Reflect.getMetadata(tableColumnsMetadataKey, target);
13126
- /* Override the field, if exists */
13127
- previousTableColumns = previousTableColumns?.filter(x => x.name != tableColumn.name);
13128
- /* Create a copy of the result */
13129
- let tableColumns = previousTableColumns ? previousTableColumns.concat([tableColumn]) : [tableColumn];
13130
- /* Set column index */
13131
- tableColumns.forEach((x, i) => x.index ??= i);
13132
- /* Sort the columns by index */
13133
- Utils.sortArray(tableColumns, 'index');
13134
- /* Override the result in the metadata */
13135
- Reflect.defineMetadata(tableColumnsMetadataKey, tableColumns, target);
13136
- };
13137
- }
13138
- /**
13139
- * Decorator function to define columns for a table object.
13140
- * @param type The constructor function of the table object.
13141
- * @returns A decorator function.
13142
- */
13143
- function ColumnObject(type) {
13144
- return function (target, propertyKey) {
13145
- /* Retrieve table definition */
13146
- var tableDef = getTableDefinition(type);
13147
- /* Retrieve columns from the table definition */
13148
- var columns = tableDef.columns;
13149
- /* Update column names with property key prefix */
13150
- columns?.forEach(x => x.name = `${propertyKey}.${x.name}`);
13151
- /* Get existing table columns from metadata */
13152
- let previousTableColumns = Reflect.getMetadata(tableColumnsMetadataKey, target);
13153
- /* Create a copy of the existing columns array and append new columns */
13154
- let tableColumns = previousTableColumns ? previousTableColumns.concat(columns ?? []) : [];
13155
- /* Set column index if not already set */
13156
- tableColumns.forEach((x, i) => x.index ??= i);
13157
- /* Sort the columns by index */
13158
- Utils.sortArray(tableColumns, 'index');
13159
- /* Override the table columns in the metadata */
13160
- Reflect.defineMetadata(tableColumnsMetadataKey, tableColumns, target);
13161
- };
13162
- }
13163
-
13164
- /**
13165
- * Abstract class representing a base entity with common properties and functionality.
13166
- */
13167
- class BaseEntity {
13168
- /**
13169
- * @property ID
13170
- * @description Represents the unique identifier of the entity.
13171
- * @type {number}
13172
- */
13173
- id;
13174
- /**
13175
- * @property Version
13176
- * @description Represents the version number of the entity for concurrency control.
13177
- * @type {number}
13178
- */
13179
- version;
13180
- /**
13181
- * Constructor to initialize properties of the base entity.
13182
- * @param init Partial object containing initial property values.
13433
+ * Constructor to initialize properties of the base entity.
13434
+ * @param init Partial object containing initial property values.
13183
13435
  */
13184
13436
  constructor(init) {
13185
13437
  Object.assign(this, init);
@@ -14516,6 +14768,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
14516
14768
  const parseProjectionString = (projection) => {
14517
14769
  /* Handle array input: join and proceed to cleaning */
14518
14770
  let input = Array.isArray(projection) ? projection.join(',') : projection;
14771
+ /* Normalize count-style pseudo field calls and preserve explicit aliases when provided */
14772
+ input = input
14773
+ .replace(/\b([a-zA-Z_][a-zA-Z0-9_]*)(?:\.|\$)(?:count|Count)\(\)\s*:\s*([a-zA-Z_][a-zA-Z0-9_]*)/g, '$1$count:$2')
14774
+ .replace(/\b([a-zA-Z_][a-zA-Z0-9_]*)(?:\.|\$)(?:count|Count)\(\)(?!\s*:)/g, '$1$count:$1Count');
14775
+ /* Normalize orderBy pseudo field calls into API projection field format */
14776
+ input = input.replace(/\b([a-zA-Z_][a-zA-Z0-9_]*)(?:\.|\$)orderBy\(([^)]*)\)/g, '$1$orderBy($2)');
14777
+ /* Normalize filter pseudo field calls into API projection field format */
14778
+ input = input.replace(/\b([a-zA-Z_][a-zA-Z0-9_]*)(?:\.|\$)filter\(([^)]*)\)/g, '$1$filter($2)');
14519
14779
  /* If it's already a clean, flat, comma-separated string without braces, return it */
14520
14780
  if (!input.includes('{') && !input.includes('}')) {
14521
14781
  return input.replace(/\s+/g, '');
@@ -14530,10 +14790,54 @@ const parseProjectionString = (projection) => {
14530
14790
  cleaned = cleaned.replace(/,\s*\)/g, ')');
14531
14791
  /* Replace spaces between alphanumeric characters with commas and remove all remaining whitespace */
14532
14792
  return cleaned
14793
+ .replace(/(\)\$[a-zA-Z_][a-zA-Z0-9_]*\([^)]*\))\s+([a-zA-Z0-9_])/g, '$1,$2')
14533
14794
  .replace(/([a-zA-Z0-9])\s+([a-zA-Z0-9])/g, '$1,$2')
14534
14795
  .replace(/\)([a-zA-Z_])/g, '),$1')
14535
14796
  .replace(/\s+/g, '');
14536
14797
  };
14798
+ /**
14799
+ * @method parseProjectionArray
14800
+ * @description Parses projection input (string, string array, or raw multi-line string) into a flattened projection array.
14801
+ * @param {string | string[]} projection The raw selection input
14802
+ * @returns {string[]} The formatted projection as an array of fields
14803
+ */
14804
+ const parseProjectionArray = (projection) => {
14805
+ /* First, parse the projection string to get a clean, comma-separated string */
14806
+ const parsedProjection = parseProjectionString(projection);
14807
+ /* If the parsed projection is empty, return an empty array */
14808
+ if (!parsedProjection) {
14809
+ return [];
14810
+ }
14811
+ const fields = [];
14812
+ let currentField = '';
14813
+ let parenthesesDepth = 0;
14814
+ /* Split only by top-level commas to keep function arguments intact (e.g. orderBy(a,b)) */
14815
+ for (const char of parsedProjection) {
14816
+ if (char === '(') {
14817
+ parenthesesDepth++;
14818
+ }
14819
+ /* Decrease depth on closing parentheses, but ensure it doesn't go below zero */
14820
+ if (char === ')') {
14821
+ parenthesesDepth = Math.max(0, parenthesesDepth - 1);
14822
+ }
14823
+ /* If we encounter a comma at the top level (not inside parentheses), we finalize the current field */
14824
+ if (char === ',' && parenthesesDepth === 0) {
14825
+ if (currentField) {
14826
+ fields.push(currentField);
14827
+ currentField = '';
14828
+ }
14829
+ continue;
14830
+ }
14831
+ /* Append the current character to the current field */
14832
+ currentField += char;
14833
+ }
14834
+ /* Push the last field if it exists */
14835
+ if (currentField) {
14836
+ fields.push(currentField);
14837
+ }
14838
+ /* Trim whitespace from each field and filter out any empty strings */
14839
+ return fields.map((field) => field.trim()).filter(Boolean);
14840
+ };
14537
14841
 
14538
14842
  class GenericService {
14539
14843
  endpoint;
@@ -14840,11 +15144,17 @@ class GenericService {
14840
15144
  * Downloads a file from the server
14841
15145
  * @param path Relative path to the download action
14842
15146
  * @param params Optional query parameters
15147
+ * @param headers Optional HTTP headers
14843
15148
  * @param handleError Whether to handle errors (default: true)
14844
15149
  */
14845
- download(path, params, handleError = true) {
15150
+ download(path, params, headers, handleError = true) {
14846
15151
  let request = this.http
14847
- .get(`${this.endpoint}/${path ? path : 'download'}`, { params: Utils.toHttpParams(params), responseType: 'arraybuffer', observe: 'response' })
15152
+ .get(`${this.endpoint}/${path ? path : 'download'}`, {
15153
+ params: Utils.toHttpParams(params),
15154
+ responseType: 'arraybuffer',
15155
+ observe: 'response',
15156
+ headers: this.toHttpHeaders(headers)
15157
+ })
14848
15158
  .pipe(map$1(x => { return { data: x.body, filename: this.getFileNameFromHeaders(x.headers) }; }));
14849
15159
  /* Handle error */
14850
15160
  if (handleError) {
@@ -14856,10 +15166,11 @@ class GenericService {
14856
15166
  * Asynchronously downloads a file from the server
14857
15167
  * @param path Relative path to the download action
14858
15168
  * @param params Optional query parameters
15169
+ * @param headers Optional HTTP headers
14859
15170
  * @returns Promise resolving to the download result
14860
15171
  */
14861
- async downloadAsync(path, params) {
14862
- return await firstValueFrom(this.download(path, params));
15172
+ async downloadAsync(path, params, headers) {
15173
+ return await firstValueFrom(this.download(path, params, headers));
14863
15174
  }
14864
15175
  /**
14865
15176
  * Duplicates a record by ID
@@ -15374,6 +15685,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
15374
15685
  type: Input
15375
15686
  }] } });
15376
15687
 
15688
+ /**
15689
+ * @function hasRequiredValidator
15690
+ * @description Checks required state using runtime marker, native Angular validators and Rx validator metadata.
15691
+ * @param {AbstractControl | null | undefined} control The control to evaluate.
15692
+ * @returns {boolean} True when the control should be treated as required.
15693
+ */
15694
+ const hasRequiredValidator = (control) => {
15695
+ if (!control) {
15696
+ return false;
15697
+ }
15698
+ /* Use the explicit required-state API when available on the control instance. */
15699
+ const controlWithRequiredApi = control;
15700
+ if (typeof controlWithRequiredApi.isRequiredActive === 'function') {
15701
+ return controlWithRequiredApi.isRequiredActive();
15702
+ }
15703
+ /* Fallback for plain Angular controls that do not use RxFormControl. */
15704
+ return typeof control.hasValidator === 'function' ? control.hasValidator(Validators.required) : false;
15705
+ };
15706
+
15377
15707
  /**
15378
15708
  * Abstract class for custom form field controls.
15379
15709
  */
@@ -15485,6 +15815,12 @@ class AbstractMatFormField {
15485
15815
  * @type {boolean}
15486
15816
  */
15487
15817
  _required = false;
15818
+ /**
15819
+ * @property _resolvedRequired
15820
+ * @description Caches the effective required state to detect runtime changes.
15821
+ * @type {boolean}
15822
+ */
15823
+ _resolvedRequired = false;
15488
15824
  /**
15489
15825
  * @property required
15490
15826
  * @description Sets the required state.
@@ -15500,7 +15836,7 @@ class AbstractMatFormField {
15500
15836
  * @type {boolean}
15501
15837
  */
15502
15838
  get required() {
15503
- return this._required;
15839
+ return this._required || hasRequiredValidator(this.ngControl?.control);
15504
15840
  }
15505
15841
  /**
15506
15842
  * @property _readonly
@@ -15687,6 +16023,12 @@ class AbstractMatFormField {
15687
16023
  ngDoCheck() {
15688
16024
  if (this.ngControl) {
15689
16025
  this.updateErrorState();
16026
+ /* Check if the required state has changed and update accordingly */
16027
+ const nextRequired = this.required;
16028
+ if (this._resolvedRequired !== nextRequired) {
16029
+ this._resolvedRequired = nextRequired;
16030
+ this.stateChanges.next();
16031
+ }
15690
16032
  }
15691
16033
  }
15692
16034
  /**
@@ -16450,7 +16792,7 @@ class VdSelectComponent extends AbstractSelectFormField {
16450
16792
  provide: MAT_SELECT_CONFIG,
16451
16793
  useValue: { overlayPanelClass: 'vd-select-filter-overlay' }
16452
16794
  }
16453
- ], queries: [{ propertyName: "optionTemplate", first: true, predicate: VdSelectOptionDirective, descendants: true }, { propertyName: "triggerTemplate", first: true, predicate: VdSelectTriggerDirective, descendants: true }], viewQueries: [{ propertyName: "selectEl", first: true, predicate: MatSelect, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-select\n [placeholder]=\"placeholder\"\n i18n-placeholder\n [(ngModel)]=\"value\"\n #select=\"matSelect\"\n (selectionChange)=\"handleChange($event)\"\n [hidden]=\"readonly\"\n [multiple]=\"multiple\"\n [compareWith]=\"compareWith??defaultCompareWith\"\n [disabled]=\"disabled\"\n flex\n>\n <!-- #region Filter input -->\n <div class=\"mat-mdc-form-field mat-form-field-appearance-fill flex\">\n <div\n class=\"mat-mdc-text-field-wrapper mdc-text-field mdc-text-field--filled mdc-text-field--no-label\"\n >\n <div class=\"mat-mdc-form-field-focus-overlay\"></div>\n <div class=\"mat-mdc-form-field-flex\">\n <div class=\"mat-mdc-form-field-infix\" layout=\"row\" flex>\n <input\n matInput\n #filterInput\n type=\"text\"\n placeholder=\"Filter...\"\n class=\"mat-mdc-input-element vd-select-filter mat-mdc-form-field-input-control mdc-text-field__input\"\n (keyup)=\"handleFilter($event)\"\n flex\n />\n @if (filterInput?.value) {\n <mat-icon\n (click)=\"filterInput!.value = ''; handleFilter($event);\"\n fontSet=\"material-symbols-outlined\"\n >close</mat-icon\n >\n }\n </div>\n </div>\n <div class=\"mdc-line-ripple\"></div>\n </div>\n </div>\n <!-- #endregion -->\n\n <!-- #region Selection template -->\n <ng-template #selectionTemplate let-label=\"label\">\n <span i18n=\"@@selection\"\n >{ label, select, option {option} other { {{ label }} } }</span\n >\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option template -->\n <ng-template #optionTextTemplate let-option=\"option\">\n <span\n layout=\"column\"\n class=\"option-text\"\n [ngClass]=\"{'option-has-hint': $safeNavigationMigration(option.hint?.length) > 0}\"\n >\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"\n ></ng-template>\n <span\n class=\"mat-caption text-secondary option-hint\"\n [matTooltip]=\"option.hint\"\n >{{option.hint}}</span\n >\n </span>\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option icon template -->\n <ng-template #optionIconTemplate let-option=\"option\" let-isAvatar=\"isAvatar\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [fontSet]=\"fontSet || 'material-symbols-outlined'\"\n >{{option[matIconKey]}}</mat-icon\n >\n } @if (svgIconKey && !matIconKey) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [svgIcon]=\"option[svgIconKey]\"\n [fontSet]=\"fontSet || 'material-symbols-outlined'\"\n ></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\"\n [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"\n >{{option.icon?.matIcon}}</mat-icon\n >\n } @if (option.icon?.svgIcon) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [svgIcon]=\"$safeNavigationMigration(option.icon?.svgIcon)\"\n [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\"\n [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"\n ></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template\n #optionIconTemplate\n [ngTemplateOutlet]=\"optionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\"\n >\n @if (optionIcon.svgIcon) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [svgIcon]=\"optionIcon.svgIcon\"\n [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"\n ></mat-icon>\n } @if (optionIcon.matIcon) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"\n >{{optionIcon.matIcon}}</mat-icon\n >\n }\n </ng-template>\n }\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option icon template -->\n <ng-template #optionIconChipAvatarTemplate let-option=\"option\">\n <!-- #region Property icon -->\n <span class=\"option-icon\" matChipAvatar>\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n </span>\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Trigger for launch button -->\n @if (onLaunch.observed) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last =\n $last) {\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"\n ></ng-template>\n\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n } }\n </span>\n <mat-icon\n class=\"vd-select-launch\"\n (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\"\n >launch</mat-icon\n >\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Custom trigger template -->\n @if (!onLaunch.observed && triggerTemplate && triggerTemplate.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <ng-template\n [ngTemplateOutlet]=\"triggerTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ trigger: selectedOptions }\"\n ></ng-template>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Option template as trigger -->\n @if (!onLaunch.observed && !triggerTemplate?.templateRef &&\n optionTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last =\n $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template\n [ngTemplateOutlet]=\"optionTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"\n ></ng-template>\n }\n </span>\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n } }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Trigger for icons -->\n @if (!triggerTemplate?.templateRef && !optionTemplate?.templateRef) {\n <mat-select-trigger>\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n @for (option of selectedOptions; track option; let i = $index; let last =\n $last) { @if (multiple) {\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n </span>\n }\n <ng-template\n [ngTemplateOutlet]=\"optionTextTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n </mat-chip>\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"optionIconChipAvatarTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n <ng-template\n [ngTemplateOutlet]=\"optionTextTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n } @if (!last) {\n <span>&nbsp;&nbsp;</span>\n } }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Default option -->\n @if (!multiple && defaultOption) {\n <mat-option class=\"tc-grey-500\" i18n=\"@@pleaseSelect\"\n >--- Please Select ---</mat-option\n >\n }\n <!-- #endregion -->\n\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-option\n [value]=\"mapper ? option : option[optionValueProperty]\"\n [disabled]=\"$safeNavigationMigration(option?.disabled)\"\n >\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\"\n >{{option[matIconKey]}}</mat-icon\n >\n } @if (svgIconKey && !matIconKey) {\n <mat-icon\n [svgIcon]=\"option[svgIconKey]\"\n [fontSet]=\"fontSet || 'material-symbols-outlined'\"\n ></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon\n [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\"\n [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"\n >{{option.icon?.matIcon}}</mat-icon\n >\n } @if (option.icon?.svgIcon) {\n <mat-icon\n [svgIcon]=\"$safeNavigationMigration(option.icon?.svgIcon)\"\n [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\"\n [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"\n ></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Text -->\n <span\n layout=\"column\"\n layout-align=\"start center\"\n class=\"option-text\"\n [ngClass]=\"{'option-has-hint':$safeNavigationMigration(option.hint?.length)>0}\"\n >\n @if (!optionTemplate?.templateRef) {\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"\n ></ng-template>\n } @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template\n [ngTemplateOutlet]=\"optionTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"\n ></ng-template>\n }\n <!-- #endregion -->\n <span\n class=\"mat-caption text-secondary option-hint\"\n [matTooltip]=\"option.hint\"\n >{{option.hint}}</span\n >\n </span>\n </mat-option>\n }\n <!-- #endregion -->\n</mat-select>\n\n<!-- #region Read only value -->\n@if (readonly) {\n<div>\n @if (currentValue) {\n <div>\n <div class=\"readonly-value\">\n @if (!optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <span>\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let\n last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n @if(!this.multiple) { @if(optionIcon || matIconKey || svgIconKey ||\n option.icon) {\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue }\"\n ></ng-template>\n <span>&nbsp;&nbsp;</span>\n }\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: currentValue[optionTextProperty] }\"\n ></ng-template>\n } @else if(currentValue[i]){\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue[i] }\"\n ></ng-template>\n </span>\n }\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: currentValue[i][optionTextProperty] }\"\n ></ng-template>\n </mat-chip>\n }\n </span>\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n } }\n </span>\n </span>\n } @if (triggerTemplate && triggerTemplate.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue }\"\n ></ng-template>\n <span>&nbsp;&nbsp;</span>\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue }\"\n ></ng-template>\n <ng-template\n [ngTemplateOutlet]=\"triggerTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ trigger: currentValue }\"\n ></ng-template>\n </span>\n } @if (optionTemplate && optionTemplate.templateRef &&\n !triggerTemplate?.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue }\"\n ></ng-template>\n <span>&nbsp;&nbsp;</span>\n <ng-template\n [ngTemplateOutlet]=\"optionTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ option: currentValue, text: currentValue[optionTextProperty] }\"\n ></ng-template>\n </span>\n }\n </div>\n @if (onLaunch.observed) {\n <mat-icon\n class=\"vd-select-launch-readonly\"\n (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\"\n >launch</mat-icon\n >\n }\n </div>\n } @if (!currentValue) {\n <div>&nbsp;</div>\n }\n</div>\n}\n<!-- #endregion -->\n", styles: [".vd-select-launch{position:absolute;right:30px;top:-5px;font-size:18px;cursor:pointer}.readonly-value{padding-right:24px;opacity:.6;min-height:15px}.vd-select-launch-readonly{position:absolute;right:0;top:9px;font-size:18px;cursor:pointer}.vd-select-filter-wrap{background:inherit;position:sticky;top:-8px;box-sizing:border-box;z-index:100}.vd-select-filter-wrap .vd-select-filter-inner{z-index:100;display:flex;flex-direction:row;align-items:center;background:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter{box-shadow:none;padding:16px 16px 16px 0;box-sizing:border-box;width:100%;border:none;background-color:inherit;color:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter:focus-visible{border:none;outline:none}.vd-select-filter-wrap .mat-divider{display:block;width:100%;border-top-width:1px;border-top-style:solid;box-sizing:border-box}::ng-deep .mat-mdc-select-trigger{display:flex!important}::ng-deep .mat-mdc-select-trigger .mat-icon{display:flex;margin-right:8px}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix{padding-top:4px!important;padding-bottom:4px!important}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix .mat-mdc-select-trigger{height:100%}.mat-mdc-select mat-select-trigger .option-text,.mat-mdc-select .mat-mdc-option .option-text{display:contents!important}.mat-mdc-select mat-select-trigger .option-text.option-has-hint,.mat-mdc-select .mat-mdc-option .option-text.option-has-hint{line-height:.92em}.mat-mdc-select mat-select-trigger .option-text .option-hint,.mat-mdc-select .mat-mdc-option .option-text .option-hint{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .option-text,.mat-mdc-select:not(.mat-mdc-select-multiple) .mat-mdc-option .option-text{width:calc(100% - 36px)}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i2$2.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i7.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i7.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
16795
+ ], queries: [{ propertyName: "optionTemplate", first: true, predicate: VdSelectOptionDirective, descendants: true }, { propertyName: "triggerTemplate", first: true, predicate: VdSelectTriggerDirective, descendants: true }], viewQueries: [{ propertyName: "selectEl", first: true, predicate: MatSelect, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-select [placeholder]=\"placeholder\" i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelect\" (selectionChange)=\"handleChange($event)\" [hidden]=\"readonly\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled\" flex>\n <!-- #region Filter input -->\n <div class=\"mat-mdc-form-field mat-form-field-appearance-fill flex\">\n <div class=\"mat-mdc-text-field-wrapper mdc-text-field mdc-text-field--filled mdc-text-field--no-label\">\n <div class=\"mat-mdc-form-field-focus-overlay\"></div>\n <div class=\"mat-mdc-form-field-flex\">\n <div class=\"mat-mdc-form-field-infix\" layout=\"row\" flex>\n <input matInput #filterInput type=\"text\" placeholder=\"Filter...\" class=\"mat-mdc-input-element vd-select-filter mat-mdc-form-field-input-control mdc-text-field__input\" (keyup)=\"handleFilter($event)\" flex />\n @if (filterInput?.value) {\n <mat-icon (click)=\"filterInput!.value = ''; handleFilter($event);\" fontSet=\"material-symbols-outlined\">close</mat-icon>\n }\n </div>\n </div>\n <div class=\"mdc-line-ripple\"></div>\n </div>\n </div>\n <!-- #endregion -->\n <!-- #region Selection template -->\n <ng-template #selectionTemplate let-label=\"label\">\n <span i18n=\"@@selection\">{ label, select, option {option} other { {{ label }} } }</span>\n </ng-template>\n <!-- #endregion -->\n <!-- #region Option template -->\n <ng-template #optionTextTemplate let-option=\"option\">\n <span layout=\"column\" class=\"option-text\" [ngClass]=\"{'option-has-hint': $safeNavigationMigration(option.hint?.length) > 0}\">\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n <span class=\"mat-caption text-secondary option-hint\" [matTooltip]=\"option.hint\">{{option.hint}}</span>\n </span>\n </ng-template>\n <!-- #endregion -->\n <!-- #region Option icon template -->\n <ng-template #optionIconTemplate let-option=\"option\" let-isAvatar=\"isAvatar\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"$safeNavigationMigration(option.icon?.svgIcon)\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template #optionIconTemplate [ngTemplateOutlet]=\"optionIconTemplate\" let-optionIcon=\"optionIcon\" [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n }\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n <!-- #region Option icon template -->\n <ng-template #optionIconChipAvatarTemplate let-option=\"option\">\n <!-- #region Property icon -->\n <span class=\"option-icon\" matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n <!-- #region Trigger for launch button -->\n @if (onLaunch.observed) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n }\n }\n </span>\n <mat-icon class=\"vd-select-launch\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n <!-- #region Custom trigger template -->\n @if (!onLaunch.observed && triggerTemplate && triggerTemplate.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <ng-template [ngTemplateOutlet]=\"triggerTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: selectedOptions }\"></ng-template>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n <!-- #region Option template as trigger -->\n @if (!onLaunch.observed && !triggerTemplate?.templateRef && optionTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n @if (multiple) {\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n </mat-chip>\n }\n @else\n {\n <span layout=\"row\" layout-align=\"start center\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n </span>\n }\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n <!-- #region Trigger for icons -->\n @if (!triggerTemplate?.templateRef && !optionTemplate?.templateRef) {\n <mat-select-trigger>\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n @if (multiple) {\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </mat-chip>\n }\n @else {\n <ng-template [ngTemplateOutlet]=\"optionIconChipAvatarTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n }\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n <!-- #region Default option -->\n @if (!multiple && defaultOption) {\n <mat-option class=\"tc-grey-500\" i18n=\"@@pleaseSelect\">--- Please Select ---</mat-option>\n }\n <!-- #endregion -->\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-option [value]=\"mapper ? option : option[optionValueProperty]\" [disabled]=\"$safeNavigationMigration(option?.disabled)\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n } @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"$safeNavigationMigration(option.icon?.svgIcon)\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n <!-- #region Text -->\n <span layout=\"column\" layout-align=\"start center\" class=\"option-text\" [ngClass]=\"{'option-has-hint':$safeNavigationMigration(option.hint?.length)>0}\">\n @if (!optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n }\n @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n <!-- #endregion -->\n <span class=\"mat-caption text-secondary option-hint\" [matTooltip]=\"option.hint\">{{option.hint}}</span>\n </span>\n </mat-option>\n }\n <!-- #endregion -->\n</mat-select>\n<!-- #region Read only value -->\n@if (readonly) {\n @if (currentValue) {\n <div class=\"readonly-value\">\n @if (!optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"readonly-content\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n @if(!this.multiple) {\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span>&nbsp;&nbsp;</span>\n }\n <span class=\"readonly-ellipsis-text\">\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: currentValue[optionTextProperty] }\"></ng-template>\n </span>\n }\n @else if(currentValue[i]){\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue[i] }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: currentValue[i][optionTextProperty] }\"></ng-template>\n </mat-chip>\n }\n </span>\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n }\n }\n </span>\n }\n @if (triggerTemplate && triggerTemplate.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger readonly-content\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span>&nbsp;&nbsp;</span>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span class=\"readonly-ellipsis-text\">\n <ng-template [ngTemplateOutlet]=\"triggerTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: currentValue }\"></ng-template>\n </span>\n </span>\n }\n @if (optionTemplate && optionTemplate.templateRef && !triggerTemplate?.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger readonly-content\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span>&nbsp;&nbsp;</span>\n <span class=\"readonly-ellipsis-text\">\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: currentValue, text: currentValue[optionTextProperty] }\"></ng-template>\n </span>\n </span>\n }\n </div>\n @if (onLaunch.observed) {\n <mat-icon class=\"vd-select-launch-readonly\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n }\n }\n @if (!currentValue) {\n <div>&nbsp;</div>\n }\n}\n<!-- #endregion -->", styles: [":host{display:block;width:100%;min-width:0}.vd-select-launch{position:absolute;right:30px;top:-5px;font-size:18px;cursor:pointer}.readonly-value{padding-right:24px;opacity:.6;min-height:15px;display:flex;align-items:center;width:0;flex:1 1 auto;max-width:100%;min-width:0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.readonly-value>*{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.readonly-value .readonly-content{display:flex;align-items:center;width:0;flex:1 1 auto;max-width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.readonly-value .readonly-ellipsis-text{display:block;flex:1 1 auto;min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.readonly-value .readonly-content [layout=row],.readonly-value .readonly-content .option-text,.readonly-value .readonly-content .mat-mdc-chip,.readonly-value .readonly-content .mat-mdc-chip-action-label,.readonly-value .readonly-content .mat-mdc-standard-chip{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vd-select-launch-readonly{position:absolute;right:0;top:9px;font-size:18px;cursor:pointer}.vd-select-filter-wrap{background:inherit;position:sticky;top:-8px;box-sizing:border-box;z-index:100}.vd-select-filter-wrap .vd-select-filter-inner{z-index:100;display:flex;flex-direction:row;align-items:center;background:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter{box-shadow:none;padding:16px 16px 16px 0;box-sizing:border-box;width:100%;border:none;background-color:inherit;color:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter:focus-visible{border:none;outline:none}.vd-select-filter-wrap .mat-divider{display:block;width:100%;border-top-width:1px;border-top-style:solid;box-sizing:border-box}::ng-deep .mat-mdc-select-trigger{display:flex!important}::ng-deep .mat-mdc-select-trigger .mat-icon{display:flex;margin-right:8px}::ng-deep .mat-mdc-form-field-type-vd-select .mat-mdc-form-field-infix{display:flex;align-items:center;min-width:0;max-width:100%;width:100%}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix{padding-top:4px!important;padding-bottom:4px!important}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix .mat-mdc-select-trigger{height:100%}.mat-mdc-select mat-select-trigger .option-text,.mat-mdc-select .mat-mdc-option .option-text{display:contents!important}.mat-mdc-select mat-select-trigger .option-text.option-has-hint,.mat-mdc-select .mat-mdc-option .option-text.option-has-hint{line-height:.92em}.mat-mdc-select mat-select-trigger .option-text .option-hint,.mat-mdc-select .mat-mdc-option .option-text .option-hint{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .option-text,.mat-mdc-select:not(.mat-mdc-select-multiple) .mat-mdc-option .option-text{width:calc(100% - 36px)}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i2$2.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i7.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i7.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
16454
16796
  }
16455
16797
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: VdSelectComponent, decorators: [{
16456
16798
  type: Component,
@@ -16468,7 +16810,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
16468
16810
  provide: MAT_SELECT_CONFIG,
16469
16811
  useValue: { overlayPanelClass: 'vd-select-filter-overlay' }
16470
16812
  }
16471
- ], template: "<mat-select\n [placeholder]=\"placeholder\"\n i18n-placeholder\n [(ngModel)]=\"value\"\n #select=\"matSelect\"\n (selectionChange)=\"handleChange($event)\"\n [hidden]=\"readonly\"\n [multiple]=\"multiple\"\n [compareWith]=\"compareWith??defaultCompareWith\"\n [disabled]=\"disabled\"\n flex\n>\n <!-- #region Filter input -->\n <div class=\"mat-mdc-form-field mat-form-field-appearance-fill flex\">\n <div\n class=\"mat-mdc-text-field-wrapper mdc-text-field mdc-text-field--filled mdc-text-field--no-label\"\n >\n <div class=\"mat-mdc-form-field-focus-overlay\"></div>\n <div class=\"mat-mdc-form-field-flex\">\n <div class=\"mat-mdc-form-field-infix\" layout=\"row\" flex>\n <input\n matInput\n #filterInput\n type=\"text\"\n placeholder=\"Filter...\"\n class=\"mat-mdc-input-element vd-select-filter mat-mdc-form-field-input-control mdc-text-field__input\"\n (keyup)=\"handleFilter($event)\"\n flex\n />\n @if (filterInput?.value) {\n <mat-icon\n (click)=\"filterInput!.value = ''; handleFilter($event);\"\n fontSet=\"material-symbols-outlined\"\n >close</mat-icon\n >\n }\n </div>\n </div>\n <div class=\"mdc-line-ripple\"></div>\n </div>\n </div>\n <!-- #endregion -->\n\n <!-- #region Selection template -->\n <ng-template #selectionTemplate let-label=\"label\">\n <span i18n=\"@@selection\"\n >{ label, select, option {option} other { {{ label }} } }</span\n >\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option template -->\n <ng-template #optionTextTemplate let-option=\"option\">\n <span\n layout=\"column\"\n class=\"option-text\"\n [ngClass]=\"{'option-has-hint': $safeNavigationMigration(option.hint?.length) > 0}\"\n >\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"\n ></ng-template>\n <span\n class=\"mat-caption text-secondary option-hint\"\n [matTooltip]=\"option.hint\"\n >{{option.hint}}</span\n >\n </span>\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option icon template -->\n <ng-template #optionIconTemplate let-option=\"option\" let-isAvatar=\"isAvatar\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [fontSet]=\"fontSet || 'material-symbols-outlined'\"\n >{{option[matIconKey]}}</mat-icon\n >\n } @if (svgIconKey && !matIconKey) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [svgIcon]=\"option[svgIconKey]\"\n [fontSet]=\"fontSet || 'material-symbols-outlined'\"\n ></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\"\n [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"\n >{{option.icon?.matIcon}}</mat-icon\n >\n } @if (option.icon?.svgIcon) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [svgIcon]=\"$safeNavigationMigration(option.icon?.svgIcon)\"\n [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\"\n [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"\n ></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template\n #optionIconTemplate\n [ngTemplateOutlet]=\"optionIconTemplate\"\n let-optionIcon=\"optionIcon\"\n [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\"\n >\n @if (optionIcon.svgIcon) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [svgIcon]=\"optionIcon.svgIcon\"\n [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"\n ></mat-icon>\n } @if (optionIcon.matIcon) {\n <mat-icon\n [class.mat-mdc-chip-avatar]=\"isAvatar\"\n [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"\n >{{optionIcon.matIcon}}</mat-icon\n >\n }\n </ng-template>\n }\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Option icon template -->\n <ng-template #optionIconChipAvatarTemplate let-option=\"option\">\n <!-- #region Property icon -->\n <span class=\"option-icon\" matChipAvatar>\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n </span>\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Trigger for launch button -->\n @if (onLaunch.observed) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last =\n $last) {\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"\n ></ng-template>\n\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n } }\n </span>\n <mat-icon\n class=\"vd-select-launch\"\n (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\"\n >launch</mat-icon\n >\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Custom trigger template -->\n @if (!onLaunch.observed && triggerTemplate && triggerTemplate.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <ng-template\n [ngTemplateOutlet]=\"triggerTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ trigger: selectedOptions }\"\n ></ng-template>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Option template as trigger -->\n @if (!onLaunch.observed && !triggerTemplate?.templateRef &&\n optionTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last =\n $last) {\n <span layout=\"row\" layout-align=\"start center\">\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template\n [ngTemplateOutlet]=\"optionTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"\n ></ng-template>\n }\n </span>\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n } }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Trigger for icons -->\n @if (!triggerTemplate?.templateRef && !optionTemplate?.templateRef) {\n <mat-select-trigger>\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n @for (option of selectedOptions; track option; let i = $index; let last =\n $last) { @if (multiple) {\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n </span>\n }\n <ng-template\n [ngTemplateOutlet]=\"optionTextTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n </mat-chip>\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"optionIconChipAvatarTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n <ng-template\n [ngTemplateOutlet]=\"optionTextTemplate\"\n [ngTemplateOutletContext]=\"{ option: option }\"\n ></ng-template>\n } @if (!last) {\n <span>&nbsp;&nbsp;</span>\n } }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n\n <!-- #region Default option -->\n @if (!multiple && defaultOption) {\n <mat-option class=\"tc-grey-500\" i18n=\"@@pleaseSelect\"\n >--- Please Select ---</mat-option\n >\n }\n <!-- #endregion -->\n\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-option\n [value]=\"mapper ? option : option[optionValueProperty]\"\n [disabled]=\"$safeNavigationMigration(option?.disabled)\"\n >\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\"\n >{{option[matIconKey]}}</mat-icon\n >\n } @if (svgIconKey && !matIconKey) {\n <mat-icon\n [svgIcon]=\"option[svgIconKey]\"\n [fontSet]=\"fontSet || 'material-symbols-outlined'\"\n ></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon\n [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\"\n [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"\n >{{option.icon?.matIcon}}</mat-icon\n >\n } @if (option.icon?.svgIcon) {\n <mat-icon\n [svgIcon]=\"$safeNavigationMigration(option.icon?.svgIcon)\"\n [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\"\n [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"\n ></mat-icon>\n }\n <!-- #endregion -->\n\n <!-- #region Text -->\n <span\n layout=\"column\"\n layout-align=\"start center\"\n class=\"option-text\"\n [ngClass]=\"{'option-has-hint':$safeNavigationMigration(option.hint?.length)>0}\"\n >\n @if (!optionTemplate?.templateRef) {\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"\n ></ng-template>\n } @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template\n [ngTemplateOutlet]=\"optionTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"\n ></ng-template>\n }\n <!-- #endregion -->\n <span\n class=\"mat-caption text-secondary option-hint\"\n [matTooltip]=\"option.hint\"\n >{{option.hint}}</span\n >\n </span>\n </mat-option>\n }\n <!-- #endregion -->\n</mat-select>\n\n<!-- #region Read only value -->\n@if (readonly) {\n<div>\n @if (currentValue) {\n <div>\n <div class=\"readonly-value\">\n @if (!optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <span>\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let\n last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n @if(!this.multiple) { @if(optionIcon || matIconKey || svgIconKey ||\n option.icon) {\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue }\"\n ></ng-template>\n <span>&nbsp;&nbsp;</span>\n }\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: currentValue[optionTextProperty] }\"\n ></ng-template>\n } @else if(currentValue[i]){\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue[i] }\"\n ></ng-template>\n </span>\n }\n <ng-template\n [ngTemplateOutlet]=\"selectionTemplate\"\n [ngTemplateOutletContext]=\"{ label: currentValue[i][optionTextProperty] }\"\n ></ng-template>\n </mat-chip>\n }\n </span>\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n } }\n </span>\n </span>\n } @if (triggerTemplate && triggerTemplate.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue }\"\n ></ng-template>\n <span>&nbsp;&nbsp;</span>\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue }\"\n ></ng-template>\n <ng-template\n [ngTemplateOutlet]=\"triggerTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ trigger: currentValue }\"\n ></ng-template>\n </span>\n } @if (optionTemplate && optionTemplate.templateRef &&\n !triggerTemplate?.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n <ng-template\n [ngTemplateOutlet]=\"optionIconTemplate\"\n [ngTemplateOutletContext]=\"{ option: currentValue }\"\n ></ng-template>\n <span>&nbsp;&nbsp;</span>\n <ng-template\n [ngTemplateOutlet]=\"optionTemplate.templateRef!\"\n [ngTemplateOutletContext]=\"{ option: currentValue, text: currentValue[optionTextProperty] }\"\n ></ng-template>\n </span>\n }\n </div>\n @if (onLaunch.observed) {\n <mat-icon\n class=\"vd-select-launch-readonly\"\n (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\"\n >launch</mat-icon\n >\n }\n </div>\n } @if (!currentValue) {\n <div>&nbsp;</div>\n }\n</div>\n}\n<!-- #endregion -->\n", styles: [".vd-select-launch{position:absolute;right:30px;top:-5px;font-size:18px;cursor:pointer}.readonly-value{padding-right:24px;opacity:.6;min-height:15px}.vd-select-launch-readonly{position:absolute;right:0;top:9px;font-size:18px;cursor:pointer}.vd-select-filter-wrap{background:inherit;position:sticky;top:-8px;box-sizing:border-box;z-index:100}.vd-select-filter-wrap .vd-select-filter-inner{z-index:100;display:flex;flex-direction:row;align-items:center;background:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter{box-shadow:none;padding:16px 16px 16px 0;box-sizing:border-box;width:100%;border:none;background-color:inherit;color:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter:focus-visible{border:none;outline:none}.vd-select-filter-wrap .mat-divider{display:block;width:100%;border-top-width:1px;border-top-style:solid;box-sizing:border-box}::ng-deep .mat-mdc-select-trigger{display:flex!important}::ng-deep .mat-mdc-select-trigger .mat-icon{display:flex;margin-right:8px}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix{padding-top:4px!important;padding-bottom:4px!important}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix .mat-mdc-select-trigger{height:100%}.mat-mdc-select mat-select-trigger .option-text,.mat-mdc-select .mat-mdc-option .option-text{display:contents!important}.mat-mdc-select mat-select-trigger .option-text.option-has-hint,.mat-mdc-select .mat-mdc-option .option-text.option-has-hint{line-height:.92em}.mat-mdc-select mat-select-trigger .option-text .option-hint,.mat-mdc-select .mat-mdc-option .option-text .option-hint{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .option-text,.mat-mdc-select:not(.mat-mdc-select-multiple) .mat-mdc-option .option-text{width:calc(100% - 36px)}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}\n"] }]
16813
+ ], template: "<mat-select [placeholder]=\"placeholder\" i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelect\" (selectionChange)=\"handleChange($event)\" [hidden]=\"readonly\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled\" flex>\n <!-- #region Filter input -->\n <div class=\"mat-mdc-form-field mat-form-field-appearance-fill flex\">\n <div class=\"mat-mdc-text-field-wrapper mdc-text-field mdc-text-field--filled mdc-text-field--no-label\">\n <div class=\"mat-mdc-form-field-focus-overlay\"></div>\n <div class=\"mat-mdc-form-field-flex\">\n <div class=\"mat-mdc-form-field-infix\" layout=\"row\" flex>\n <input matInput #filterInput type=\"text\" placeholder=\"Filter...\" class=\"mat-mdc-input-element vd-select-filter mat-mdc-form-field-input-control mdc-text-field__input\" (keyup)=\"handleFilter($event)\" flex />\n @if (filterInput?.value) {\n <mat-icon (click)=\"filterInput!.value = ''; handleFilter($event);\" fontSet=\"material-symbols-outlined\">close</mat-icon>\n }\n </div>\n </div>\n <div class=\"mdc-line-ripple\"></div>\n </div>\n </div>\n <!-- #endregion -->\n <!-- #region Selection template -->\n <ng-template #selectionTemplate let-label=\"label\">\n <span i18n=\"@@selection\">{ label, select, option {option} other { {{ label }} } }</span>\n </ng-template>\n <!-- #endregion -->\n <!-- #region Option template -->\n <ng-template #optionTextTemplate let-option=\"option\">\n <span layout=\"column\" class=\"option-text\" [ngClass]=\"{'option-has-hint': $safeNavigationMigration(option.hint?.length) > 0}\">\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n <span class=\"mat-caption text-secondary option-hint\" [matTooltip]=\"option.hint\">{{option.hint}}</span>\n </span>\n </ng-template>\n <!-- #endregion -->\n <!-- #region Option icon template -->\n <ng-template #optionIconTemplate let-option=\"option\" let-isAvatar=\"isAvatar\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n }\n @if (svgIconKey && !matIconKey) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"$safeNavigationMigration(option.icon?.svgIcon)\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n <!-- #region Dynamic icon -->\n @if (optionIcon; as optionIcon) {\n <ng-template #optionIconTemplate [ngTemplateOutlet]=\"optionIconTemplate\" let-optionIcon=\"optionIcon\" [ngTemplateOutletContext]=\"{ optionIcon: optionIcon(option) }\">\n @if (optionIcon.svgIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [svgIcon]=\"optionIcon.svgIcon\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n @if (optionIcon.matIcon) {\n <mat-icon [class.mat-mdc-chip-avatar]=\"isAvatar\" [fontSet]=\"optionIcon.fontSet || 'material-symbols-outlined'\">{{optionIcon.matIcon}}</mat-icon>\n }\n </ng-template>\n }\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n <!-- #region Option icon template -->\n <ng-template #optionIconChipAvatarTemplate let-option=\"option\">\n <!-- #region Property icon -->\n <span class=\"option-icon\" matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n <!-- #endregion -->\n </ng-template>\n <!-- #endregion -->\n <!-- #region Trigger for launch button -->\n @if (onLaunch.observed) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n }\n }\n </span>\n <mat-icon class=\"vd-select-launch\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n <!-- #region Custom trigger template -->\n @if (!onLaunch.observed && triggerTemplate && triggerTemplate.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <ng-template [ngTemplateOutlet]=\"triggerTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: selectedOptions }\"></ng-template>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n <!-- #region Option template as trigger -->\n @if (!onLaunch.observed && !triggerTemplate?.templateRef && optionTemplate?.templateRef) {\n <mat-select-trigger [class]=\"triggerCssClass\">\n <span layout=\"row\" layout-align=\"start center\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n @if (multiple) {\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n </mat-chip>\n }\n @else\n {\n <span layout=\"row\" layout-align=\"start center\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n </span>\n }\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n <!-- #region Trigger for icons -->\n @if (!triggerTemplate?.templateRef && !optionTemplate?.templateRef) {\n <mat-select-trigger>\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n @if (multiple) {\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n </mat-chip>\n }\n @else {\n <ng-template [ngTemplateOutlet]=\"optionIconChipAvatarTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n <ng-template [ngTemplateOutlet]=\"optionTextTemplate\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n }\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n }\n }\n </span>\n </mat-select-trigger>\n }\n <!-- #endregion -->\n <!-- #region Default option -->\n @if (!multiple && defaultOption) {\n <mat-option class=\"tc-grey-500\" i18n=\"@@pleaseSelect\">--- Please Select ---</mat-option>\n }\n <!-- #endregion -->\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-option [value]=\"mapper ? option : option[optionValueProperty]\" [disabled]=\"$safeNavigationMigration(option?.disabled)\">\n <!-- #region Property icon -->\n @if (matIconKey && !svgIconKey) {\n <mat-icon [fontSet]=\"fontSet || 'material-symbols-outlined'\">{{option[matIconKey]}}</mat-icon>\n } @if (svgIconKey && !matIconKey) {\n <mat-icon [svgIcon]=\"option[svgIconKey]\" [fontSet]=\"fontSet || 'material-symbols-outlined'\"></mat-icon>\n }\n <!-- #endregion -->\n <!-- #region Option icon -->\n @if (option.icon?.matIcon) {\n <mat-icon [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\">{{option.icon?.matIcon}}</mat-icon>\n }\n @if (option.icon?.svgIcon) {\n <mat-icon [svgIcon]=\"$safeNavigationMigration(option.icon?.svgIcon)\" [fontSet]=\"option.icon?.fontSet || 'material-symbols-outlined'\" [ngStyle]=\"{ color: option.icon?.iconColor??'' }\"></mat-icon>\n }\n <!-- #endregion -->\n <!-- #region Text -->\n <span layout=\"column\" layout-align=\"start center\" class=\"option-text\" [ngClass]=\"{'option-has-hint':$safeNavigationMigration(option.hint?.length)>0}\">\n @if (!optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: option[optionTextProperty] }\"></ng-template>\n }\n @if (optionTemplate && optionTemplate.templateRef) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: option, text: option[optionTextProperty] }\"></ng-template>\n }\n <!-- #endregion -->\n <span class=\"mat-caption text-secondary option-hint\" [matTooltip]=\"option.hint\">{{option.hint}}</span>\n </span>\n </mat-option>\n }\n <!-- #endregion -->\n</mat-select>\n<!-- #region Read only value -->\n@if (readonly) {\n @if (currentValue) {\n <div class=\"readonly-value\">\n @if (!optionTemplate?.templateRef && !triggerTemplate?.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"readonly-content\">\n @for (option of selectedOptions; track option; let i = $index; let last = $last) {\n <span layout=\"row\" layout-align=\"start center\">\n @if(!this.multiple) {\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span>&nbsp;&nbsp;</span>\n }\n <span class=\"readonly-ellipsis-text\">\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: currentValue[optionTextProperty] }\"></ng-template>\n </span>\n }\n @else if(currentValue[i]){\n <mat-chip>\n @if(optionIcon || matIconKey || svgIconKey || option.icon) {\n <span matChipAvatar>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue[i] }\"></ng-template>\n </span>\n }\n <ng-template [ngTemplateOutlet]=\"selectionTemplate\" [ngTemplateOutletContext]=\"{ label: currentValue[i][optionTextProperty] }\"></ng-template>\n </mat-chip>\n }\n </span>\n @if (!last) {\n <span>&nbsp;&nbsp;</span>\n }\n }\n </span>\n }\n @if (triggerTemplate && triggerTemplate.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger readonly-content\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span>&nbsp;&nbsp;</span>\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span class=\"readonly-ellipsis-text\">\n <ng-template [ngTemplateOutlet]=\"triggerTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ trigger: currentValue }\"></ng-template>\n </span>\n </span>\n }\n @if (optionTemplate && optionTemplate.templateRef && !triggerTemplate?.templateRef) {\n <span layout=\"row\" layout-align=\"start center\" class=\"option-trigger readonly-content\">\n <ng-template [ngTemplateOutlet]=\"optionIconTemplate\" [ngTemplateOutletContext]=\"{ option: currentValue }\"></ng-template>\n <span>&nbsp;&nbsp;</span>\n <span class=\"readonly-ellipsis-text\">\n <ng-template [ngTemplateOutlet]=\"optionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: currentValue, text: currentValue[optionTextProperty] }\"></ng-template>\n </span>\n </span>\n }\n </div>\n @if (onLaunch.observed) {\n <mat-icon class=\"vd-select-launch-readonly\" (click)=\"$event.stopPropagation(); handleLaunchClicked(value)\">launch</mat-icon>\n }\n }\n @if (!currentValue) {\n <div>&nbsp;</div>\n }\n}\n<!-- #endregion -->", styles: [":host{display:block;width:100%;min-width:0}.vd-select-launch{position:absolute;right:30px;top:-5px;font-size:18px;cursor:pointer}.readonly-value{padding-right:24px;opacity:.6;min-height:15px;display:flex;align-items:center;width:0;flex:1 1 auto;max-width:100%;min-width:0;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.readonly-value>*{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.readonly-value .readonly-content{display:flex;align-items:center;width:0;flex:1 1 auto;max-width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.readonly-value .readonly-ellipsis-text{display:block;flex:1 1 auto;min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.readonly-value .readonly-content [layout=row],.readonly-value .readonly-content .option-text,.readonly-value .readonly-content .mat-mdc-chip,.readonly-value .readonly-content .mat-mdc-chip-action-label,.readonly-value .readonly-content .mat-mdc-standard-chip{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vd-select-launch-readonly{position:absolute;right:0;top:9px;font-size:18px;cursor:pointer}.vd-select-filter-wrap{background:inherit;position:sticky;top:-8px;box-sizing:border-box;z-index:100}.vd-select-filter-wrap .vd-select-filter-inner{z-index:100;display:flex;flex-direction:row;align-items:center;background:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter{box-shadow:none;padding:16px 16px 16px 0;box-sizing:border-box;width:100%;border:none;background-color:inherit;color:inherit}.vd-select-filter-wrap .vd-select-filter-inner .vd-select-filter:focus-visible{border:none;outline:none}.vd-select-filter-wrap .mat-divider{display:block;width:100%;border-top-width:1px;border-top-style:solid;box-sizing:border-box}::ng-deep .mat-mdc-select-trigger{display:flex!important}::ng-deep .mat-mdc-select-trigger .mat-icon{display:flex;margin-right:8px}::ng-deep .mat-mdc-form-field-type-vd-select .mat-mdc-form-field-infix{display:flex;align-items:center;min-width:0;max-width:100%;width:100%}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix{padding-top:4px!important;padding-bottom:4px!important}::ng-deep .mat-mdc-form-field-type-vd-select-multiple .mat-mdc-form-field-infix .mat-mdc-select-trigger{height:100%}.mat-mdc-select mat-select-trigger .option-text,.mat-mdc-select .mat-mdc-option .option-text{display:contents!important}.mat-mdc-select mat-select-trigger .option-text.option-has-hint,.mat-mdc-select .mat-mdc-option .option-text.option-has-hint{line-height:.92em}.mat-mdc-select mat-select-trigger .option-text .option-hint,.mat-mdc-select .mat-mdc-option .option-text .option-hint{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .option-text,.mat-mdc-select:not(.mat-mdc-select-multiple) .mat-mdc-option .option-text{width:calc(100% - 36px)}.mat-mdc-select:not(.mat-mdc-select-multiple) mat-select-trigger .mat-mdc-form-field-infix{padding-top:8px;padding-bottom:8px}\n"] }]
16472
16814
  }], ctorParameters: () => [], propDecorators: { optionTemplate: [{
16473
16815
  type: ContentChild,
16474
16816
  args: [VdSelectOptionDirective]
@@ -16799,57 +17141,239 @@ class TableDataSource extends DataSource {
16799
17141
  /**
16800
17142
  * Get selected Items
16801
17143
  */
16802
- getSelected = (key) => this.selectionModel.selected.map(x => x[key]);
17144
+ getSelected = (key) => this.selectionModel.selected.map(x => x[key]);
17145
+ /**
17146
+ * Get selected Items
17147
+ */
17148
+ getSelectedIds = () => this.getSelected('id');
17149
+ }
17150
+
17151
+ class DataSourceFilterDirective {
17152
+ /**
17153
+ * DataSource instance
17154
+ */
17155
+ dataSource;
17156
+ /**
17157
+ * Represents a value that changes over time.
17158
+ * Observers can subscribe to the subject to receive filter changes
17159
+ */
17160
+ _queryChange = new BehaviorSubject(null);
17161
+ /**
17162
+ * Sets query
17163
+ */
17164
+ set dataSourceFilter(query) { this._queryChange.next(query); }
17165
+ /**
17166
+ * Gets query
17167
+ */
17168
+ get dataSourceFilter() { return this._queryChange.value; }
17169
+ /**
17170
+ * Lifecycle hook that is called after data-bound properties of a directive are initialized.
17171
+ */
17172
+ ngOnInit() {
17173
+ this._queryChange.subscribe(() => {
17174
+ if (this.dataSource) {
17175
+ /* Update the filters */
17176
+ Object.assign(this.dataSource.staticFieldFilters || {}, this.dataSourceFilter != null ? this.dataSourceFilter : {});
17177
+ /* Reload data */
17178
+ this.dataSource.reload();
17179
+ }
17180
+ });
17181
+ }
17182
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: DataSourceFilterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
17183
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: DataSourceFilterDirective, isStandalone: true, selector: "[dataSourceFilter]", inputs: { dataSource: "dataSource", dataSourceFilter: "dataSourceFilter" }, ngImport: i0 });
17184
+ }
17185
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: DataSourceFilterDirective, decorators: [{
17186
+ type: Directive,
17187
+ args: [{
17188
+ selector: '[dataSourceFilter]'
17189
+ }]
17190
+ }], propDecorators: { dataSource: [{
17191
+ type: Input
17192
+ }], dataSourceFilter: [{
17193
+ type: Input
17194
+ }] } });
17195
+
17196
+ /**
17197
+ * Class representing the structure and behavior of a table definition.
17198
+ * It defines various configurations such as column settings, actions,
17199
+ * and callbacks for rows and data handling.
17200
+ *
17201
+ * @template T - The type of data represented in the table rows.
17202
+ */
17203
+ class TableDefinition {
17204
+ /**
17205
+ * @property endpoint
17206
+ * @description API endpoint from which table data will be fetched.
17207
+ * @type {string}
17208
+ */
17209
+ endpoint = '';
17210
+ /**
17211
+ * @property projection
17212
+ * @description Optional projection for specifying which fields should be included
17213
+ * in the fetched data. Can be a single string or an array of field names.
17214
+ * @type {string | string[]}
17215
+ */
17216
+ projection;
17217
+ /**
17218
+ * @property includes
17219
+ * @description Optional array of related data entities (includes) to be retrieved along
17220
+ * with the main data set.
17221
+ * @type {string[]}
17222
+ */
17223
+ includes;
17224
+ /**
17225
+ * @property showAction
17226
+ * @description Flag to indicate if action columns (e.g., edit, delete buttons)
17227
+ * should be displayed in the table. Defaults to `true`.
17228
+ * @type {boolean}
17229
+ */
17230
+ showAction = true;
17231
+ /**
17232
+ * @property selectable
17233
+ * @description Flag to indicate if rows can be selected (e.g., with checkboxes).
17234
+ * Defaults to `true`.
17235
+ * @type {boolean}
17236
+ */
17237
+ selectable = true;
17238
+ /**
17239
+ * @property addable
17240
+ * @description Flag to indicate if new items can be added to the table.
17241
+ * Defaults to `true`.
17242
+ * @type {boolean}
17243
+ */
17244
+ addable = true;
17245
+ /**
17246
+ * @property editable
17247
+ * @description Flag to indicate if rows can be edited. Defaults to `true`.
17248
+ * @type {boolean}
17249
+ */
17250
+ editable = true;
17251
+ /**
17252
+ * @property deletable
17253
+ * @description Flag to indicate if rows can be deleted. Defaults to `true`.
17254
+ * @type {boolean}
17255
+ */
17256
+ deletable = true;
17257
+ /**
17258
+ * @property downloadable
17259
+ * @description Flag to indicate if table data can be downloaded (e.g., as CSV or Excel).
17260
+ * @type {boolean}
17261
+ */
17262
+ downloadable;
17263
+ /**
17264
+ * @property duplicable
17265
+ * @description Flag to indicate if rows can be duplicated.
17266
+ * @type {boolean}
17267
+ */
17268
+ duplicable;
17269
+ /**
17270
+ * @property exportable
17271
+ * @description Determines if the table is exportable.
17272
+ * @type {boolean}
17273
+ */
17274
+ exportable = true;
17275
+ /**
17276
+ * @property exportFileName
17277
+ * @description The name of the file to export.
17278
+ * @type {string}
17279
+ */
17280
+ exportFileName;
17281
+ /**
17282
+ * @property sticky
17283
+ * @description Flag to indicate whether the table headers or columns should stick
17284
+ * to the viewport during scrolling. Defaults to `false`.
17285
+ * @type {boolean}
17286
+ */
17287
+ sticky = false;
17288
+ /**
17289
+ * @property columns
17290
+ * @description Array of table columns that define the structure and data types
17291
+ * of each column in the table.
17292
+ * @type {TableColumn<T>[]}
17293
+ */
17294
+ columns = [];
17295
+ /**
17296
+ * @property hideColumns
17297
+ * @description Optional array of column keys that should be hidden from view.
17298
+ * @type {string[]}
17299
+ */
17300
+ hideColumns;
17301
+ /**
17302
+ * @property rowNgClass
17303
+ * @description Function to dynamically assign CSS classes to rows based on the row data
17304
+ * and context. Can be used for conditional row styling.
17305
+ * @type {(x?: T, ctx?: IGenericListComponent<T>) => any}
17306
+ */
17307
+ rowNgClass;
16803
17308
  /**
16804
- * Get selected Items
17309
+ * @property rowClick
17310
+ * @description Callback function for handling row click events.
17311
+ * Invoked when a row is clicked.
17312
+ * @type {(x?: T, ctx?: IGenericListComponent<T>) => any}
16805
17313
  */
16806
- getSelectedIds = () => this.getSelected('id');
16807
- }
16808
-
16809
- class DataSourceFilterDirective {
17314
+ rowClick;
16810
17315
  /**
16811
- * DataSource instance
17316
+ * @property onEdit
17317
+ * @description Callback function for handling edit actions.
17318
+ * Invoked when the edit button is clicked for a row.
17319
+ * @type {(x?: T, ctx?: IGenericListComponent<T>) => any}
16812
17320
  */
16813
- dataSource;
17321
+ onEdit;
16814
17322
  /**
16815
- * Represents a value that changes over time.
16816
- * Observers can subscribe to the subject to receive filter changes
17323
+ * @property detailsTemplate
17324
+ * @description Name of the template to use for displaying additional row details.
17325
+ * @type {string}
16817
17326
  */
16818
- _queryChange = new BehaviorSubject(null);
17327
+ detailsTemplate;
16819
17328
  /**
16820
- * Sets query
17329
+ * @property actions
17330
+ * @description Array of action items (e.g., custom buttons) available for each row in the table.
17331
+ * Actions can be context-sensitive based on the row data and table context.
17332
+ * @type {ActionItem<T, IGenericListComponent<T>>[]}
16821
17333
  */
16822
- set dataSourceFilter(query) { this._queryChange.next(query); }
17334
+ actions = [];
16823
17335
  /**
16824
- * Gets query
17336
+ * @property columnSets
17337
+ * @description Used to display specific columns in the table.
17338
+ * This array defines sets of columns that can be shown
17339
+ * based on the active configuration, allowing for dynamic table
17340
+ * column customization.
17341
+ * @type {string[]}
16825
17342
  */
16826
- get dataSourceFilter() { return this._queryChange.value; }
17343
+ columnSets = [];
16827
17344
  /**
16828
- * Lifecycle hook that is called after data-bound properties of a directive are initialized.
17345
+ * Constructor for initializing the table definition with optional values.
17346
+ * Merges the provided initialization object with default properties.
17347
+ *
17348
+ * @param init - Optional partial table definition to initialize values.
16829
17349
  */
16830
- ngOnInit() {
16831
- this._queryChange.subscribe(() => {
16832
- if (this.dataSource) {
16833
- /* Update the filters */
16834
- Object.assign(this.dataSource.staticFieldFilters || {}, this.dataSourceFilter != null ? this.dataSourceFilter : {});
16835
- /* Reload data */
16836
- this.dataSource.reload();
16837
- }
16838
- });
17350
+ constructor(init) {
17351
+ Object.assign(this, init);
16839
17352
  }
16840
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: DataSourceFilterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
16841
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: DataSourceFilterDirective, isStandalone: true, selector: "[dataSourceFilter]", inputs: { dataSource: "dataSource", dataSourceFilter: "dataSourceFilter" }, ngImport: i0 });
16842
17353
  }
16843
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: DataSourceFilterDirective, decorators: [{
16844
- type: Directive,
16845
- args: [{
16846
- selector: '[dataSourceFilter]'
16847
- }]
16848
- }], propDecorators: { dataSource: [{
16849
- type: Input
16850
- }], dataSourceFilter: [{
16851
- type: Input
16852
- }] } });
17354
+
17355
+ /**
17356
+ * Gets classes decoarated with @Table
17357
+ * @param origin
17358
+ * @returns
17359
+ */
17360
+ function getTableDefinition(origin) {
17361
+ /* Save the table defintion in the metadata */
17362
+ var tableDefinition = Reflect.getMetadata(TABLE_DEFINITION_METADATA_KEY, origin) ?? new TableDefinition({});
17363
+ if (tableDefinition) {
17364
+ /* Set column in the table definition */
17365
+ tableDefinition.columns = Reflect.getMetadata(TABLE_COLUMNS_METADATA_KEY, Reflect.construct(origin, []))
17366
+ ?.filter((x) => !x.hidden && !tableDefinition.hideColumns?.some(y => y.trim() == x.name.trim()));
17367
+ /* Sort the columns by index */
17368
+ Utils.sortArray(tableDefinition.columns || [], 'index');
17369
+ /* Set endpoint from the decorator @Api, if any */
17370
+ var endpoint = Reflect.getMetadata(endpointMetadataKey, origin);
17371
+ if (endpoint) {
17372
+ tableDefinition.endpoint = endpoint;
17373
+ }
17374
+ }
17375
+ return tableDefinition;
17376
+ }
16853
17377
 
16854
17378
  /**
16855
17379
  * A generic datasource class for working with data-tables in Angular Material.
@@ -18240,6 +18764,10 @@ class VdDynamicTableComponent {
18240
18764
  updateColumns() {
18241
18765
  /* Sort the columns by index */
18242
18766
  Utils.sortArray(this.columns || [], 'index');
18767
+ /* Cache responsive display classes once per column */
18768
+ this.columns?.forEach(column => {
18769
+ column.displayNgClass = this.getDisplayClasses(column);
18770
+ });
18243
18771
  /* Trigger changes */
18244
18772
  this.columnsSubject.next(this.columns);
18245
18773
  }
@@ -18395,20 +18923,47 @@ class VdDynamicTableComponent {
18395
18923
  keys.slice(0, -1).reduce((acc, key) => acc && acc[key], row)[keys[keys.length - 1]] = value;
18396
18924
  }
18397
18925
  /**
18398
- * Gets row classes
18399
- * @param column
18400
- * @param row
18401
- * @returns
18926
+ * Retrieves the display setting for a given column, which can be either a static value or a function.
18927
+ * If the display property is a function, it will be invoked with the current column sets and context.
18928
+ * @param column - The TableColumn object for which to retrieve the display setting.
18929
+ * @returns The display setting for the column, which can be a Grid value or undefined.
18930
+ */
18931
+ getColumnDisplay(column) {
18932
+ /* If the display property is a function, invoke it with the current column sets and context */
18933
+ if (typeof column.display === 'function') {
18934
+ return column.display(this.columnSets || [], this.context);
18935
+ }
18936
+ return column.display;
18937
+ }
18938
+ /**
18939
+ * Computes the CSS classes for a column based on its display setting.
18940
+ * It maps the display value to corresponding CSS classes that control visibility and layout.
18941
+ * @param column - The TableColumn object for which to compute the display classes.
18942
+ * @returns An object containing CSS class names as keys and boolean values indicating whether the class should be applied.
18943
+ */
18944
+ getDisplayClasses(column) {
18945
+ /* Retrieve the display setting for the column, which may be a static value or computed dynamically. */
18946
+ const display = this.getColumnDisplay(column);
18947
+ /* Return an object mapping display values to CSS classes, allowing for responsive visibility control. */
18948
+ return {
18949
+ 'gt-xs': display == Grid.Xs,
18950
+ 'gt-sm': display == Grid.Sm,
18951
+ 'gt-md': display == Grid.Md,
18952
+ 'gt-lg': display == Grid.Lg,
18953
+ 'gt-xl': display == Grid.Xl,
18954
+ 'gt-xxl': display == Grid.Xxl,
18955
+ 'hidden': display == Grid.None,
18956
+ };
18957
+ }
18958
+ /**
18959
+ * Computes the CSS classes for a specific row based on the column's display settings and any additional classes defined.
18960
+ * It combines the column's display classes, any custom classes defined in `cellNgClass`, and a 'text-right' class if `arrowBefore` is true.
18961
+ * @param column - The TableColumn object for which to compute the row classes.
18962
+ * @param row - The data object representing the current row.
18963
+ * @returns An object containing CSS class names as keys and boolean values indicating whether the class should be applied.
18402
18964
  */
18403
18965
  getRowClasses(column, row) {
18404
- return Object.assign({
18405
- 'gt-xs': column.display == Grid.Xs,
18406
- 'gt-sm': column.display == Grid.Sm,
18407
- 'gt-md': column.display == Grid.Md,
18408
- 'gt-lg': column.display == Grid.Lg,
18409
- 'gt-xl': column.display == Grid.Xl,
18410
- 'gt-xxl': column.display == Grid.Xxl,
18411
- 'hidden': column.display == Grid.None,
18966
+ return Object.assign({}, column.displayNgClass || this.getDisplayClasses(column), {
18412
18967
  'text-right': column.arrowBefore
18413
18968
  }, column.cellNgClass ? column.cellNgClass(row, this.context) : {});
18414
18969
  }
@@ -18453,7 +19008,7 @@ class VdDynamicTableComponent {
18453
19008
  this.changeDetector.detectChanges();
18454
19009
  }
18455
19010
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: VdDynamicTableComponent, deps: [{ token: DynamicBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
18456
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: VdDynamicTableComponent, isStandalone: true, selector: "vd-dynamic-table", inputs: { dataSource: "dataSource", data: "data", parentControl: "parentControl", entityObject: "entityObject", formArray: "formArray", debugValue: "debugValue", classType: "classType", context: "context", dataSourceFilter: "dataSourceFilter", static: "static", filterable: "filterable", sticky: "sticky", tableWidth: "tableWidth", useFilterOperator: "useFilterOperator", paginable: "paginable", selectable: "selectable", sortActive: "sortActive", sortDirection: "sortDirection", stickyHeader: "stickyHeader", stickyFilter: "stickyFilter", columnSets: "columnSets", rowNgClass: "rowNgClass", detailsTemplate: "detailsTemplate", readonly: "readonly", selectAllFilter: "selectAllFilter", paginatorRef: "paginatorRef", columns: "columns", rowMenuItems: "rowMenuItems", rowAction: "rowAction", excludedColumns: "excludedColumns", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions" }, outputs: { rowClick: "rowClick" }, queries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "table", first: true, predicate: ["table"], descendants: true }, { propertyName: "matSort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, static: true }, { propertyName: "detailsTemplateRef", predicate: ["detailsTemplate"], descendants: true, read: ViewContainerRef }, { propertyName: "rowContextMenuTriggers", predicate: MatMenuTrigger, descendants: true }], ngImport: i0, template: "@if (!static) {\r\n <div class=\"loading-progress\">\r\n @if (dataSource?.isLoading) {\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n }\r\n </div>\r\n}\r\n\r\n<!-- #region Data table -->\r\n<div class=\"mat-table-container scrollbar-secondary\" [ngClass]=\"{'mat-table-sticky': sticky}\" #scrollContainer>\r\n <table mat-table #table [dataSource]=\"dataSource\" [dataSourceFilter]=\"dataSourceFilter\" [ngClass]=\"{'table-fixed': !sticky && !detailsTemplate && !templateRef, 'table-stick': sticky}\" [trackBy]=\"trackBy\" matSort matSortDisableClear [matSortActive]=\"sortActive||'id'\" [matSortDirection]=\"sortDirection\" multiTemplateDataRows>\r\n @for (column of columns$ | async; track columnsTrackBy($index, column)) {\r\n <!-- #region Column def -->\r\n <ng-container [cdkColumnDef]=\"column.name\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\r\n <ng-template #header [ngTemplateOutlet]=\"header\" let-headerText=\"headerText\" [ngTemplateOutletContext]=\"{headerText: column.header | func:context}\">\r\n <th mat-header-cell *cdkHeaderCellDef [mat-sort-header]=\"column.sortBy || column.name\" [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [disabled]=\"column.type == ColumnType.Checkbox || column.disabled\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\" [arrowPosition]=\"column.arrowBefore?'before':'after'\">\r\n @if (column.type == ColumnType.Checkbox) {\r\n <mat-checkbox (change)=\"$event ? dataSource.toggleSelect($event, selectAllFilter) : null\" [disabled]=\"!dataSource.paginator?.length\" [checked]=\"dataSource.selectionModel.hasValue() && dataSource.isAllSelected()\" [indeterminate]=\"dataSource.selectionModel.hasValue() && !dataSource.isAllSelected()\"></mat-checkbox>\r\n } @if (column.type != ColumnType.Checkbox) {\r\n <span [matTooltip]=\"headerText\">{{headerText}}</span>\r\n }\r\n </th>\r\n </ng-template>\r\n <td mat-cell *cdkCellDef=\"let row; let rowIndex = dataIndex\" [matTooltip]=\"column.tooltip?column.tooltip(row, undefined, context):null\" [matTooltipClass]=\"column.tooltipClass??''\" [hidden]=\"column.hidden\" [ngClass]=\"getRowClasses(column, row)\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\">\r\n <ng-template #rowVal [ngTemplateOutlet]=\"rowVal\" let-rowValue [ngTemplateOutletContext]=\"{$implicit: column?.content && column?.content(row, undefined, context)}\">\r\n @switch (column.type) {\r\n <!-- #region Checkbox column -->\r\n @case (ColumnType.Checkbox) {\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? dataSource.selectionModel.toggle(row) : null\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [checked]=\"dataSource.selectionModel.isSelected(row)\"></mat-checkbox>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Enum column -->\r\n @case (ColumnType.Enum) {\r\n <span>\r\n @if (column.enumMetadata) {\r\n @if (column.multiple) {\r\n @for (item of rowValue; track item; let i = $index) {\r\n @if (i < 2) {\r\n <ng-template let-displayValue=\"displayValue\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ displayValue: column.enumMetadata[item].display }\"></ng-template>\r\n }\r\n @if (i === 1 && rowValue?.length > 2) {\r\n <small [matTooltip]=\"(rowValue | slice:2 | map:column.enumMetadata | map:'display') | join:'\\n'\" matTooltipClass=\"mat-tooltip-multiline\">...</small>\r\n }\r\n }\r\n <ng-template #template let-displayValue=\"displayValue\">\r\n <mat-chip-row disableRipple=\"true\" selectable=\"false\" [matTooltip]=\"displayValue\">\r\n <span>{{ displayValue }}</span>\r\n </mat-chip-row>\r\n </ng-template>\r\n } @else {\r\n @if (rowValue >= 0) {\r\n <span class=\"na\" [ngStyle]=\"{ color: ((column.enumMetadata[rowValue] || {}).textColor || 'inherit') }\" [innerHtml]=\"(column.enumMetadata[rowValue]||{}).display\"></span>\r\n }\r\n }\r\n } @else {\r\n @if (column.multiple) {\r\n @for (item of rowValue; track item; let i = $index; let last = $last) {\r\n <div>\r\n @if (i<2) {\r\n <small>\r\n <msa-enum-display [value]=\"item\" [enumType]=\"column.enumType\" [metadata]=\"column.enumMetadata\"></msa-enum-display>\r\n </small>\r\n } @if (i==1 && rowValue?.length > 2) {\r\n <small>, ...</small>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @if (rowValue >= 0) {\r\n <msa-enum-display [value]=\"rowValue\" [enumType]=\"column.enumType\" [metadata]=\"column.enumMetadata\"></msa-enum-display>\r\n }\r\n }\r\n }\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Toggle column -->\r\n @case (ColumnType.Toggle) {\r\n @if (!formArray) {\r\n <mat-slide-toggle [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);handleModelChange(column, row, undefined);\" (click)=\"$event.stopPropagation();\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" color=\"accent\"></mat-slide-toggle>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Date column -->\r\n @case (ColumnType.Date) {\r\n <span>{{rowValue | date:column.shortDate?'dd.MM.yyyy':'dd.MM.yyyy HH:mm:ss'}}</span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Text Input column -->\r\n @case (ColumnType.TextInput) {\r\n @if (!formArray) {\r\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\r\n @if (!formArray) {\r\n <input matInput type=\"{{column.inputType}}\" autocomplete=\"none\" name=\"{{column.name}}{{rowIndex}}\" [ngModel]=\"row | property:column.name\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [min]=\"column.inputMin?column.inputMin(row, undefined, context):null\" [max]=\"column.inputMax?column.inputMax(row, undefined, context):null\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);(column.change?column.change(row, undefined, context):patch(row, [column.name], $event, column.patchIncludes));\" [ngModelOptions]=\"{updateOn: 'blur'}\" (keydown.enter)=\"handleKeydownEnter($event)\" />\r\n }\r\n </mat-form-field>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region VD-Select column -->\r\n @case (ColumnType.Select) {\r\n @if (!formArray) {\r\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\r\n @if (!formArray) {\r\n <vd-select name=\"{{column.name}}{{rowIndex}}\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"$safeNavigationMigration(column?.enumFilter) | func:row:context\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" (change)=\"column.change?column.change(row, undefined, context):patch(row, [column.name], $event.value, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\r\n }\r\n </mat-form-field>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Action -->\r\n @case (ColumnType.Action) {\r\n @if (column.menu) {\r\n @if (menu?.matMenu && !row.locked && hasVisibleRowMenuItems(row, column)) {\r\n <div id=\"menu-{{row.id}}\" style=\"visibility: hidden; position: fixed\" #contextMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"menu.matMenu!\"></div>\r\n }\r\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\" #menu></vd-dynamic-menu>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Menu -->\r\n @case (ColumnType.Menu) {\r\n @if (column.menu) {\r\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\"></vd-dynamic-menu>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region icon -->\r\n @case (ColumnType.Icon) {\r\n <span layout=\"row\" layout-align=\"start center\">\r\n @if(column && column.icon){\r\n @if ( column.icon.matIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\">{{handleExpression($safeNavigationMigration(column.icon.matIcon)!, row)}}</mat-icon>\r\n }\r\n @if (column.icon.svgIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\" [svgIcon]=\"handleExpression($safeNavigationMigration(column.icon.svgIcon)!, row)!\"></mat-icon>\r\n }\r\n @if (column.icon.fontIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\" [fontIcon]=\"handleExpression($safeNavigationMigration(column.icon.fontIcon)!, row)!\"></mat-icon>\r\n }\r\n }\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region icon button -->\r\n @case (ColumnType.IconButton) {\r\n <a mat-icon-button (click)=\"$event.stopPropagation();column.iconButton?.event?column.iconButton.event(row, context):null\">\r\n <mat-icon fontSet=\"{{column.iconButton?.iconFontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.iconButton?.iconClass??'', row)\">{{handleExpression(column.iconButton?.icon??'radio_button_checked', row) || 'radio_button_checked'}}</mat-icon>\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Other column types -->\r\n @default {\r\n <span [innerHtml]=\"rowValue??''\"></span>\r\n }\r\n <!-- #endregion -->\r\n }\r\n <ng-template #recursiveContainer let-columnNameSegments=\"segments\" let-formGroup=\"formGroup\" let-parentFormGroup=\"parentFormGroup\">\r\n @if (formGroup) {\r\n <ng-container [formGroup]=\"formGroup\">\r\n <!-- If the columnNameSegments array is empty, we're at the leaf node -->\r\n @if (!columnNameSegments.length) {\r\n @switch (column.type) {\r\n <!-- #region Toggle column -->\r\n @case (ColumnType.Toggle) {\r\n <mat-slide-toggle [formControl]=\"formGroup\" (click)=\"$event.stopPropagation();\" (change)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):handleModelChange(column, parentFormGroup.value, parentFormGroup)\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" color=\"accent\"></mat-slide-toggle>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Text Input column -->\r\n @case (ColumnType.TextInput) {\r\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\r\n <input matInput [formControl]=\"formGroup\" type=\"{{column.inputType}}\" autocomplete=\"none\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" [min]=\"column.inputMin?column.inputMin(parentFormGroup.value, parentFormGroup, context):null\" [max]=\"column.inputMax?column.inputMax(parentFormGroup.value, parentFormGroup, context):null\" (keydown.enter)=\"handleKeydownEnter($event)\" />\r\n </mat-form-field>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region VD-Select column -->\r\n @case (ColumnType.Select) {\r\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\r\n <vd-select [formControl]=\"formGroup\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:parentFormGroup.value:context\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" (selectionChange)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):patch(parentFormGroup.value, [column.name], rowValue, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\r\n </mat-form-field>\r\n }\r\n <!-- #endregion -->\r\n }\r\n } @else {\r\n <!-- If not the last segment, create a nested form group -->\r\n <ng-container [formGroupName]=\"columnNameSegments[0]\">\r\n <!-- Recursive call to handle nested segments -->\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: columnNameSegments.slice(1), parentFormGroup:formGroup, formGroup: formGroup.get(columnNameSegments[0])}\"></ng-container>\r\n </ng-container>\r\n }\r\n </ng-container>\r\n }\r\n </ng-template>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n <!-- #endregion -->\r\n }\r\n\r\n <!-- #region Filter row -->\r\n @if (dataSource && filterable) {\r\n @for (column of columns$ | async; track column) {\r\n <ng-container cdkColumnDef=\"filter.{{column.filter || column.name}}\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\r\n <th mat-header-cell *cdkHeaderCellDef [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\">\r\n <!-- #region Select filter -->\r\n @if(column.endpoint || column.enumType || column.options){\r\n <span filter-select [endpoint]=\"column.endpoint\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:{}:context\" [options]=\"column.options\" [text]=\"column.filterOptionText || 'name'\"></span>\r\n }\r\n <!-- #region Text filter -->\r\n @else if(column.type == ColumnType.Text || column.type == ColumnType.TextInput || column.type == ColumnType.Number) {\r\n <span filter-input [onlyNumber]=\"column.filterInputNumber??false\" [matTooltip]=\"column.filterTooltip ? column.filterTooltip(context):null\" [matTooltipClass]=\"column.filterTooltipClass??''\" [operator]=\"!useFilterOperator ? undefined : column.filterOperator\"></span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Date filter -->\r\n @else if (column.type == ColumnType.Date) {\r\n <span filter-date></span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Action filter (clear) -->\r\n @else if (column.type == ColumnType.Action) {\r\n <span filter-clear></span>\r\n }\r\n <!-- #endregion -->\r\n </th>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n\r\n <!-- #region Details column -->\r\n <ng-container cdkColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let row; let index = index\" [attr.colspan]=\"(displayedColumns$ | async)?.length\">\r\n <div class=\"row-detail\" [@detailExpand]=\"row == expandedRow ? 'expanded' : 'collapsed'\" #detailsTemplate>\r\n @if (templateRef && row === expandedRow) {\r\n <ng-container *ngTemplateOutlet=\"templateRef; context:{row: row, index: index, context: context}\"></ng-container>\r\n }\r\n </div>\r\n </td>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Filter header -->\r\n @if (filterable) {\r\n <tr mat-header-row *cdkHeaderRowDef=\"displayedFilterColumns$ | async\"></tr>\r\n }\r\n <!-- #endregion -->\r\n\r\n <tr mat-header-row *cdkHeaderRowDef=\"displayedColumns$ | async; sticky: stickyFilter\"></tr>\r\n <tr mat-row *cdkRowDef=\"let row; columns: displayedColumns$ | async; let index = dataIndex\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\" [class.expanded-row]=\"expandedRow === row\" (click)=\"handleRowClick(index, row)\" (contextmenu)=\"handleRowRightClick($event, row)\"></tr>\r\n\r\n <!-- #region Detrails row -->\r\n @if (detailsTemplate || templateRef) {\r\n <tr mat-row *cdkRowDef=\"let row; columns: ['expandedDetail']\" class=\"detail-row\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\"></tr>\r\n }\r\n <!-- #endregion -->\r\n </table>\r\n\r\n <!-- #region Modern No Results Message -->\r\n @if (dataSource?.filteredData?.length <= 0 && dataSource?.total <= 0) {\r\n <div class=\"no-results-overlay\">\r\n <mat-icon class=\"no-results-icon\">search_off</mat-icon>\r\n <div class=\"no-results-text mat-body-1\">\r\n <h3 i18n=\"@@noResultsFound\">No results found</h3>\r\n <p i18n=\"@@tryAdjustFilters\">\r\n Try adjusting your filters or search criteria.\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n <!-- #endregion -->\r\n</div>\r\n<!-- #endregion -->\r\n\r\n<!-- #region Debug value -->\r\n@if (debugValue) {\r\n <code>\r\n <pre>{{formValue | json}}</pre>\r\n</code>\r\n}\r\n<!-- #endregion -->\r\n\r\n<div class=\"table-footer\" layout=\"row\">\r\n <ng-content select=\"[table-footer]\"></ng-content>\r\n <span flex></span>\r\n @if (paginable) {\r\n <mat-paginator [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\r\n }\r\n</div>", styles: ["::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-form-field .mat-form-field-wrapper{width:100%}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip{height:24px;margin-top:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:9px;padding-right:9px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip:last-child{margin-bottom:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip *{font-size:.8rem}@media(max-width:389px){::ng-deep .mat-mdc-table [gt-xs],::ng-deep .mat-mdc-table .gt-xs{display:none}::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:599px){::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:959px){::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1279px){::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1919px){::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1979px){::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}.mat-table-container{width:100%;max-width:100%;overflow:auto}.mat-table-container .mat-mdc-header-cell,.mat-table-container .mat-mdc-footer-cell,.mat-table-container .mat-mdc-cell{min-width:80px;box-sizing:border-box}.mat-table-container .mat-mdc-header-row,.mat-table-container .mat-mdc-footer-row,.mat-table-container .mat-mdc-row{min-width:1920px}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-right{box-shadow:-3px 0 5px #0000001a}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-left{box-shadow:3px 0 5px #0000001a}\n"], dependencies: [{ kind: "ngmodule", type: CdkTableModule }, { kind: "directive", type: i2$3.CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "directive", type: i2$3.CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: i2$3.CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: i2$3.CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: i2$3.CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i7.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i10.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i3.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i12.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i12.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i16.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type:
19011
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: VdDynamicTableComponent, isStandalone: true, selector: "vd-dynamic-table", inputs: { dataSource: "dataSource", data: "data", parentControl: "parentControl", entityObject: "entityObject", formArray: "formArray", debugValue: "debugValue", classType: "classType", context: "context", dataSourceFilter: "dataSourceFilter", static: "static", filterable: "filterable", sticky: "sticky", tableWidth: "tableWidth", useFilterOperator: "useFilterOperator", paginable: "paginable", selectable: "selectable", sortActive: "sortActive", sortDirection: "sortDirection", stickyHeader: "stickyHeader", stickyFilter: "stickyFilter", columnSets: "columnSets", rowNgClass: "rowNgClass", detailsTemplate: "detailsTemplate", readonly: "readonly", selectAllFilter: "selectAllFilter", paginatorRef: "paginatorRef", columns: "columns", rowMenuItems: "rowMenuItems", rowAction: "rowAction", excludedColumns: "excludedColumns", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions" }, outputs: { rowClick: "rowClick" }, queries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "table", first: true, predicate: ["table"], descendants: true }, { propertyName: "matSort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, static: true }, { propertyName: "detailsTemplateRef", predicate: ["detailsTemplate"], descendants: true, read: ViewContainerRef }, { propertyName: "rowContextMenuTriggers", predicate: MatMenuTrigger, descendants: true }], ngImport: i0, template: "@if (!static) {\r\n <div class=\"loading-progress\">\r\n @if (dataSource?.isLoading) {\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n }\r\n </div>\r\n}\r\n<!-- #region Data table -->\r\n<div class=\"mat-table-container scrollbar-secondary\" [ngClass]=\"{'mat-table-sticky': sticky}\" #scrollContainer>\r\n <table mat-table #table [dataSource]=\"dataSource\" [dataSourceFilter]=\"dataSourceFilter\" [ngClass]=\"{'table-fixed': !sticky && !detailsTemplate && !templateRef, 'table-stick': sticky}\" [trackBy]=\"trackBy\" matSort matSortDisableClear [matSortActive]=\"sortActive||'id'\" [matSortDirection]=\"sortDirection\" multiTemplateDataRows>\r\n @for (column of columns$ | async; track columnsTrackBy($index, column)) {\r\n <!-- #region Column def -->\r\n <ng-container [cdkColumnDef]=\"column.name\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\r\n <ng-template #header [ngTemplateOutlet]=\"header\" let-headerText=\"headerText\" [ngTemplateOutletContext]=\"{headerText: column.header | func:context}\">\r\n <th mat-header-cell *cdkHeaderCellDef [mat-sort-header]=\"column.sortBy || column.name\" [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [disabled]=\"column.type == ColumnType.Checkbox || column.disabled\" [ngClass]=\"column.displayNgClass\" [arrowPosition]=\"column.arrowBefore?'before':'after'\">\r\n @if (column.type == ColumnType.Checkbox) {\r\n <mat-checkbox (change)=\"$event ? dataSource.toggleSelect($event, selectAllFilter) : null\" [disabled]=\"!dataSource.paginator?.length\" [checked]=\"dataSource.selectionModel.hasValue() && dataSource.isAllSelected()\" [indeterminate]=\"dataSource.selectionModel.hasValue() && !dataSource.isAllSelected()\"></mat-checkbox>\r\n } @if (column.type != ColumnType.Checkbox) {\r\n <span [matTooltip]=\"headerText\">{{headerText}}</span>\r\n }\r\n </th>\r\n </ng-template>\r\n <td mat-cell *cdkCellDef=\"let row; let rowIndex = dataIndex\" [matTooltip]=\"column.tooltip?column.tooltip(row, undefined, context):null\" [matTooltipClass]=\"column.tooltipClass??''\" [hidden]=\"column.hidden\" [ngClass]=\"getRowClasses(column, row)\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\">\r\n <ng-template #rowVal [ngTemplateOutlet]=\"rowVal\" let-rowValue [ngTemplateOutletContext]=\"{$implicit: column?.content && column?.content(row, undefined, context)}\">\r\n @switch (column.type) {\r\n <!-- #region Checkbox column -->\r\n @case (ColumnType.Checkbox) {\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? dataSource.selectionModel.toggle(row) : null\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [checked]=\"dataSource.selectionModel.isSelected(row)\"></mat-checkbox>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Enum column -->\r\n @case (ColumnType.Enum) {\r\n <span>\r\n @if (column.enumMetadata) {\r\n @if (column.multiple) {\r\n @for (item of rowValue; track item; let i = $index) {\r\n @if (i < 2) {\r\n <ng-template let-displayValue=\"displayValue\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ displayValue: column.enumMetadata[item].display }\"></ng-template>\r\n }\r\n @if (i === 1 && rowValue?.length > 2) {\r\n <small [matTooltip]=\"(rowValue | slice:2 | map:column.enumMetadata | map:'display') | join:'\\n'\" matTooltipClass=\"mat-tooltip-multiline\">...</small>\r\n }\r\n }\r\n <ng-template #template let-displayValue=\"displayValue\">\r\n <mat-chip-row disableRipple=\"true\" selectable=\"false\" [matTooltip]=\"displayValue\">\r\n <span>{{ displayValue }}</span>\r\n </mat-chip-row>\r\n </ng-template>\r\n } @else {\r\n @if (rowValue >= 0) {\r\n <span class=\"na\" [ngStyle]=\"{ color: ((column.enumMetadata[rowValue] || {}).textColor || 'inherit') }\" [innerHtml]=\"(column.enumMetadata[rowValue]||{}).display\"></span>\r\n }\r\n }\r\n } @else {\r\n @if (column.multiple) {\r\n @for (item of rowValue; track item; let i = $index; let last = $last) {\r\n <div>\r\n @if (i<2) {\r\n <small>\r\n <msa-enum-display [value]=\"item\" [enumType]=\"column.enumType\" [metadata]=\"column.enumMetadata\"></msa-enum-display>\r\n </small>\r\n } @if (i==1 && rowValue?.length > 2) {\r\n <small>, ...</small>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @if (rowValue >= 0) {\r\n <msa-enum-display [value]=\"rowValue\" [enumType]=\"column.enumType\" [metadata]=\"column.enumMetadata\"></msa-enum-display>\r\n }\r\n }\r\n }\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Toggle column -->\r\n @case (ColumnType.Toggle) {\r\n @if (!formArray) {\r\n <mat-slide-toggle [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);handleModelChange(column, row, undefined);\" (click)=\"$event.stopPropagation();\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" color=\"accent\"></mat-slide-toggle>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Date column -->\r\n @case (ColumnType.Date) {\r\n <span>{{rowValue | date:column.shortDate?'dd.MM.yyyy':'dd.MM.yyyy HH:mm:ss'}}</span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Text Input column -->\r\n @case (ColumnType.TextInput) {\r\n @if (!formArray) {\r\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\r\n @if (!formArray) {\r\n <input matInput type=\"{{column.inputType}}\" autocomplete=\"none\" name=\"{{column.name}}{{rowIndex}}\" [ngModel]=\"row | property:column.name\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [min]=\"column.inputMin?column.inputMin(row, undefined, context):null\" [max]=\"column.inputMax?column.inputMax(row, undefined, context):null\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);(column.change?column.change(row, undefined, context):patch(row, [column.name], $event, column.patchIncludes));\" [ngModelOptions]=\"{updateOn: 'blur'}\" (keydown.enter)=\"handleKeydownEnter($event)\" />\r\n }\r\n </mat-form-field>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region VD-Select column -->\r\n @case (ColumnType.Select) {\r\n @if (!formArray) {\r\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\r\n @if (!formArray) {\r\n <vd-select name=\"{{column.name}}{{rowIndex}}\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"$safeNavigationMigration(column?.enumFilter) | func:row:context\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" (change)=\"column.change?column.change(row, undefined, context):patch(row, [column.name], $event.value, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\r\n }\r\n </mat-form-field>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Action -->\r\n @case (ColumnType.Action) {\r\n @if (column.menu) {\r\n @if (menu?.matMenu && !row.locked && hasVisibleRowMenuItems(row, column)) {\r\n <div id=\"menu-{{row.id}}\" style=\"visibility: hidden; position: fixed\" #contextMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"menu.matMenu!\"></div>\r\n }\r\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\" #menu></vd-dynamic-menu>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Menu -->\r\n @case (ColumnType.Menu) {\r\n @if (column.menu) {\r\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\"></vd-dynamic-menu>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region icon -->\r\n @case (ColumnType.Icon) {\r\n <span layout=\"row\" layout-align=\"start center\">\r\n @if(column && column.icon){\r\n @if ( column.icon.matIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\">{{handleExpression($safeNavigationMigration(column.icon.matIcon)!, row)}}</mat-icon>\r\n }\r\n @if (column.icon.svgIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\" [svgIcon]=\"handleExpression($safeNavigationMigration(column.icon.svgIcon)!, row)!\"></mat-icon>\r\n }\r\n @if (column.icon.fontIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\" [fontIcon]=\"handleExpression($safeNavigationMigration(column.icon.fontIcon)!, row)!\"></mat-icon>\r\n }\r\n }\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region icon button -->\r\n @case (ColumnType.IconButton) {\r\n <a mat-icon-button (click)=\"$event.stopPropagation();column.iconButton?.event?column.iconButton.event(row, context):null\">\r\n <mat-icon fontSet=\"{{column.iconButton?.iconFontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.iconButton?.iconClass??'', row)\">{{handleExpression(column.iconButton?.icon??'radio_button_checked', row) || 'radio_button_checked'}}</mat-icon>\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Other column types -->\r\n @default {\r\n <span [innerHtml]=\"rowValue??''\"></span>\r\n }\r\n <!-- #endregion -->\r\n }\r\n <ng-template #recursiveContainer let-columnNameSegments=\"segments\" let-formGroup=\"formGroup\" let-parentFormGroup=\"parentFormGroup\">\r\n @if (formGroup) {\r\n <ng-container [formGroup]=\"formGroup\">\r\n <!-- If the columnNameSegments array is empty, we're at the leaf node -->\r\n @if (!columnNameSegments.length) {\r\n @switch (column.type) {\r\n <!-- #region Toggle column -->\r\n @case (ColumnType.Toggle) {\r\n <mat-slide-toggle [formControl]=\"formGroup\" (click)=\"$event.stopPropagation();\" (change)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):handleModelChange(column, parentFormGroup.value, parentFormGroup)\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" color=\"accent\"></mat-slide-toggle>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Text Input column -->\r\n @case (ColumnType.TextInput) {\r\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\r\n <input matInput [formControl]=\"formGroup\" type=\"{{column.inputType}}\" autocomplete=\"none\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" [min]=\"column.inputMin?column.inputMin(parentFormGroup.value, parentFormGroup, context):null\" [max]=\"column.inputMax?column.inputMax(parentFormGroup.value, parentFormGroup, context):null\" (keydown.enter)=\"handleKeydownEnter($event)\" />\r\n </mat-form-field>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region VD-Select column -->\r\n @case (ColumnType.Select) {\r\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\r\n <vd-select [formControl]=\"formGroup\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:parentFormGroup.value:context\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" (selectionChange)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):patch(parentFormGroup.value, [column.name], rowValue, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\r\n </mat-form-field>\r\n }\r\n <!-- #endregion -->\r\n }\r\n } @else {\r\n <!-- If not the last segment, create a nested form group -->\r\n <ng-container [formGroupName]=\"columnNameSegments[0]\">\r\n <!-- Recursive call to handle nested segments -->\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: columnNameSegments.slice(1), parentFormGroup:formGroup, formGroup: formGroup.get(columnNameSegments[0])}\"></ng-container>\r\n </ng-container>\r\n }\r\n </ng-container>\r\n }\r\n </ng-template>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n <!-- #endregion -->\r\n }\r\n <!-- #region Filter row -->\r\n @if (dataSource && filterable) {\r\n @for (column of columns$ | async; track column) {\r\n <ng-container cdkColumnDef=\"filter.{{column.filter || column.name}}\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\r\n <th mat-header-cell *cdkHeaderCellDef [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [ngClass]=\"column.displayNgClass\">\r\n <!-- #region Select filter -->\r\n @if(column.endpoint || column.enumType || column.options){\r\n <span filter-select [endpoint]=\"column.endpoint\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:{}:context\" [options]=\"column.options\" [text]=\"column.filterOptionText || 'name'\"></span>\r\n }\r\n <!-- #region Text filter -->\r\n @else if(column.type == ColumnType.Text || column.type == ColumnType.TextInput || column.type == ColumnType.Number) {\r\n <span filter-input [onlyNumber]=\"column.filterInputNumber??false\" [matTooltip]=\"column.filterTooltip ? column.filterTooltip(context):null\" [matTooltipClass]=\"column.filterTooltipClass??''\" [operator]=\"!useFilterOperator ? undefined : column.filterOperator\"></span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Date filter -->\r\n @else if (column.type == ColumnType.Date) {\r\n <span filter-date></span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Action filter (clear) -->\r\n @else if (column.type == ColumnType.Action) {\r\n <span filter-clear></span>\r\n }\r\n <!-- #endregion -->\r\n </th>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Details column -->\r\n <ng-container cdkColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let row; let index = index\" [attr.colspan]=\"(displayedColumns$ | async)?.length\">\r\n <div class=\"row-detail\" [@detailExpand]=\"row == expandedRow ? 'expanded' : 'collapsed'\" #detailsTemplate>\r\n @if (templateRef && row === expandedRow) {\r\n <ng-container *ngTemplateOutlet=\"templateRef; context:{row: row, index: index, context: context}\"></ng-container>\r\n }\r\n </div>\r\n </td>\r\n </ng-container>\r\n <!-- #endregion -->\r\n <!-- #region Filter header -->\r\n @if (filterable) {\r\n <tr mat-header-row *cdkHeaderRowDef=\"displayedFilterColumns$ | async\"></tr>\r\n }\r\n <!-- #endregion -->\r\n <tr mat-header-row *cdkHeaderRowDef=\"displayedColumns$ | async; sticky: stickyFilter\"></tr>\r\n <tr mat-row *cdkRowDef=\"let row; columns: displayedColumns$ | async; let index = dataIndex\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\" [class.expanded-row]=\"expandedRow === row\" (click)=\"handleRowClick(index, row)\" (contextmenu)=\"handleRowRightClick($event, row)\"></tr>\r\n <!-- #region Detrails row -->\r\n @if (detailsTemplate || templateRef) {\r\n <tr mat-row *cdkRowDef=\"let row; columns: ['expandedDetail']\" class=\"detail-row\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\"></tr>\r\n }\r\n <!-- #endregion -->\r\n </table>\r\n <!-- #region Modern No Results Message -->\r\n @if (dataSource?.filteredData?.length <= 0 && dataSource?.total <= 0) {\r\n <div class=\"no-results-overlay\">\r\n <mat-icon class=\"no-results-icon\">search_off</mat-icon>\r\n <div class=\"no-results-text mat-body-1\">\r\n <h3 i18n=\"@@noResultsFound\">No results found</h3>\r\n <p i18n=\"@@tryAdjustFilters\"> Try adjusting your filters or search criteria. </p>\r\n </div>\r\n </div>\r\n }\r\n <!-- #endregion -->\r\n</div>\r\n<!-- #endregion -->\r\n<!-- #region Debug value -->\r\n@if (debugValue) {\r\n <code>\r\n <pre>{{formValue | json}}</pre>\r\n</code>\r\n}\r\n<!-- #endregion -->\r\n<div class=\"table-footer\" layout=\"row\">\r\n <ng-content select=\"[table-footer]\"></ng-content>\r\n <span flex></span>\r\n @if (paginable) {\r\n <mat-paginator [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\r\n }\r\n</div>", styles: ["::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-form-field .mat-form-field-wrapper{width:100%}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip{height:24px;margin-top:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:9px;padding-right:9px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip:last-child{margin-bottom:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip *{font-size:.8rem}@media(max-width:389px){::ng-deep .mat-mdc-table [gt-xs],::ng-deep .mat-mdc-table .gt-xs{display:none}::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:599px){::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:959px){::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1279px){::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1919px){::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1979px){::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}.mat-table-container{width:100%;max-width:100%;overflow:auto}.mat-table-container .mat-mdc-header-cell,.mat-table-container .mat-mdc-footer-cell,.mat-table-container .mat-mdc-cell{min-width:80px;box-sizing:border-box}.mat-table-container .mat-mdc-header-row,.mat-table-container .mat-mdc-footer-row,.mat-table-container .mat-mdc-row{min-width:1920px}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-right{box-shadow:-3px 0 5px #0000001a}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-left{box-shadow:3px 0 5px #0000001a}\n"], dependencies: [{ kind: "ngmodule", type: CdkTableModule }, { kind: "directive", type: i2$3.CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }, { kind: "directive", type: i2$3.CdkCellDef, selector: "[cdkCellDef]" }, { kind: "directive", type: i2$3.CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { kind: "directive", type: i2$3.CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["cdkColumnDef", "sticky", "stickyEnd"] }, { kind: "directive", type: i2$3.CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i7.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i10.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i3.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i12.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i12.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$5.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$5.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$5.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$5.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$5.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$5.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i16.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type:
18457
19012
  //----------------------
18458
19013
  DataSourceFilterDirective, selector: "[dataSourceFilter]", inputs: ["dataSource", "dataSourceFilter"] }, { kind: "directive", type: DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "component", type: FilterDateComponent, selector: "mat-header-cell[filter-date], [mat-header-cell][filter-date], [filter-date]", inputs: ["field", "debounce", "placeholder"] }, { kind: "component", type: FilterInputComponent, selector: "mat-header-cell[filter-input], [mat-header-cell][filter-input], [filter-input]", inputs: ["field", "operator", "onlyNumber", "debounce", "placeholder"] }, { kind: "component", type: FilterSelectComponent, selector: "mat-header-cell[filter-select], [mat-header-cell][filter-select], [filter-select]", inputs: ["endpoint", "params", "projection", "sortBy", "sorted", "enumFilter", "enum", "enumMetadata", "key", "text", "prefix", "multiple", "options", "filteredOptions", "filterable", "field", "placeholder", "cache"] }, { kind: "component", type: FilterClearComponent, selector: "mat-header-cell[filter-clear], [mat-header-cell][filter-clear], [filter-clear]" }, { kind: "component", type: VdDynamicMenuComponent, selector: "vd-dynamic-menu", inputs: ["items", "data", "index", "context", "contextMenu"] }, { kind: "component", type: VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass"] }, { kind: "component", type: MsaEnumDisplayComponent, selector: "msa-enum-display", inputs: ["value", "enumType", "metadata", "showIcon", "entity", "context"] }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i1$2.JsonPipe, name: "json" }, { kind: "pipe", type: i1$2.SlicePipe, name: "slice" }, { kind: "pipe", type: i1$2.DatePipe, name: "date" }, { kind: "pipe", type:
18459
19014
  //----------------------
@@ -18507,7 +19062,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
18507
19062
  state('expanded', style({ height: AUTO_STYLE })),
18508
19063
  transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
18509
19064
  ]),
18510
- ], template: "@if (!static) {\r\n <div class=\"loading-progress\">\r\n @if (dataSource?.isLoading) {\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n }\r\n </div>\r\n}\r\n\r\n<!-- #region Data table -->\r\n<div class=\"mat-table-container scrollbar-secondary\" [ngClass]=\"{'mat-table-sticky': sticky}\" #scrollContainer>\r\n <table mat-table #table [dataSource]=\"dataSource\" [dataSourceFilter]=\"dataSourceFilter\" [ngClass]=\"{'table-fixed': !sticky && !detailsTemplate && !templateRef, 'table-stick': sticky}\" [trackBy]=\"trackBy\" matSort matSortDisableClear [matSortActive]=\"sortActive||'id'\" [matSortDirection]=\"sortDirection\" multiTemplateDataRows>\r\n @for (column of columns$ | async; track columnsTrackBy($index, column)) {\r\n <!-- #region Column def -->\r\n <ng-container [cdkColumnDef]=\"column.name\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\r\n <ng-template #header [ngTemplateOutlet]=\"header\" let-headerText=\"headerText\" [ngTemplateOutletContext]=\"{headerText: column.header | func:context}\">\r\n <th mat-header-cell *cdkHeaderCellDef [mat-sort-header]=\"column.sortBy || column.name\" [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [disabled]=\"column.type == ColumnType.Checkbox || column.disabled\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\" [arrowPosition]=\"column.arrowBefore?'before':'after'\">\r\n @if (column.type == ColumnType.Checkbox) {\r\n <mat-checkbox (change)=\"$event ? dataSource.toggleSelect($event, selectAllFilter) : null\" [disabled]=\"!dataSource.paginator?.length\" [checked]=\"dataSource.selectionModel.hasValue() && dataSource.isAllSelected()\" [indeterminate]=\"dataSource.selectionModel.hasValue() && !dataSource.isAllSelected()\"></mat-checkbox>\r\n } @if (column.type != ColumnType.Checkbox) {\r\n <span [matTooltip]=\"headerText\">{{headerText}}</span>\r\n }\r\n </th>\r\n </ng-template>\r\n <td mat-cell *cdkCellDef=\"let row; let rowIndex = dataIndex\" [matTooltip]=\"column.tooltip?column.tooltip(row, undefined, context):null\" [matTooltipClass]=\"column.tooltipClass??''\" [hidden]=\"column.hidden\" [ngClass]=\"getRowClasses(column, row)\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\">\r\n <ng-template #rowVal [ngTemplateOutlet]=\"rowVal\" let-rowValue [ngTemplateOutletContext]=\"{$implicit: column?.content && column?.content(row, undefined, context)}\">\r\n @switch (column.type) {\r\n <!-- #region Checkbox column -->\r\n @case (ColumnType.Checkbox) {\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? dataSource.selectionModel.toggle(row) : null\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [checked]=\"dataSource.selectionModel.isSelected(row)\"></mat-checkbox>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Enum column -->\r\n @case (ColumnType.Enum) {\r\n <span>\r\n @if (column.enumMetadata) {\r\n @if (column.multiple) {\r\n @for (item of rowValue; track item; let i = $index) {\r\n @if (i < 2) {\r\n <ng-template let-displayValue=\"displayValue\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ displayValue: column.enumMetadata[item].display }\"></ng-template>\r\n }\r\n @if (i === 1 && rowValue?.length > 2) {\r\n <small [matTooltip]=\"(rowValue | slice:2 | map:column.enumMetadata | map:'display') | join:'\\n'\" matTooltipClass=\"mat-tooltip-multiline\">...</small>\r\n }\r\n }\r\n <ng-template #template let-displayValue=\"displayValue\">\r\n <mat-chip-row disableRipple=\"true\" selectable=\"false\" [matTooltip]=\"displayValue\">\r\n <span>{{ displayValue }}</span>\r\n </mat-chip-row>\r\n </ng-template>\r\n } @else {\r\n @if (rowValue >= 0) {\r\n <span class=\"na\" [ngStyle]=\"{ color: ((column.enumMetadata[rowValue] || {}).textColor || 'inherit') }\" [innerHtml]=\"(column.enumMetadata[rowValue]||{}).display\"></span>\r\n }\r\n }\r\n } @else {\r\n @if (column.multiple) {\r\n @for (item of rowValue; track item; let i = $index; let last = $last) {\r\n <div>\r\n @if (i<2) {\r\n <small>\r\n <msa-enum-display [value]=\"item\" [enumType]=\"column.enumType\" [metadata]=\"column.enumMetadata\"></msa-enum-display>\r\n </small>\r\n } @if (i==1 && rowValue?.length > 2) {\r\n <small>, ...</small>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @if (rowValue >= 0) {\r\n <msa-enum-display [value]=\"rowValue\" [enumType]=\"column.enumType\" [metadata]=\"column.enumMetadata\"></msa-enum-display>\r\n }\r\n }\r\n }\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Toggle column -->\r\n @case (ColumnType.Toggle) {\r\n @if (!formArray) {\r\n <mat-slide-toggle [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);handleModelChange(column, row, undefined);\" (click)=\"$event.stopPropagation();\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" color=\"accent\"></mat-slide-toggle>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Date column -->\r\n @case (ColumnType.Date) {\r\n <span>{{rowValue | date:column.shortDate?'dd.MM.yyyy':'dd.MM.yyyy HH:mm:ss'}}</span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Text Input column -->\r\n @case (ColumnType.TextInput) {\r\n @if (!formArray) {\r\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\r\n @if (!formArray) {\r\n <input matInput type=\"{{column.inputType}}\" autocomplete=\"none\" name=\"{{column.name}}{{rowIndex}}\" [ngModel]=\"row | property:column.name\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [min]=\"column.inputMin?column.inputMin(row, undefined, context):null\" [max]=\"column.inputMax?column.inputMax(row, undefined, context):null\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);(column.change?column.change(row, undefined, context):patch(row, [column.name], $event, column.patchIncludes));\" [ngModelOptions]=\"{updateOn: 'blur'}\" (keydown.enter)=\"handleKeydownEnter($event)\" />\r\n }\r\n </mat-form-field>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region VD-Select column -->\r\n @case (ColumnType.Select) {\r\n @if (!formArray) {\r\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\r\n @if (!formArray) {\r\n <vd-select name=\"{{column.name}}{{rowIndex}}\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"$safeNavigationMigration(column?.enumFilter) | func:row:context\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" (change)=\"column.change?column.change(row, undefined, context):patch(row, [column.name], $event.value, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\r\n }\r\n </mat-form-field>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Action -->\r\n @case (ColumnType.Action) {\r\n @if (column.menu) {\r\n @if (menu?.matMenu && !row.locked && hasVisibleRowMenuItems(row, column)) {\r\n <div id=\"menu-{{row.id}}\" style=\"visibility: hidden; position: fixed\" #contextMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"menu.matMenu!\"></div>\r\n }\r\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\" #menu></vd-dynamic-menu>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Menu -->\r\n @case (ColumnType.Menu) {\r\n @if (column.menu) {\r\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\"></vd-dynamic-menu>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region icon -->\r\n @case (ColumnType.Icon) {\r\n <span layout=\"row\" layout-align=\"start center\">\r\n @if(column && column.icon){\r\n @if ( column.icon.matIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\">{{handleExpression($safeNavigationMigration(column.icon.matIcon)!, row)}}</mat-icon>\r\n }\r\n @if (column.icon.svgIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\" [svgIcon]=\"handleExpression($safeNavigationMigration(column.icon.svgIcon)!, row)!\"></mat-icon>\r\n }\r\n @if (column.icon.fontIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\" [fontIcon]=\"handleExpression($safeNavigationMigration(column.icon.fontIcon)!, row)!\"></mat-icon>\r\n }\r\n }\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region icon button -->\r\n @case (ColumnType.IconButton) {\r\n <a mat-icon-button (click)=\"$event.stopPropagation();column.iconButton?.event?column.iconButton.event(row, context):null\">\r\n <mat-icon fontSet=\"{{column.iconButton?.iconFontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.iconButton?.iconClass??'', row)\">{{handleExpression(column.iconButton?.icon??'radio_button_checked', row) || 'radio_button_checked'}}</mat-icon>\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Other column types -->\r\n @default {\r\n <span [innerHtml]=\"rowValue??''\"></span>\r\n }\r\n <!-- #endregion -->\r\n }\r\n <ng-template #recursiveContainer let-columnNameSegments=\"segments\" let-formGroup=\"formGroup\" let-parentFormGroup=\"parentFormGroup\">\r\n @if (formGroup) {\r\n <ng-container [formGroup]=\"formGroup\">\r\n <!-- If the columnNameSegments array is empty, we're at the leaf node -->\r\n @if (!columnNameSegments.length) {\r\n @switch (column.type) {\r\n <!-- #region Toggle column -->\r\n @case (ColumnType.Toggle) {\r\n <mat-slide-toggle [formControl]=\"formGroup\" (click)=\"$event.stopPropagation();\" (change)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):handleModelChange(column, parentFormGroup.value, parentFormGroup)\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" color=\"accent\"></mat-slide-toggle>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Text Input column -->\r\n @case (ColumnType.TextInput) {\r\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\r\n <input matInput [formControl]=\"formGroup\" type=\"{{column.inputType}}\" autocomplete=\"none\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" [min]=\"column.inputMin?column.inputMin(parentFormGroup.value, parentFormGroup, context):null\" [max]=\"column.inputMax?column.inputMax(parentFormGroup.value, parentFormGroup, context):null\" (keydown.enter)=\"handleKeydownEnter($event)\" />\r\n </mat-form-field>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region VD-Select column -->\r\n @case (ColumnType.Select) {\r\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\r\n <vd-select [formControl]=\"formGroup\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:parentFormGroup.value:context\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" (selectionChange)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):patch(parentFormGroup.value, [column.name], rowValue, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\r\n </mat-form-field>\r\n }\r\n <!-- #endregion -->\r\n }\r\n } @else {\r\n <!-- If not the last segment, create a nested form group -->\r\n <ng-container [formGroupName]=\"columnNameSegments[0]\">\r\n <!-- Recursive call to handle nested segments -->\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: columnNameSegments.slice(1), parentFormGroup:formGroup, formGroup: formGroup.get(columnNameSegments[0])}\"></ng-container>\r\n </ng-container>\r\n }\r\n </ng-container>\r\n }\r\n </ng-template>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n <!-- #endregion -->\r\n }\r\n\r\n <!-- #region Filter row -->\r\n @if (dataSource && filterable) {\r\n @for (column of columns$ | async; track column) {\r\n <ng-container cdkColumnDef=\"filter.{{column.filter || column.name}}\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\r\n <th mat-header-cell *cdkHeaderCellDef [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [ngClass]=\"{'gt-xs': column.display == Grid.Xs, 'gt-sm': column.display == Grid.Sm, 'gt-md': column.display == Grid.Md, 'gt-lg': column.display == Grid.Lg, 'gt-xl': column.display == Grid.Xl, 'gt-xxl': column.display == Grid.Xxl, 'hidden': column.display == Grid.None}\">\r\n <!-- #region Select filter -->\r\n @if(column.endpoint || column.enumType || column.options){\r\n <span filter-select [endpoint]=\"column.endpoint\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:{}:context\" [options]=\"column.options\" [text]=\"column.filterOptionText || 'name'\"></span>\r\n }\r\n <!-- #region Text filter -->\r\n @else if(column.type == ColumnType.Text || column.type == ColumnType.TextInput || column.type == ColumnType.Number) {\r\n <span filter-input [onlyNumber]=\"column.filterInputNumber??false\" [matTooltip]=\"column.filterTooltip ? column.filterTooltip(context):null\" [matTooltipClass]=\"column.filterTooltipClass??''\" [operator]=\"!useFilterOperator ? undefined : column.filterOperator\"></span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Date filter -->\r\n @else if (column.type == ColumnType.Date) {\r\n <span filter-date></span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Action filter (clear) -->\r\n @else if (column.type == ColumnType.Action) {\r\n <span filter-clear></span>\r\n }\r\n <!-- #endregion -->\r\n </th>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n\r\n <!-- #region Details column -->\r\n <ng-container cdkColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let row; let index = index\" [attr.colspan]=\"(displayedColumns$ | async)?.length\">\r\n <div class=\"row-detail\" [@detailExpand]=\"row == expandedRow ? 'expanded' : 'collapsed'\" #detailsTemplate>\r\n @if (templateRef && row === expandedRow) {\r\n <ng-container *ngTemplateOutlet=\"templateRef; context:{row: row, index: index, context: context}\"></ng-container>\r\n }\r\n </div>\r\n </td>\r\n </ng-container>\r\n <!-- #endregion -->\r\n\r\n <!-- #region Filter header -->\r\n @if (filterable) {\r\n <tr mat-header-row *cdkHeaderRowDef=\"displayedFilterColumns$ | async\"></tr>\r\n }\r\n <!-- #endregion -->\r\n\r\n <tr mat-header-row *cdkHeaderRowDef=\"displayedColumns$ | async; sticky: stickyFilter\"></tr>\r\n <tr mat-row *cdkRowDef=\"let row; columns: displayedColumns$ | async; let index = dataIndex\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\" [class.expanded-row]=\"expandedRow === row\" (click)=\"handleRowClick(index, row)\" (contextmenu)=\"handleRowRightClick($event, row)\"></tr>\r\n\r\n <!-- #region Detrails row -->\r\n @if (detailsTemplate || templateRef) {\r\n <tr mat-row *cdkRowDef=\"let row; columns: ['expandedDetail']\" class=\"detail-row\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\"></tr>\r\n }\r\n <!-- #endregion -->\r\n </table>\r\n\r\n <!-- #region Modern No Results Message -->\r\n @if (dataSource?.filteredData?.length <= 0 && dataSource?.total <= 0) {\r\n <div class=\"no-results-overlay\">\r\n <mat-icon class=\"no-results-icon\">search_off</mat-icon>\r\n <div class=\"no-results-text mat-body-1\">\r\n <h3 i18n=\"@@noResultsFound\">No results found</h3>\r\n <p i18n=\"@@tryAdjustFilters\">\r\n Try adjusting your filters or search criteria.\r\n </p>\r\n </div>\r\n </div>\r\n }\r\n <!-- #endregion -->\r\n</div>\r\n<!-- #endregion -->\r\n\r\n<!-- #region Debug value -->\r\n@if (debugValue) {\r\n <code>\r\n <pre>{{formValue | json}}</pre>\r\n</code>\r\n}\r\n<!-- #endregion -->\r\n\r\n<div class=\"table-footer\" layout=\"row\">\r\n <ng-content select=\"[table-footer]\"></ng-content>\r\n <span flex></span>\r\n @if (paginable) {\r\n <mat-paginator [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\r\n }\r\n</div>", styles: ["::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-form-field .mat-form-field-wrapper{width:100%}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip{height:24px;margin-top:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:9px;padding-right:9px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip:last-child{margin-bottom:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip *{font-size:.8rem}@media(max-width:389px){::ng-deep .mat-mdc-table [gt-xs],::ng-deep .mat-mdc-table .gt-xs{display:none}::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:599px){::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:959px){::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1279px){::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1919px){::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1979px){::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}.mat-table-container{width:100%;max-width:100%;overflow:auto}.mat-table-container .mat-mdc-header-cell,.mat-table-container .mat-mdc-footer-cell,.mat-table-container .mat-mdc-cell{min-width:80px;box-sizing:border-box}.mat-table-container .mat-mdc-header-row,.mat-table-container .mat-mdc-footer-row,.mat-table-container .mat-mdc-row{min-width:1920px}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-right{box-shadow:-3px 0 5px #0000001a}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-left{box-shadow:3px 0 5px #0000001a}\n"] }]
19065
+ ], template: "@if (!static) {\r\n <div class=\"loading-progress\">\r\n @if (dataSource?.isLoading) {\r\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\r\n }\r\n </div>\r\n}\r\n<!-- #region Data table -->\r\n<div class=\"mat-table-container scrollbar-secondary\" [ngClass]=\"{'mat-table-sticky': sticky}\" #scrollContainer>\r\n <table mat-table #table [dataSource]=\"dataSource\" [dataSourceFilter]=\"dataSourceFilter\" [ngClass]=\"{'table-fixed': !sticky && !detailsTemplate && !templateRef, 'table-stick': sticky}\" [trackBy]=\"trackBy\" matSort matSortDisableClear [matSortActive]=\"sortActive||'id'\" [matSortDirection]=\"sortDirection\" multiTemplateDataRows>\r\n @for (column of columns$ | async; track columnsTrackBy($index, column)) {\r\n <!-- #region Column def -->\r\n <ng-container [cdkColumnDef]=\"column.name\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\r\n <ng-template #header [ngTemplateOutlet]=\"header\" let-headerText=\"headerText\" [ngTemplateOutletContext]=\"{headerText: column.header | func:context}\">\r\n <th mat-header-cell *cdkHeaderCellDef [mat-sort-header]=\"column.sortBy || column.name\" [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [disabled]=\"column.type == ColumnType.Checkbox || column.disabled\" [ngClass]=\"column.displayNgClass\" [arrowPosition]=\"column.arrowBefore?'before':'after'\">\r\n @if (column.type == ColumnType.Checkbox) {\r\n <mat-checkbox (change)=\"$event ? dataSource.toggleSelect($event, selectAllFilter) : null\" [disabled]=\"!dataSource.paginator?.length\" [checked]=\"dataSource.selectionModel.hasValue() && dataSource.isAllSelected()\" [indeterminate]=\"dataSource.selectionModel.hasValue() && !dataSource.isAllSelected()\"></mat-checkbox>\r\n } @if (column.type != ColumnType.Checkbox) {\r\n <span [matTooltip]=\"headerText\">{{headerText}}</span>\r\n }\r\n </th>\r\n </ng-template>\r\n <td mat-cell *cdkCellDef=\"let row; let rowIndex = dataIndex\" [matTooltip]=\"column.tooltip?column.tooltip(row, undefined, context):null\" [matTooltipClass]=\"column.tooltipClass??''\" [hidden]=\"column.hidden\" [ngClass]=\"getRowClasses(column, row)\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\">\r\n <ng-template #rowVal [ngTemplateOutlet]=\"rowVal\" let-rowValue [ngTemplateOutletContext]=\"{$implicit: column?.content && column?.content(row, undefined, context)}\">\r\n @switch (column.type) {\r\n <!-- #region Checkbox column -->\r\n @case (ColumnType.Checkbox) {\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? dataSource.selectionModel.toggle(row) : null\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [checked]=\"dataSource.selectionModel.isSelected(row)\"></mat-checkbox>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Enum column -->\r\n @case (ColumnType.Enum) {\r\n <span>\r\n @if (column.enumMetadata) {\r\n @if (column.multiple) {\r\n @for (item of rowValue; track item; let i = $index) {\r\n @if (i < 2) {\r\n <ng-template let-displayValue=\"displayValue\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ displayValue: column.enumMetadata[item].display }\"></ng-template>\r\n }\r\n @if (i === 1 && rowValue?.length > 2) {\r\n <small [matTooltip]=\"(rowValue | slice:2 | map:column.enumMetadata | map:'display') | join:'\\n'\" matTooltipClass=\"mat-tooltip-multiline\">...</small>\r\n }\r\n }\r\n <ng-template #template let-displayValue=\"displayValue\">\r\n <mat-chip-row disableRipple=\"true\" selectable=\"false\" [matTooltip]=\"displayValue\">\r\n <span>{{ displayValue }}</span>\r\n </mat-chip-row>\r\n </ng-template>\r\n } @else {\r\n @if (rowValue >= 0) {\r\n <span class=\"na\" [ngStyle]=\"{ color: ((column.enumMetadata[rowValue] || {}).textColor || 'inherit') }\" [innerHtml]=\"(column.enumMetadata[rowValue]||{}).display\"></span>\r\n }\r\n }\r\n } @else {\r\n @if (column.multiple) {\r\n @for (item of rowValue; track item; let i = $index; let last = $last) {\r\n <div>\r\n @if (i<2) {\r\n <small>\r\n <msa-enum-display [value]=\"item\" [enumType]=\"column.enumType\" [metadata]=\"column.enumMetadata\"></msa-enum-display>\r\n </small>\r\n } @if (i==1 && rowValue?.length > 2) {\r\n <small>, ...</small>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @if (rowValue >= 0) {\r\n <msa-enum-display [value]=\"rowValue\" [enumType]=\"column.enumType\" [metadata]=\"column.enumMetadata\"></msa-enum-display>\r\n }\r\n }\r\n }\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Toggle column -->\r\n @case (ColumnType.Toggle) {\r\n @if (!formArray) {\r\n <mat-slide-toggle [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);handleModelChange(column, row, undefined);\" (click)=\"$event.stopPropagation();\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" color=\"accent\"></mat-slide-toggle>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Date column -->\r\n @case (ColumnType.Date) {\r\n <span>{{rowValue | date:column.shortDate?'dd.MM.yyyy':'dd.MM.yyyy HH:mm:ss'}}</span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Text Input column -->\r\n @case (ColumnType.TextInput) {\r\n @if (!formArray) {\r\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\r\n @if (!formArray) {\r\n <input matInput type=\"{{column.inputType}}\" autocomplete=\"none\" name=\"{{column.name}}{{rowIndex}}\" [ngModel]=\"row | property:column.name\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" [min]=\"column.inputMin?column.inputMin(row, undefined, context):null\" [max]=\"column.inputMax?column.inputMax(row, undefined, context):null\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);(column.change?column.change(row, undefined, context):patch(row, [column.name], $event, column.patchIncludes));\" [ngModelOptions]=\"{updateOn: 'blur'}\" (keydown.enter)=\"handleKeydownEnter($event)\" />\r\n }\r\n </mat-form-field>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region VD-Select column -->\r\n @case (ColumnType.Select) {\r\n @if (!formArray) {\r\n <mat-form-field appearance=\"outline\" layout=\"column\" layout-align=\"center start\" subscriptSizing=\"dynamic\" dense-3 (click)=\"$event.stopPropagation();\">\r\n @if (!formArray) {\r\n <vd-select name=\"{{column.name}}{{rowIndex}}\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"$safeNavigationMigration(column?.enumFilter) | func:row:context\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [ngModel]=\"row | property:column.name\" (ngModelChange)=\"setNestedProperty(row, column.name, $event);\" [disabled]=\"readonly || (column.disabled || (column.disable && column.disable(row, undefined, context)))\" (change)=\"column.change?column.change(row, undefined, context):patch(row, [column.name], $event.value, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\r\n }\r\n </mat-form-field>\r\n } @if (formArray) {\r\n <ng-container [formGroup]=\"$any(formArray.controls)[rowIndex] | formGroup\">\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: column.name.split('.'), formGroup: formArray.controls[rowIndex]}\"></ng-container>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Action -->\r\n @case (ColumnType.Action) {\r\n @if (column.menu) {\r\n @if (menu?.matMenu && !row.locked && hasVisibleRowMenuItems(row, column)) {\r\n <div id=\"menu-{{row.id}}\" style=\"visibility: hidden; position: fixed\" #contextMenuTrigger=\"matMenuTrigger\" [matMenuTriggerFor]=\"menu.matMenu!\"></div>\r\n }\r\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\" #menu></vd-dynamic-menu>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Menu -->\r\n @case (ColumnType.Menu) {\r\n @if (column.menu) {\r\n <vd-dynamic-menu [items]=\"[column.menu]\" [data]=\"row\" [context]=\"context\"></vd-dynamic-menu>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region icon -->\r\n @case (ColumnType.Icon) {\r\n <span layout=\"row\" layout-align=\"start center\">\r\n @if(column && column.icon){\r\n @if ( column.icon.matIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\">{{handleExpression($safeNavigationMigration(column.icon.matIcon)!, row)}}</mat-icon>\r\n }\r\n @if (column.icon.svgIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\" [svgIcon]=\"handleExpression($safeNavigationMigration(column.icon.svgIcon)!, row)!\"></mat-icon>\r\n }\r\n @if (column.icon.fontIcon) {\r\n <mat-icon fontSet=\"{{column.icon.fontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.icon.cssClass??'', row)\" [fontIcon]=\"handleExpression($safeNavigationMigration(column.icon.fontIcon)!, row)!\"></mat-icon>\r\n }\r\n }\r\n </span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region icon button -->\r\n @case (ColumnType.IconButton) {\r\n <a mat-icon-button (click)=\"$event.stopPropagation();column.iconButton?.event?column.iconButton.event(row, context):null\">\r\n <mat-icon fontSet=\"{{column.iconButton?.iconFontSet || 'material-symbols-outlined'}}\" [class]=\"handleExpression(column.iconButton?.iconClass??'', row)\">{{handleExpression(column.iconButton?.icon??'radio_button_checked', row) || 'radio_button_checked'}}</mat-icon>\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Other column types -->\r\n @default {\r\n <span [innerHtml]=\"rowValue??''\"></span>\r\n }\r\n <!-- #endregion -->\r\n }\r\n <ng-template #recursiveContainer let-columnNameSegments=\"segments\" let-formGroup=\"formGroup\" let-parentFormGroup=\"parentFormGroup\">\r\n @if (formGroup) {\r\n <ng-container [formGroup]=\"formGroup\">\r\n <!-- If the columnNameSegments array is empty, we're at the leaf node -->\r\n @if (!columnNameSegments.length) {\r\n @switch (column.type) {\r\n <!-- #region Toggle column -->\r\n @case (ColumnType.Toggle) {\r\n <mat-slide-toggle [formControl]=\"formGroup\" (click)=\"$event.stopPropagation();\" (change)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):handleModelChange(column, parentFormGroup.value, parentFormGroup)\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" color=\"accent\"></mat-slide-toggle>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Text Input column -->\r\n @case (ColumnType.TextInput) {\r\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\r\n <input matInput [formControl]=\"formGroup\" type=\"{{column.inputType}}\" autocomplete=\"none\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" [min]=\"column.inputMin?column.inputMin(parentFormGroup.value, parentFormGroup, context):null\" [max]=\"column.inputMax?column.inputMax(parentFormGroup.value, parentFormGroup, context):null\" (keydown.enter)=\"handleKeydownEnter($event)\" />\r\n </mat-form-field>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region VD-Select column -->\r\n @case (ColumnType.Select) {\r\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\" dense-3 layout=\"column\" layout-align=\"center start\" (click)=\"$event.stopPropagation();\">\r\n <vd-select [formControl]=\"formGroup\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:parentFormGroup.value:context\" [options]=\"column.options\" [defaultOption]=\"column.defaultOption??true\" [disableControl]=\"readonly || (column.disabled || (column.disable && column.disable(parentFormGroup.value, parentFormGroup, context)))\" (selectionChange)=\"column.change?column.change(parentFormGroup.value, parentFormGroup, context):patch(parentFormGroup.value, [column.name], rowValue, column.patchIncludes)\" (keydown.enter)=\"handleKeydownEnter($event)\"></vd-select>\r\n </mat-form-field>\r\n }\r\n <!-- #endregion -->\r\n }\r\n } @else {\r\n <!-- If not the last segment, create a nested form group -->\r\n <ng-container [formGroupName]=\"columnNameSegments[0]\">\r\n <!-- Recursive call to handle nested segments -->\r\n <ng-container [ngTemplateOutlet]=\"recursiveContainer\" [ngTemplateOutletContext]=\"{segments: columnNameSegments.slice(1), parentFormGroup:formGroup, formGroup: formGroup.get(columnNameSegments[0])}\"></ng-container>\r\n </ng-container>\r\n }\r\n </ng-container>\r\n }\r\n </ng-template>\r\n </ng-template>\r\n </td>\r\n </ng-container>\r\n <!-- #endregion -->\r\n }\r\n <!-- #region Filter row -->\r\n @if (dataSource && filterable) {\r\n @for (column of columns$ | async; track column) {\r\n <ng-container cdkColumnDef=\"filter.{{column.filter || column.name}}\" [sticky]=\"column.sticky\" [stickyEnd]=\"column.stickyEnd\">\r\n <th mat-header-cell *cdkHeaderCellDef [hidden]=\"column.hidden\" [ngStyle]=\"{maxWidth:column.maxWidth?(column.maxWidth+(column.maxWidthUnit || 'px')):null,minWidth:column.minWidth?(column.minWidth+(column.minWidthUnit || 'px')):null,width:column.width?(column.width+(column.widthUnit || 'px')):null}\" [ngClass]=\"column.displayNgClass\">\r\n <!-- #region Select filter -->\r\n @if(column.endpoint || column.enumType || column.options){\r\n <span filter-select [endpoint]=\"column.endpoint\" [enum]=\"column.enumType\" [enumMetadata]=\"column.enumMetadata\" [enumFilter]=\"column.enumFilter | func:{}:context\" [options]=\"column.options\" [text]=\"column.filterOptionText || 'name'\"></span>\r\n }\r\n <!-- #region Text filter -->\r\n @else if(column.type == ColumnType.Text || column.type == ColumnType.TextInput || column.type == ColumnType.Number) {\r\n <span filter-input [onlyNumber]=\"column.filterInputNumber??false\" [matTooltip]=\"column.filterTooltip ? column.filterTooltip(context):null\" [matTooltipClass]=\"column.filterTooltipClass??''\" [operator]=\"!useFilterOperator ? undefined : column.filterOperator\"></span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Date filter -->\r\n @else if (column.type == ColumnType.Date) {\r\n <span filter-date></span>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Action filter (clear) -->\r\n @else if (column.type == ColumnType.Action) {\r\n <span filter-clear></span>\r\n }\r\n <!-- #endregion -->\r\n </th>\r\n </ng-container>\r\n }\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Details column -->\r\n <ng-container cdkColumnDef=\"expandedDetail\">\r\n <td mat-cell *matCellDef=\"let row; let index = index\" [attr.colspan]=\"(displayedColumns$ | async)?.length\">\r\n <div class=\"row-detail\" [@detailExpand]=\"row == expandedRow ? 'expanded' : 'collapsed'\" #detailsTemplate>\r\n @if (templateRef && row === expandedRow) {\r\n <ng-container *ngTemplateOutlet=\"templateRef; context:{row: row, index: index, context: context}\"></ng-container>\r\n }\r\n </div>\r\n </td>\r\n </ng-container>\r\n <!-- #endregion -->\r\n <!-- #region Filter header -->\r\n @if (filterable) {\r\n <tr mat-header-row *cdkHeaderRowDef=\"displayedFilterColumns$ | async\"></tr>\r\n }\r\n <!-- #endregion -->\r\n <tr mat-header-row *cdkHeaderRowDef=\"displayedColumns$ | async; sticky: stickyFilter\"></tr>\r\n <tr mat-row *cdkRowDef=\"let row; columns: displayedColumns$ | async; let index = dataIndex\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\" [class.expanded-row]=\"expandedRow === row\" (click)=\"handleRowClick(index, row)\" (contextmenu)=\"handleRowRightClick($event, row)\"></tr>\r\n <!-- #region Detrails row -->\r\n @if (detailsTemplate || templateRef) {\r\n <tr mat-row *cdkRowDef=\"let row; columns: ['expandedDetail']\" class=\"detail-row\" [ngClass]=\"rowNgClass?rowNgClass(row, context):null\"></tr>\r\n }\r\n <!-- #endregion -->\r\n </table>\r\n <!-- #region Modern No Results Message -->\r\n @if (dataSource?.filteredData?.length <= 0 && dataSource?.total <= 0) {\r\n <div class=\"no-results-overlay\">\r\n <mat-icon class=\"no-results-icon\">search_off</mat-icon>\r\n <div class=\"no-results-text mat-body-1\">\r\n <h3 i18n=\"@@noResultsFound\">No results found</h3>\r\n <p i18n=\"@@tryAdjustFilters\"> Try adjusting your filters or search criteria. </p>\r\n </div>\r\n </div>\r\n }\r\n <!-- #endregion -->\r\n</div>\r\n<!-- #endregion -->\r\n<!-- #region Debug value -->\r\n@if (debugValue) {\r\n <code>\r\n <pre>{{formValue | json}}</pre>\r\n</code>\r\n}\r\n<!-- #endregion -->\r\n<div class=\"table-footer\" layout=\"row\">\r\n <ng-content select=\"[table-footer]\"></ng-content>\r\n <span flex></span>\r\n @if (paginable) {\r\n <mat-paginator [pageSize]=\"pageSize\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\"></mat-paginator>\r\n }\r\n</div>", styles: ["::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-form-field .mat-form-field-wrapper{width:100%}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip{height:24px;margin-top:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:9px;padding-right:9px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip:last-child{margin-bottom:2px}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}::ng-deep .mat-mdc-table .mat-mdc-row .mat-mdc-cell .mat-mdc-chip *{font-size:.8rem}@media(max-width:389px){::ng-deep .mat-mdc-table [gt-xs],::ng-deep .mat-mdc-table .gt-xs{display:none}::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:599px){::ng-deep .mat-mdc-table [gt-sm],::ng-deep .mat-mdc-table .gt-sm{display:none}::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:959px){::ng-deep .mat-mdc-table [gt-md],::ng-deep .mat-mdc-table .gt-md{display:none}::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1279px){::ng-deep .mat-mdc-table [gt-lg],::ng-deep .mat-mdc-table .gt-lg{display:none}::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1919px){::ng-deep .mat-mdc-table [gt-xl],::ng-deep .mat-mdc-table .gt-xl{display:none}::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}@media(max-width:1979px){::ng-deep .mat-mdc-table [gt-xxl],::ng-deep .mat-mdc-table .gt-xxl{display:none}}.mat-table-container{width:100%;max-width:100%;overflow:auto}.mat-table-container .mat-mdc-header-cell,.mat-table-container .mat-mdc-footer-cell,.mat-table-container .mat-mdc-cell{min-width:80px;box-sizing:border-box}.mat-table-container .mat-mdc-header-row,.mat-table-container .mat-mdc-footer-row,.mat-table-container .mat-mdc-row{min-width:1920px}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-right{box-shadow:-3px 0 5px #0000001a}.mat-table-container.mat-table-sticky .mat-mdc-table-sticky-border-elem-left{box-shadow:3px 0 5px #0000001a}\n"] }]
18511
19066
  }], ctorParameters: () => [{ type: DynamicBuilder }, { type: i0.ChangeDetectorRef }], propDecorators: { table: [{
18512
19067
  type: ViewChild,
18513
19068
  args: ['table']
@@ -18664,7 +19219,7 @@ __decorate([
18664
19219
  defaultOption: false
18665
19220
  }),
18666
19221
  Display($localize `:@@display:Display`),
18667
- __metadata("design:type", Number)
19222
+ __metadata("design:type", Object)
18668
19223
  ], TableColumnConfig.prototype, "display", void 0);
18669
19224
  __decorate([
18670
19225
  Column({
@@ -18835,7 +19390,9 @@ class VdDynamicTableConfigDialogComponent extends BaseComponent {
18835
19390
  this.configForm.controls["sticky"].valueChanges.subscribe(value => genericList.dynamicTable.sticky = value);
18836
19391
  }
18837
19392
  /* Filter columns that are configurable from the provided dynamic table configuration */
18838
- this.columns = genericList?.dynamicTable?.columns?.filter((x) => x.configurable);
19393
+ this.columns = genericList?.dynamicTable?.columns
19394
+ ?.filter((x) => x.configurable)
19395
+ ?.filter((x) => x.columnSets?.some(cs => genericList?.dynamicTable?.columnSets?.includes(cs)));
18839
19396
  }
18840
19397
  /**
18841
19398
  * Saves the current column configuration and closes the dialog.
@@ -19151,6 +19708,15 @@ class GenericListComponent extends BaseComponent {
19151
19708
  * @type {string}
19152
19709
  */
19153
19710
  configsKey = '';
19711
+ /**
19712
+ * @property configsKeySuffix
19713
+ * @description Optional suffix appended to the persisted table configuration key.
19714
+ * Subclasses can override this getter to isolate configurations.
19715
+ * @type {string | undefined}
19716
+ */
19717
+ get configsKeySuffix() {
19718
+ return undefined;
19719
+ }
19154
19720
  /**
19155
19721
  * Constructor for the table component.
19156
19722
  * @param service The service used for managing table data.
@@ -19170,9 +19736,16 @@ class GenericListComponent extends BaseComponent {
19170
19736
  ngOnInit() {
19171
19737
  super.ngOnInit();
19172
19738
  /* Assemble the config key */
19173
- this.configsKey = [this.projectName, 'list-config.v2', window.btoa(this.currentBaseRoute ?? ''), this.menu?.title].join('.');
19739
+ this.configsKey = [
19740
+ this.projectName,
19741
+ 'list-config.v2',
19742
+ window.btoa(this.currentBaseRoute ?? ''),
19743
+ this.menu?.title,
19744
+ this.configsKeySuffix
19745
+ ].filter(x => x !== null && x !== undefined && x !== '').join('.');
19174
19746
  /* Load list configs */
19175
19747
  this.tableConfig = AppStorage.getObjectEncoded(this.configsKey, new TableConfig());
19748
+ /* Set table width from config */
19176
19749
  this.sticky = this.tableConfig.sticky ?? false;
19177
19750
  /* Set back button from route params */
19178
19751
  this.backButton = this.route?.snapshot?.paramMap?.get('backButton') == 'true';
@@ -19530,17 +20103,18 @@ class GenericListComponent extends BaseComponent {
19530
20103
  });
19531
20104
  }
19532
20105
  /**
19533
- * Downloads a document
19534
- * @param entity
20106
+ * Downloads a file for the specified entity and path.
20107
+ * @param entity The entity to download
20108
+ * @param path The path to download
19535
20109
  */
19536
20110
  download(entity, path = 'download') {
19537
- this.service.download(`${path}/${entity.id}`).subscribe(x => {
20111
+ this.service.download(`${path}/${entity.id}`, {}, { 'Show-Message': 'Yes' }).subscribe(x => {
19538
20112
  saveAs(new Blob([x.data], {}), x.filename);
19539
20113
  });
19540
20114
  }
19541
20115
  /**
19542
- * Duplicates a record
19543
- * @param entity
20116
+ * Duplicates an entity by calling the duplicate method of the service and then reloads the list.
20117
+ * @param entity The entity to duplicate
19544
20118
  */
19545
20119
  duplicate(entity) {
19546
20120
  this.service.duplicate(entity.id).subscribe(_ => this.loadList());
@@ -19577,7 +20151,7 @@ class GenericListComponent extends BaseComponent {
19577
20151
  endpoint: this.service.endpoint,
19578
20152
  formData: {
19579
20153
  fileName: this.exportFileName ?? this.subtitle,
19580
- projection: this.projection,
20154
+ projection: parseProjectionArray(this.projection),
19581
20155
  page: this.dataSource?.pageIndex + 1,
19582
20156
  pageSize: this.paginator?.pageSize,
19583
20157
  sortBy: this.sort?.active,
@@ -21904,7 +22478,7 @@ class VdChipsComponent extends AbstractMatFormField {
21904
22478
  get dynamicTable() { return this._dynamicTable; }
21905
22479
  set dynamicTable(dynamicTable) {
21906
22480
  this._dynamicTable = dynamicTable;
21907
- if (this._dynamicTable) {
22481
+ if (this._dynamicTable && this.dataSource) {
21908
22482
  this.dataSource.sort = this._dynamicTable.matSort;
21909
22483
  }
21910
22484
  }
@@ -21945,6 +22519,10 @@ class VdChipsComponent extends AbstractMatFormField {
21945
22519
  * Subscription for the data source observable.
21946
22520
  */
21947
22521
  dataSourceSubscription;
22522
+ /**
22523
+ * Subscription for the data source loaded event.
22524
+ */
22525
+ onDataLoadedSubscription;
21948
22526
  /**
21949
22527
  * Form control for the autocomplete chip list.
21950
22528
  */
@@ -22026,10 +22604,7 @@ class VdChipsComponent extends AbstractMatFormField {
22026
22604
  * Indicates whether the component is disabled.
22027
22605
  */
22028
22606
  get disabled() {
22029
- if (this._readonly) {
22030
- return true;
22031
- }
22032
- return super.disabled;
22607
+ return super.disabled || (this.readonly && !this._value);
22033
22608
  }
22034
22609
  /**
22035
22610
  * Indicates if pagination is enabled.
@@ -22262,19 +22837,55 @@ class VdChipsComponent extends AbstractMatFormField {
22262
22837
  connect() {
22263
22838
  /* Set the dropdown to open */
22264
22839
  this.opened = true;
22265
- /* Configure field filters for the data source */
22266
- this.dataSource.fieldFilters = this.getQueryParams();
22267
- /* Manually connect the data source for 'mat-option' triggers */
22268
- if (!this.classType && !this.dataSource?.isConnected) {
22269
- this.dataSourceSubscription?.unsubscribe();
22270
- this.dataSourceSubscription = this.dataSource?.connect().subscribe();
22840
+ this.loading = true;
22841
+ /* Wait a bit before preparing query params and loading data */
22842
+ setTimeout(() => {
22843
+ /* Configure field filters for the data source */
22844
+ this.dataSource.fieldFilters = this.getQueryParams();
22845
+ /* Force opening panel when data is actually loaded */
22846
+ if (!this.onDataLoadedSubscription && this.dataSource) {
22847
+ this.onDataLoadedSubscription = this.dataSource.onDataLoaded
22848
+ .pipe(skip(1))
22849
+ .subscribe(() => {
22850
+ this.loading = false;
22851
+ queueMicrotask(() => this.autocompleteTrigger?.openPanel());
22852
+ this.changeDetectorRef.detectChanges();
22853
+ });
22854
+ }
22855
+ /* Manually connect the data source for 'mat-option' triggers */
22856
+ if (!this.classType && !this.dataSource?.isConnected) {
22857
+ this.dataSourceSubscription?.unsubscribe();
22858
+ this.dataSourceSubscription = this.dataSource?.connect().subscribe(() => {
22859
+ this.loading = false;
22860
+ this.changeDetectorRef.detectChanges();
22861
+ });
22862
+ }
22863
+ /* Reload the data source if it is already connected */
22864
+ else if (this.dataSource?.isConnected) {
22865
+ this.dataSource?.reload();
22866
+ }
22867
+ /* Trigger change detection */
22868
+ this.changeDetectorRef.detectChanges();
22869
+ }, 100);
22870
+ /* Open panel after the current microtask to let binding updates settle */
22871
+ queueMicrotask(() => this.autocompleteTrigger?.openPanel());
22872
+ }
22873
+ /**
22874
+ * @description Reopens the autocomplete panel when the input is clicked while already focused.
22875
+ * @returns {void}
22876
+ */
22877
+ reopenPanel() {
22878
+ /* Prevent reopening when the control is not interactive */
22879
+ if (this.readonly || this.disabled) {
22880
+ return;
22271
22881
  }
22272
- /* Reload the data source if it is already connected */
22273
- else if (this.dataSource?.isConnected) {
22274
- this.dataSource?.reload();
22882
+ /* Initialize and connect once when the panel has not been opened yet */
22883
+ if (!this.opened || !this.dataSource?.isConnected) {
22884
+ this.connect();
22885
+ return;
22275
22886
  }
22276
- /* Trigger change detection */
22277
- this.changeDetectorRef.detectChanges();
22887
+ /* Reopen panel on next microtask so click/focus processing can complete first */
22888
+ queueMicrotask(() => this.autocompleteTrigger?.openPanel());
22278
22889
  }
22279
22890
  /**
22280
22891
  * Sets focus on the filter input element.
@@ -22482,6 +23093,7 @@ class VdChipsComponent extends AbstractMatFormField {
22482
23093
  ngOnDestroy() {
22483
23094
  super.ngOnDestroy();
22484
23095
  this.dataSourceSubscription?.unsubscribe();
23096
+ this.onDataLoadedSubscription?.unsubscribe();
22485
23097
  }
22486
23098
  /**
22487
23099
  * Log to console
@@ -22498,7 +23110,7 @@ class VdChipsComponent extends AbstractMatFormField {
22498
23110
  provide: MAT_AUTOCOMPLETE_DEFAULT_OPTIONS,
22499
23111
  useValue: { overlayPanelClass: 'vd-chips-autocomplete' }
22500
23112
  }
22501
- ], queries: [{ propertyName: "chipTemplate", first: true, predicate: VdChipDirective, descendants: true }, { propertyName: "autocompleteOptionTemplate", first: true, predicate: VdAutocompleteOptionDirective, descendants: true }], viewQueries: [{ propertyName: "dynamicTable", first: true, predicate: VdDynamicTableComponent, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }, { propertyName: "autocomplete", first: true, predicate: MatAutocomplete, descendants: true }, { propertyName: "autocompleteTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-chip-grid #chipList [required]=\"required\" [disabled]=\"readonly\">\r\n <!-- #region Chips -->\r\n @for (chip of chips; track chip; let first = $first; let index = $index) {\r\n <mat-chip-row [removable]=\"!readonly\" (removed)=\"handleRemovedEvent()\" disableRipple>\r\n <span class=\"vd-chip-content\">\r\n @if (!chipTemplate?.templateRef) {\r\n <span>\r\n @if (!autocompleteOptionTemplate?.templateRef) {\r\n <span>{{ chip }}</span>\r\n }\r\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: chip }\"></ng-template>\r\n }\r\n </span>\r\n }\r\n @if (chipTemplate && chipTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"chipTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ chip: chip }\"></ng-template>\r\n }\r\n </span>\r\n @for (button of suffixButtons; track button; let first = $first) {\r\n <a matChipTrailingIcon [hidden]=\"button.hide && button.hide(chips[0], context)\" (click)=\"$event.stopPropagation(); button.event && button.event(chips[0], context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{button.icon}}</mat-icon>\r\n </a>\r\n }\r\n @if ((onLaunch.observers.length) > 0) {\r\n <a matChipTrailingIcon (click)=\"$event.stopPropagation(); handleLaunchClicked()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">launch</mat-icon>\r\n </a>\r\n }\r\n @if (!readonly) {\r\n <a matChipTrailingIcon (click)=\"handleRemovedEvent()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">close</mat-icon>\r\n </a>\r\n }\r\n </mat-chip-row>\r\n }\r\n <!-- #endregion -->\r\n\r\n <!-- #region Search box -->\r\n <input matInput [hidden]=\"value && !empty\" placeholder=\"{{placeholder}}\" (focus)=\"connect()\" [readonly]=\"readonly\" [matChipInputFor]=\"chipList\" [matAutocomplete]=\"auto\" [matAutocompleteConnectedTo]=\"origin\" [formControl]=\"autoCompleteChipList\" (blur)=\"customValue && addOnBlur($event)\" #filterInput />\r\n <!-- #endregion -->\r\n\r\n <!-- #region Reset button -->\r\n @if ((!value || empty) && !readonly && !disabled) {\r\n <a trailingIcon class=\"mat-mdc-select-arrow\" (click)=\"filterInput.value = ''\">\r\n <svg viewBox=\"0 0 24 24\" width=\"24px\" height=\"24px\" focusable=\"false\" class=\"ng-tns-c184-21\">\r\n <path d=\"M7 10l5 5 5-5z\" class=\"ng-tns-c184-21\"></path>\r\n </svg>\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n</mat-chip-grid>\r\n\r\n<!-- #region Autocomplete -->\r\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"addChip($event.option.value, filterInput)\" class=\"{{autocompleteCssClass}}{{classType?' table-autocomplete':''}}\">\r\n @if(opened){\r\n @if(!classType)\r\n {\r\n @for (item of dataSource?.items; track item; let first = $first; let last = $last) {\r\n <mat-option [value]=\"item\">\r\n @if (!autocompleteOptionTemplate?.templateRef) {\r\n <span>{{item}}</span>\r\n }\r\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: item }\"></ng-template>\r\n }\r\n </mat-option>\r\n @if(!last){\r\n <mat-divider></mat-divider>\r\n }\r\n }\r\n }\r\n @if (classType) {\r\n <mat-option hide=\"true\"></mat-option>\r\n <vd-dynamic-table [dataSource]=\"dataSource\" [classType]=\"classType\" [entityObject]=\"entityObject\" [parentControl]=\"parentControl\" [context]=\"context\" [stickyHeader]=\"true\" [sticky]=\"true\" (rowClick)=\"addChip($event, filterInput)\" matSort [sortActive]=\"sortActive\" [sortDirection]=\"sortDirection\"></vd-dynamic-table>\r\n }\r\n }\r\n <div class=\"vd-chips-paginator\">\r\n <mat-divider></mat-divider>\r\n <mat-paginator [length]=\"dataSource?.total ?? 0\" [pageIndex]=\"dataSource?.pageIndex ?? 0\" [pageSize]=\"dataSource?.pageSize ?? 15\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\" hidePageSize=\"true\"></mat-paginator>\r\n </div>\r\n</mat-autocomplete>\r\n<!-- #endregion -->\r\n\r\n<div matAutocompleteOrigin #origin=\"matAutocompleteOrigin\" class=\"autocomplete-origin\"></div>", styles: [":host ::ng-deep .mat-mdc-chip-set{width:100%}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips{margin-left:0!important;margin-right:0;align-items:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip{display:flex;flex-direction:row;width:100%;padding:0 5px;justify-content:center;background-color:transparent!important;margin-right:0!important;margin-left:0!important;padding:0!important;margin:0;height:initial}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mdc-evolution-chip--disabled{opacity:.6;pointer-events:all}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action{justify-content:left}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__cell--trailing{margin-right:-10px;display:flex}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-mdc-chip-focus-overlay{background-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-icon{cursor:pointer;font-size:1.2em;opacity:.8}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mat-chip-disabled{opacity:.6}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-content{-ms-flex-positive:1!important;flex-grow:1!important;font-weight:initial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;flex-direction:column;justify-content:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch{font-size:18px;position:absolute;right:4px;top:0;cursor:pointer}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch.removable{right:34px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__action--primary:before,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__action--primary:before{border-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__text-label,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__text-label{color:inherit!important}:host ::ng-deep .autocomplete-origin{position:absolute;width:calc(100% + 28px);bottom:0;height:2px;margin-left:-14px}mat-spinner{margin-top:-9px;margin-right:6px}.mat-mdc-form-field-infix{display:flex}::ng-deep .vd-chips-autocomplete .mat-mdc-autocomplete-panel{padding:0!important}::ng-deep .vd-chips-autocomplete .table-autocomplete{overflow:hidden}::ng-deep .vd-chips-autocomplete .table-autocomplete .mat-table-container{height:calc(100% - 56px)!important;max-height:100vh!important}::ng-deep .vd-chips-autocomplete .vd-chips-paginator{position:sticky;bottom:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container{padding:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container .mat-mdc-paginator-range-actions .mat-mdc-paginator-range-label{margin:0 16px 0 24px}::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mat-mdc-notch-piece,::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mdc-text-field--focused .mat-mdc-notch-piece{border-color:var(--mat-form-field-outlined-outline-color, var(--mat-sys-outline))!important;border-width:var(--mat-form-field-outlined-outline-width, 1px)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i4$2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4$2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i4$2.MatAutocompleteOrigin, selector: "[matAutocompleteOrigin]", exportAs: ["matAutocompleteOrigin"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i6.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i7.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i7.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "component", type: i7.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: i7.MatChipTrailingIcon, selector: "mat-chip-trailing-icon, [matChipTrailingIcon]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: VdDynamicTableComponent, selector: "vd-dynamic-table", inputs: ["dataSource", "data", "parentControl", "entityObject", "formArray", "debugValue", "classType", "context", "dataSourceFilter", "static", "filterable", "sticky", "tableWidth", "useFilterOperator", "paginable", "selectable", "sortActive", "sortDirection", "stickyHeader", "stickyFilter", "columnSets", "rowNgClass", "detailsTemplate", "readonly", "selectAllFilter", "paginatorRef", "columns", "rowMenuItems", "rowAction", "excludedColumns", "pageSize", "pageSizeOptions"], outputs: ["rowClick"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
23113
+ ], queries: [{ propertyName: "chipTemplate", first: true, predicate: VdChipDirective, descendants: true }, { propertyName: "autocompleteOptionTemplate", first: true, predicate: VdAutocompleteOptionDirective, descendants: true }], viewQueries: [{ propertyName: "dynamicTable", first: true, predicate: VdDynamicTableComponent, descendants: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "sort", first: true, predicate: MatSort, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }, { propertyName: "autocomplete", first: true, predicate: MatAutocomplete, descendants: true }, { propertyName: "autocompleteTrigger", first: true, predicate: MatAutocompleteTrigger, descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-chip-grid #chipList [required]=\"required\" [disabled]=\"disabled\">\r\n <!-- #region Chips -->\r\n @for (chip of chips; track chip?.[key] ?? chip ?? $index; let first = $first; let index = $index) {\r\n <mat-chip [removable]=\"!readonly\" (removed)=\"handleRemovedEvent()\">\r\n @if(chip.icon) {\r\n <span matChipAvatar>\r\n <mat-icon fontSet=\"material-symbols-outlined\" [style.color]=\"chip.iconColor\">{{chip.icon}}</mat-icon>\r\n </span>\r\n }\r\n @if (!chipTemplate?.templateRef) {\r\n @if (!autocompleteOptionTemplate?.templateRef) {\r\n <span>{{ chip }}</span>\r\n }\r\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: chip }\"></ng-template>\r\n }\r\n }\r\n @if (chipTemplate && chipTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"chipTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ chip: chip }\"></ng-template>\r\n }\r\n @for (button of suffixButtons; track button?.icon ?? $index; let first = $first) {\r\n <a matChipTrailingIcon [hidden]=\"button.hide && button.hide(chips[0], context)\" (click)=\"$event.stopPropagation(); button.event && button.event(chips[0], context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{button.icon}}</mat-icon>\r\n </a>\r\n }\r\n @if (onLaunch.observed) {\r\n <a matChipTrailingIcon (click)=\"$event.stopPropagation(); handleLaunchClicked()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">launch</mat-icon>\r\n </a>\r\n }\r\n @if (!readonly) {\r\n <a matChipTrailingIcon (click)=\"handleRemovedEvent()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">close</mat-icon>\r\n </a>\r\n }\r\n </mat-chip>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Search box -->\r\n <input matInput [hidden]=\"value && !empty\" placeholder=\"{{placeholder}}\" (focus)=\"connect()\" (click)=\"reopenPanel()\" [readonly]=\"readonly\" [matChipInputFor]=\"chipList\" [matAutocomplete]=\"auto\" [matAutocompleteConnectedTo]=\"origin\" [formControl]=\"autoCompleteChipList\" (blur)=\"customValue && addOnBlur($event)\" #filterInput />\r\n <!-- #endregion -->\r\n <!-- #region Reset button -->\r\n @if ((!value || empty) && !readonly && !disabled) {\r\n <a trailingIcon class=\"mat-mdc-select-arrow\" (click)=\"filterInput.value = ''\">\r\n <svg viewBox=\"0 0 24 24\" width=\"24px\" height=\"24px\" focusable=\"false\" class=\"ng-tns-c184-21\">\r\n <path d=\"M7 10l5 5 5-5z\" class=\"ng-tns-c184-21\"></path>\r\n </svg>\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n</mat-chip-grid>\r\n<!-- #region Autocomplete -->\r\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"addChip($event.option.value, filterInput)\" class=\"{{autocompleteCssClass}}{{classType?' table-autocomplete':''}}\">\r\n @if(opened){\r\n @if (loading) {\r\n <mat-option disabled class=\"vd-chips-loading-option\">\r\n <mat-spinner diameter=\"32\"></mat-spinner>\r\n </mat-option>\r\n }\r\n @if (!loading && ((dataSource?.items?.length ?? 0) === 0)) {\r\n <mat-option disabled class=\"vd-chips-loading-option\">\r\n <span i18n=\"@@noResultsFound\">No results found</span>\r\n </mat-option>\r\n }\r\n @if(!classType)\r\n {\r\n @for (item of dataSource?.items; track item?.[key] ?? item ?? $index; let first = $first; let last = $last) {\r\n <mat-option [value]=\"item\">\r\n <div layout=\"row\" layout-align=\"start center\">\r\n @if(item.icon) {\r\n <span matChipAvatar>\r\n <mat-icon fontSet=\"material-symbols-outlined\" [style.color]=\"item.iconColor\">{{item.icon}}</mat-icon>\r\n </span>\r\n }\r\n @if (!autocompleteOptionTemplate?.templateRef) {\r\n <span>{{item}}</span>\r\n }\r\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: item }\"></ng-template>\r\n }\r\n </div>\r\n </mat-option>\r\n @if(!last){\r\n <mat-divider></mat-divider>\r\n }\r\n }\r\n }\r\n @if (classType) {\r\n <mat-option hide=\"true\"></mat-option>\r\n <vd-dynamic-table [dataSource]=\"dataSource\" [classType]=\"classType\" [entityObject]=\"entityObject\" [parentControl]=\"parentControl\" [context]=\"context\" [stickyHeader]=\"true\" [sticky]=\"true\" (rowClick)=\"addChip($event, filterInput)\" matSort [sortActive]=\"sortActive\" [sortDirection]=\"sortDirection\"></vd-dynamic-table>\r\n }\r\n }\r\n <div class=\"vd-chips-paginator\">\r\n <mat-divider></mat-divider>\r\n <mat-paginator [length]=\"dataSource?.total ?? 0\" [pageIndex]=\"dataSource?.pageIndex ?? 0\" [pageSize]=\"dataSource?.pageSize ?? 15\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\" hidePageSize=\"true\"></mat-paginator>\r\n </div>\r\n</mat-autocomplete>\r\n<!-- #endregion -->\r\n<div matAutocompleteOrigin #origin=\"matAutocompleteOrigin\" class=\"autocomplete-origin\"></div>", styles: [":host ::ng-deep .mat-mdc-standard-chip.mdc-evolution-chip--disabled .mdc-evolution-chip__text-label,:host ::ng-deep .mat-mdc-standard-chip.mdc-evolution-chip--selected.mdc-evolution-chip--disabled .mdc-evolution-chip__text-label{color:inherit!important}:host ::ng-deep .mat-mdc-chip{height:auto;min-height:32px}:host ::ng-deep .mat-mdc-chip-set{width:100%}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips{margin-left:0!important;margin-right:0;align-items:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip{display:flex;flex-direction:row;padding:0 10px;justify-content:center;margin:-4px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mdc-evolution-chip--disabled{opacity:.8;pointer-events:all}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action{justify-content:left}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__cell--trailing{margin-right:-10px;display:flex}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__icon--trailing{width:19px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__icon--trailing:not(:last-child){padding-right:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-mdc-chip-focus-overlay{background-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-icon{cursor:pointer;font-size:1.2em;opacity:.8;padding-top:4px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mat-chip-disabled{opacity:.6}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-content{-ms-flex-positive:1!important;flex-grow:1!important;font-weight:initial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;flex-direction:column;justify-content:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch{font-size:18px;position:absolute;right:4px;top:0;cursor:pointer}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch.removable{right:34px}:host ::ng-deep .autocomplete-origin{position:absolute;width:calc(100% + 28px);bottom:0;height:2px;margin-left:-14px}mat-spinner{margin-top:-9px;margin-right:6px}.mat-mdc-form-field-infix{display:flex}::ng-deep .vd-chips-autocomplete .mat-mdc-autocomplete-panel{padding:0!important}::ng-deep .vd-chips-autocomplete .vd-chips-loading-option{display:flex;justify-content:center;align-items:center;padding-left:0!important;padding-right:0!important}::ng-deep .vd-chips-autocomplete .vd-chips-loading-option .mdc-list-item__primary-text{display:flex;width:100%;justify-content:center;align-items:center}::ng-deep .vd-chips-autocomplete .vd-chips-loading-option mat-spinner{margin:0!important}::ng-deep .vd-chips-autocomplete .table-autocomplete{overflow:hidden}::ng-deep .vd-chips-autocomplete .table-autocomplete .mat-table-container{height:calc(100% - 56px)!important;max-height:100vh!important}::ng-deep .vd-chips-autocomplete .vd-chips-paginator{position:sticky;bottom:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container{padding:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container .mat-mdc-paginator-range-actions .mat-mdc-paginator-range-label{margin:0 16px 0 24px}::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mat-mdc-notch-piece,::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mdc-text-field--focused .mat-mdc-notch-piece{border-color:var(--mat-form-field-outlined-outline-color, var(--mat-sys-outline))!important;border-width:var(--mat-form-field-outlined-outline-width, 1px)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i4$2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4$2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: i4$2.MatAutocompleteOrigin, selector: "[matAutocompleteOrigin]", exportAs: ["matAutocompleteOrigin"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i6.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i7.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i7.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "component", type: i7.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i7.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i7.MatChipTrailingIcon, selector: "mat-chip-trailing-icon, [matChipTrailingIcon]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i10$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: VdDynamicTableComponent, selector: "vd-dynamic-table", inputs: ["dataSource", "data", "parentControl", "entityObject", "formArray", "debugValue", "classType", "context", "dataSourceFilter", "static", "filterable", "sticky", "tableWidth", "useFilterOperator", "paginable", "selectable", "sortActive", "sortDirection", "stickyHeader", "stickyFilter", "columnSets", "rowNgClass", "detailsTemplate", "readonly", "selectAllFilter", "paginatorRef", "columns", "rowMenuItems", "rowAction", "excludedColumns", "pageSize", "pageSizeOptions"], outputs: ["rowClick"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
22502
23114
  }
22503
23115
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: VdChipsComponent, decorators: [{
22504
23116
  type: Component,
@@ -22517,8 +23129,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
22517
23129
  MatChipsModule,
22518
23130
  MatIconModule,
22519
23131
  MatInputModule,
22520
- VdDynamicTableComponent,
22521
- ], template: "<mat-chip-grid #chipList [required]=\"required\" [disabled]=\"readonly\">\r\n <!-- #region Chips -->\r\n @for (chip of chips; track chip; let first = $first; let index = $index) {\r\n <mat-chip-row [removable]=\"!readonly\" (removed)=\"handleRemovedEvent()\" disableRipple>\r\n <span class=\"vd-chip-content\">\r\n @if (!chipTemplate?.templateRef) {\r\n <span>\r\n @if (!autocompleteOptionTemplate?.templateRef) {\r\n <span>{{ chip }}</span>\r\n }\r\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: chip }\"></ng-template>\r\n }\r\n </span>\r\n }\r\n @if (chipTemplate && chipTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"chipTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ chip: chip }\"></ng-template>\r\n }\r\n </span>\r\n @for (button of suffixButtons; track button; let first = $first) {\r\n <a matChipTrailingIcon [hidden]=\"button.hide && button.hide(chips[0], context)\" (click)=\"$event.stopPropagation(); button.event && button.event(chips[0], context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{button.icon}}</mat-icon>\r\n </a>\r\n }\r\n @if ((onLaunch.observers.length) > 0) {\r\n <a matChipTrailingIcon (click)=\"$event.stopPropagation(); handleLaunchClicked()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">launch</mat-icon>\r\n </a>\r\n }\r\n @if (!readonly) {\r\n <a matChipTrailingIcon (click)=\"handleRemovedEvent()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">close</mat-icon>\r\n </a>\r\n }\r\n </mat-chip-row>\r\n }\r\n <!-- #endregion -->\r\n\r\n <!-- #region Search box -->\r\n <input matInput [hidden]=\"value && !empty\" placeholder=\"{{placeholder}}\" (focus)=\"connect()\" [readonly]=\"readonly\" [matChipInputFor]=\"chipList\" [matAutocomplete]=\"auto\" [matAutocompleteConnectedTo]=\"origin\" [formControl]=\"autoCompleteChipList\" (blur)=\"customValue && addOnBlur($event)\" #filterInput />\r\n <!-- #endregion -->\r\n\r\n <!-- #region Reset button -->\r\n @if ((!value || empty) && !readonly && !disabled) {\r\n <a trailingIcon class=\"mat-mdc-select-arrow\" (click)=\"filterInput.value = ''\">\r\n <svg viewBox=\"0 0 24 24\" width=\"24px\" height=\"24px\" focusable=\"false\" class=\"ng-tns-c184-21\">\r\n <path d=\"M7 10l5 5 5-5z\" class=\"ng-tns-c184-21\"></path>\r\n </svg>\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n</mat-chip-grid>\r\n\r\n<!-- #region Autocomplete -->\r\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"addChip($event.option.value, filterInput)\" class=\"{{autocompleteCssClass}}{{classType?' table-autocomplete':''}}\">\r\n @if(opened){\r\n @if(!classType)\r\n {\r\n @for (item of dataSource?.items; track item; let first = $first; let last = $last) {\r\n <mat-option [value]=\"item\">\r\n @if (!autocompleteOptionTemplate?.templateRef) {\r\n <span>{{item}}</span>\r\n }\r\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: item }\"></ng-template>\r\n }\r\n </mat-option>\r\n @if(!last){\r\n <mat-divider></mat-divider>\r\n }\r\n }\r\n }\r\n @if (classType) {\r\n <mat-option hide=\"true\"></mat-option>\r\n <vd-dynamic-table [dataSource]=\"dataSource\" [classType]=\"classType\" [entityObject]=\"entityObject\" [parentControl]=\"parentControl\" [context]=\"context\" [stickyHeader]=\"true\" [sticky]=\"true\" (rowClick)=\"addChip($event, filterInput)\" matSort [sortActive]=\"sortActive\" [sortDirection]=\"sortDirection\"></vd-dynamic-table>\r\n }\r\n }\r\n <div class=\"vd-chips-paginator\">\r\n <mat-divider></mat-divider>\r\n <mat-paginator [length]=\"dataSource?.total ?? 0\" [pageIndex]=\"dataSource?.pageIndex ?? 0\" [pageSize]=\"dataSource?.pageSize ?? 15\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\" hidePageSize=\"true\"></mat-paginator>\r\n </div>\r\n</mat-autocomplete>\r\n<!-- #endregion -->\r\n\r\n<div matAutocompleteOrigin #origin=\"matAutocompleteOrigin\" class=\"autocomplete-origin\"></div>", styles: [":host ::ng-deep .mat-mdc-chip-set{width:100%}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips{margin-left:0!important;margin-right:0;align-items:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip{display:flex;flex-direction:row;width:100%;padding:0 5px;justify-content:center;background-color:transparent!important;margin-right:0!important;margin-left:0!important;padding:0!important;margin:0;height:initial}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mdc-evolution-chip--disabled{opacity:.6;pointer-events:all}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action{justify-content:left}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__cell--trailing{margin-right:-10px;display:flex}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-mdc-chip-focus-overlay{background-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-icon{cursor:pointer;font-size:1.2em;opacity:.8}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mat-chip-disabled{opacity:.6}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-content{-ms-flex-positive:1!important;flex-grow:1!important;font-weight:initial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;flex-direction:column;justify-content:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch{font-size:18px;position:absolute;right:4px;top:0;cursor:pointer}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch.removable{right:34px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__action--primary:before,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__action--primary:before{border-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip .mdc-evolution-chip__text-label,:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip--disabled .mdc-evolution-chip__text-label{color:inherit!important}:host ::ng-deep .autocomplete-origin{position:absolute;width:calc(100% + 28px);bottom:0;height:2px;margin-left:-14px}mat-spinner{margin-top:-9px;margin-right:6px}.mat-mdc-form-field-infix{display:flex}::ng-deep .vd-chips-autocomplete .mat-mdc-autocomplete-panel{padding:0!important}::ng-deep .vd-chips-autocomplete .table-autocomplete{overflow:hidden}::ng-deep .vd-chips-autocomplete .table-autocomplete .mat-table-container{height:calc(100% - 56px)!important;max-height:100vh!important}::ng-deep .vd-chips-autocomplete .vd-chips-paginator{position:sticky;bottom:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container{padding:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container .mat-mdc-paginator-range-actions .mat-mdc-paginator-range-label{margin:0 16px 0 24px}::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mat-mdc-notch-piece,::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mdc-text-field--focused .mat-mdc-notch-piece{border-color:var(--mat-form-field-outlined-outline-color, var(--mat-sys-outline))!important;border-width:var(--mat-form-field-outlined-outline-width, 1px)!important}\n"] }]
23132
+ MatProgressSpinnerModule,
23133
+ VdDynamicTableComponent
23134
+ ], template: "<mat-chip-grid #chipList [required]=\"required\" [disabled]=\"disabled\">\r\n <!-- #region Chips -->\r\n @for (chip of chips; track chip?.[key] ?? chip ?? $index; let first = $first; let index = $index) {\r\n <mat-chip [removable]=\"!readonly\" (removed)=\"handleRemovedEvent()\">\r\n @if(chip.icon) {\r\n <span matChipAvatar>\r\n <mat-icon fontSet=\"material-symbols-outlined\" [style.color]=\"chip.iconColor\">{{chip.icon}}</mat-icon>\r\n </span>\r\n }\r\n @if (!chipTemplate?.templateRef) {\r\n @if (!autocompleteOptionTemplate?.templateRef) {\r\n <span>{{ chip }}</span>\r\n }\r\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: chip }\"></ng-template>\r\n }\r\n }\r\n @if (chipTemplate && chipTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"chipTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ chip: chip }\"></ng-template>\r\n }\r\n @for (button of suffixButtons; track button?.icon ?? $index; let first = $first) {\r\n <a matChipTrailingIcon [hidden]=\"button.hide && button.hide(chips[0], context)\" (click)=\"$event.stopPropagation(); button.event && button.event(chips[0], context)\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">{{button.icon}}</mat-icon>\r\n </a>\r\n }\r\n @if (onLaunch.observed) {\r\n <a matChipTrailingIcon (click)=\"$event.stopPropagation(); handleLaunchClicked()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">launch</mat-icon>\r\n </a>\r\n }\r\n @if (!readonly) {\r\n <a matChipTrailingIcon (click)=\"handleRemovedEvent()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">close</mat-icon>\r\n </a>\r\n }\r\n </mat-chip>\r\n }\r\n <!-- #endregion -->\r\n <!-- #region Search box -->\r\n <input matInput [hidden]=\"value && !empty\" placeholder=\"{{placeholder}}\" (focus)=\"connect()\" (click)=\"reopenPanel()\" [readonly]=\"readonly\" [matChipInputFor]=\"chipList\" [matAutocomplete]=\"auto\" [matAutocompleteConnectedTo]=\"origin\" [formControl]=\"autoCompleteChipList\" (blur)=\"customValue && addOnBlur($event)\" #filterInput />\r\n <!-- #endregion -->\r\n <!-- #region Reset button -->\r\n @if ((!value || empty) && !readonly && !disabled) {\r\n <a trailingIcon class=\"mat-mdc-select-arrow\" (click)=\"filterInput.value = ''\">\r\n <svg viewBox=\"0 0 24 24\" width=\"24px\" height=\"24px\" focusable=\"false\" class=\"ng-tns-c184-21\">\r\n <path d=\"M7 10l5 5 5-5z\" class=\"ng-tns-c184-21\"></path>\r\n </svg>\r\n </a>\r\n }\r\n <!-- #endregion -->\r\n</mat-chip-grid>\r\n<!-- #region Autocomplete -->\r\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"addChip($event.option.value, filterInput)\" class=\"{{autocompleteCssClass}}{{classType?' table-autocomplete':''}}\">\r\n @if(opened){\r\n @if (loading) {\r\n <mat-option disabled class=\"vd-chips-loading-option\">\r\n <mat-spinner diameter=\"32\"></mat-spinner>\r\n </mat-option>\r\n }\r\n @if (!loading && ((dataSource?.items?.length ?? 0) === 0)) {\r\n <mat-option disabled class=\"vd-chips-loading-option\">\r\n <span i18n=\"@@noResultsFound\">No results found</span>\r\n </mat-option>\r\n }\r\n @if(!classType)\r\n {\r\n @for (item of dataSource?.items; track item?.[key] ?? item ?? $index; let first = $first; let last = $last) {\r\n <mat-option [value]=\"item\">\r\n <div layout=\"row\" layout-align=\"start center\">\r\n @if(item.icon) {\r\n <span matChipAvatar>\r\n <mat-icon fontSet=\"material-symbols-outlined\" [style.color]=\"item.iconColor\">{{item.icon}}</mat-icon>\r\n </span>\r\n }\r\n @if (!autocompleteOptionTemplate?.templateRef) {\r\n <span>{{item}}</span>\r\n }\r\n @if (autocompleteOptionTemplate && autocompleteOptionTemplate.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"autocompleteOptionTemplate.templateRef!\" [ngTemplateOutletContext]=\"{ option: item }\"></ng-template>\r\n }\r\n </div>\r\n </mat-option>\r\n @if(!last){\r\n <mat-divider></mat-divider>\r\n }\r\n }\r\n }\r\n @if (classType) {\r\n <mat-option hide=\"true\"></mat-option>\r\n <vd-dynamic-table [dataSource]=\"dataSource\" [classType]=\"classType\" [entityObject]=\"entityObject\" [parentControl]=\"parentControl\" [context]=\"context\" [stickyHeader]=\"true\" [sticky]=\"true\" (rowClick)=\"addChip($event, filterInput)\" matSort [sortActive]=\"sortActive\" [sortDirection]=\"sortDirection\"></vd-dynamic-table>\r\n }\r\n }\r\n <div class=\"vd-chips-paginator\">\r\n <mat-divider></mat-divider>\r\n <mat-paginator [length]=\"dataSource?.total ?? 0\" [pageIndex]=\"dataSource?.pageIndex ?? 0\" [pageSize]=\"dataSource?.pageSize ?? 15\" [pageSizeOptions]=\"pageSizeOptions\" showFirstLastButtons=\"true\" hidePageSize=\"true\"></mat-paginator>\r\n </div>\r\n</mat-autocomplete>\r\n<!-- #endregion -->\r\n<div matAutocompleteOrigin #origin=\"matAutocompleteOrigin\" class=\"autocomplete-origin\"></div>", styles: [":host ::ng-deep .mat-mdc-standard-chip.mdc-evolution-chip--disabled .mdc-evolution-chip__text-label,:host ::ng-deep .mat-mdc-standard-chip.mdc-evolution-chip--selected.mdc-evolution-chip--disabled .mdc-evolution-chip__text-label{color:inherit!important}:host ::ng-deep .mat-mdc-chip{height:auto;min-height:32px}:host ::ng-deep .mat-mdc-chip-set{width:100%}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips{margin-left:0!important;margin-right:0;align-items:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip{display:flex;flex-direction:row;padding:0 10px;justify-content:center;margin:-4px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mdc-evolution-chip--disabled{opacity:.8;pointer-events:all}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action{justify-content:left}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__action--primary{padding-left:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__cell--trailing{margin-right:-10px;display:flex}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__icon--trailing{width:19px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mdc-evolution-chip__icon--trailing:not(:last-child){padding-right:0}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-mdc-chip-focus-overlay{background-color:transparent!important}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .mat-icon{cursor:pointer;font-size:1.2em;opacity:.8;padding-top:4px}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip.mat-chip-disabled{opacity:.6}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-content{-ms-flex-positive:1!important;flex-grow:1!important;font-weight:initial;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;flex-direction:column;justify-content:center}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch{font-size:18px;position:absolute;right:4px;top:0;cursor:pointer}:host ::ng-deep .mat-mdc-chip-set .mdc-evolution-chip-set__chips .mat-mdc-chip .vd-chip-launch.removable{right:34px}:host ::ng-deep .autocomplete-origin{position:absolute;width:calc(100% + 28px);bottom:0;height:2px;margin-left:-14px}mat-spinner{margin-top:-9px;margin-right:6px}.mat-mdc-form-field-infix{display:flex}::ng-deep .vd-chips-autocomplete .mat-mdc-autocomplete-panel{padding:0!important}::ng-deep .vd-chips-autocomplete .vd-chips-loading-option{display:flex;justify-content:center;align-items:center;padding-left:0!important;padding-right:0!important}::ng-deep .vd-chips-autocomplete .vd-chips-loading-option .mdc-list-item__primary-text{display:flex;width:100%;justify-content:center;align-items:center}::ng-deep .vd-chips-autocomplete .vd-chips-loading-option mat-spinner{margin:0!important}::ng-deep .vd-chips-autocomplete .table-autocomplete{overflow:hidden}::ng-deep .vd-chips-autocomplete .table-autocomplete .mat-table-container{height:calc(100% - 56px)!important;max-height:100vh!important}::ng-deep .vd-chips-autocomplete .vd-chips-paginator{position:sticky;bottom:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container{padding:0}::ng-deep .vd-chips-autocomplete .vd-chips-paginator .mat-mdc-paginator .mat-mdc-paginator-container .mat-mdc-paginator-range-actions .mat-mdc-paginator-range-label{margin:0 16px 0 24px}::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mat-mdc-notch-piece,::ng-deep .mat-mdc-table .mat-mdc-form-field .mdc-text-field--outlined .mdc-text-field--focused .mat-mdc-notch-piece{border-color:var(--mat-form-field-outlined-outline-color, var(--mat-sys-outline))!important;border-width:var(--mat-form-field-outlined-outline-width, 1px)!important}\n"] }]
22522
23135
  }], ctorParameters: () => [{ type: VdMediaService }], propDecorators: { dynamicTable: [{
22523
23136
  type: ViewChild,
22524
23137
  args: [VdDynamicTableComponent, { static: false }]
@@ -23159,6 +23772,41 @@ var FormFieldType;
23159
23772
  FormFieldType[FormFieldType["Custom"] = 100] = "Custom";
23160
23773
  })(FormFieldType || (FormFieldType = {}));
23161
23774
 
23775
+ /**
23776
+ * @class MatInputRequiredDirective
23777
+ * @description Synchronizes Angular Material input required marker with tracked control required state.
23778
+ */
23779
+ class MatInputRequiredDirective {
23780
+ input;
23781
+ /**
23782
+ * @constructor
23783
+ * @param {MatInput} input Material input instance.
23784
+ */
23785
+ constructor(input) {
23786
+ this.input = input;
23787
+ }
23788
+ /**
23789
+ * @method ngDoCheck
23790
+ * @description Updates Material input required flag when control required state changes.
23791
+ */
23792
+ ngDoCheck() {
23793
+ const isRequired = hasRequiredValidator(this.input.ngControl?.control);
23794
+ if (isRequired !== this.input.required) {
23795
+ this.input.required = isRequired;
23796
+ this.input.ngOnChanges();
23797
+ }
23798
+ }
23799
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MatInputRequiredDirective, deps: [{ token: i3$2.MatInput }], target: i0.ɵɵFactoryTarget.Directive });
23800
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: MatInputRequiredDirective, isStandalone: true, selector: "[matInput][formControl]:not([required]), [matInput][formControlName]:not([required])", ngImport: i0 });
23801
+ }
23802
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MatInputRequiredDirective, decorators: [{
23803
+ type: Directive,
23804
+ args: [{
23805
+ selector: '[matInput][formControl]:not([required]), [matInput][formControlName]:not([required])',
23806
+ standalone: true
23807
+ }]
23808
+ }], ctorParameters: () => [{ type: i3$2.MatInput }] });
23809
+
23162
23810
  /**
23163
23811
  * Directive that optionally enforces a fixed, non-removable prefix
23164
23812
  * at the beginning of an input field.
@@ -23895,7 +24543,7 @@ class MsaGenericFormAutocompleteFieldComponent extends MsaGenericFormFieldBaseCo
23895
24543
  <mat-error>{{errorMessage}}</mat-error>
23896
24544
  }
23897
24545
  </mat-form-field>
23898
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i4$2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4$2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: PrefixDirective, selector: "[prefix]", inputs: ["prefix"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
24546
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i4$2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i4$2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatInputRequiredDirective, selector: "[matInput][formControl]:not([required]), [matInput][formControlName]:not([required])" }, { kind: "directive", type: PrefixDirective, selector: "[prefix]", inputs: ["prefix"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
23899
24547
  }
23900
24548
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormAutocompleteFieldComponent, decorators: [{
23901
24549
  type: Component,
@@ -23907,6 +24555,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
23907
24555
  MatAutocompleteModule,
23908
24556
  MatIconModule,
23909
24557
  MatIconButton,
24558
+ MatInputRequiredDirective,
23910
24559
  PrefixDirective,
23911
24560
  FuncPipe
23912
24561
  ], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: `
@@ -23991,11 +24640,11 @@ class MsaGenericFormCalendarFieldComponent extends MsaGenericFormFieldBaseCompon
23991
24640
  <mat-error layout-margin>{{errorMessage}}</mat-error>
23992
24641
  }
23993
24642
  </mat-form-field>
23994
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4$1.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
24643
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4$1.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "directive", type: MatInputRequiredDirective, selector: "[matInput][formControl]:not([required]), [matInput][formControlName]:not([required])" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
23995
24644
  }
23996
24645
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormCalendarFieldComponent, decorators: [{
23997
24646
  type: Component,
23998
- args: [{ selector: 'msa-generic-form-calendar-field', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatDatepickerModule], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: `
24647
+ args: [{ selector: 'msa-generic-form-calendar-field', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, MatInputRequiredDirective], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: `
23999
24648
  <mat-form-field [class]="field.cssClass" floatLabel="always" class="form-field-type-calendar">
24000
24649
  <mat-label>{{field.label}}</mat-label>
24001
24650
  <input input="hidden" hidden matInput [formControlName]="field.name!" />
@@ -24326,7 +24975,7 @@ class MsaGenericFormColorFieldComponent extends MsaGenericFormFieldBaseComponent
24326
24975
  <mat-error>{{errorMessage}}</mat-error>
24327
24976
  }
24328
24977
  </mat-form-field>
24329
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}.color-picker{width:1.6rem!important;height:1.6rem!important;padding:2px!important;margin:8px;display:inline-block;box-sizing:border-box;border-color:transparent!important;border-radius:100%;background:#fff;cursor:pointer;padding:3px;box-shadow:0 1px 1px #0003,0 1px 1px 1px #00000024,0 1px 1px 1px #0000001f;appearance:none;-webkit-appearance:none}.color-picker::-webkit-color-swatch-wrapper{padding:0}.color-picker::-webkit-color-swatch{border:1px solid rgba(0,0,0,.2);border-radius:999px}.color-picker::-moz-color-swatch{border:1px solid rgba(0,0,0,.2);border-radius:999px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: OnlyNumberDirective, selector: "[onlyNumber]", inputs: ["onlyNumber", "excludePrefix"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
24978
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}.color-picker{width:1.6rem!important;height:1.6rem!important;padding:2px!important;margin:8px;display:inline-block;box-sizing:border-box;border-color:transparent!important;border-radius:100%;background:#fff;cursor:pointer;padding:3px;box-shadow:0 1px 1px #0003,0 1px 1px 1px #00000024,0 1px 1px 1px #0000001f;appearance:none;-webkit-appearance:none}.color-picker::-webkit-color-swatch-wrapper{padding:0}.color-picker::-webkit-color-swatch{border:1px solid rgba(0,0,0,.2);border-radius:999px}.color-picker::-moz-color-swatch{border:1px solid rgba(0,0,0,.2);border-radius:999px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatInputRequiredDirective, selector: "[matInput][formControl]:not([required]), [matInput][formControlName]:not([required])" }, { kind: "directive", type: OnlyNumberDirective, selector: "[onlyNumber]", inputs: ["onlyNumber", "excludePrefix"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
24330
24979
  }
24331
24980
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormColorFieldComponent, decorators: [{
24332
24981
  type: Component,
@@ -24337,6 +24986,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
24337
24986
  MatInputModule,
24338
24987
  MatIconModule,
24339
24988
  MatIconButton,
24989
+ MatInputRequiredDirective,
24340
24990
  FuncPipe,
24341
24991
  OnlyNumberDirective
24342
24992
  ], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: `
@@ -24477,11 +25127,11 @@ class MsaGenericFormDateFieldComponent extends MsaGenericFormFieldBaseComponent
24477
25127
  <mat-error>{{errorMessage}}</mat-error>
24478
25128
  }
24479
25129
  </mat-form-field>
24480
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "pipe", type: i1$2.DatePipe, name: "date" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
25130
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i4$1.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i4$1.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i4$1.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "directive", type: MatInputRequiredDirective, selector: "[matInput][formControl]:not([required]), [matInput][formControlName]:not([required])" }, { kind: "pipe", type: i1$2.DatePipe, name: "date" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
24481
25131
  }
24482
25132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormDateFieldComponent, decorators: [{
24483
25133
  type: Component,
24484
- args: [{ selector: 'msa-generic-form-date-field', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatDatepickerModule], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: `
25134
+ args: [{ selector: 'msa-generic-form-date-field', standalone: true, imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatDatepickerModule, MatInputRequiredDirective], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: `
24485
25135
  <mat-form-field [class]="field.cssClass">
24486
25136
  <mat-label>{{field.label}}</mat-label>
24487
25137
  <div flex layout="row" layout-align="start center" [class]="{'has-time': field.showTime}">
@@ -24783,8 +25433,8 @@ class MsaGenericFormMsaChipsFieldComponent extends MsaGenericFormFieldBaseCompon
24783
25433
  layout="row"
24784
25434
  flex>
24785
25435
  @if (field.chipTemplate; as chip) {
24786
- <ng-template vd-chip let-chip="chip">
24787
- <div [outerHTML]="field.chipTemplate(chip, formValue, formGroup, context)"></div>
25436
+ <ng-template vd-chip let-chip="chip">
25437
+ <span [outerHTML]="field.chipTemplate(chip, formValue, formGroup, context)"></span>
24788
25438
  </ng-template>
24789
25439
  }
24790
25440
  @if (field.autocompleteTemplate; as option) {
@@ -24803,7 +25453,7 @@ class MsaGenericFormMsaChipsFieldComponent extends MsaGenericFormFieldBaseCompon
24803
25453
  <mat-error>{{errorMessage}}</mat-error>
24804
25454
  }
24805
25455
  </mat-form-field>
24806
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: VdChipsComponent, selector: "vd-chips", inputs: ["classType", "chips", "endpoint", "params", "projection", "paginated", "customValue", "context", "key", "searchField", "searchFields", "filters", "removable", "selectFirst", "debounce", "autocompleteCssClass", "suffixButtons"], outputs: ["initSelect", "selected", "cleared", "launch", "chipFocus"] }, { kind: "directive", type: VdChipDirective, selector: "[vd-chip]ng-template" }, { kind: "directive", type: VdAutocompleteOptionDirective, selector: "[vd-autocomplete-option]ng-template" }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
25456
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: VdChipsComponent, selector: "vd-chips", inputs: ["classType", "chips", "endpoint", "params", "projection", "paginated", "customValue", "context", "key", "searchField", "searchFields", "filters", "removable", "selectFirst", "debounce", "autocompleteCssClass", "suffixButtons"], outputs: ["initSelect", "selected", "cleared", "launch", "chipFocus"] }, { kind: "directive", type: VdChipDirective, selector: "[vd-chip]ng-template" }, { kind: "directive", type: VdAutocompleteOptionDirective, selector: "[vd-autocomplete-option]ng-template" }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
24807
25457
  }
24808
25458
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormMsaChipsFieldComponent, decorators: [{
24809
25459
  type: Component,
@@ -24811,6 +25461,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
24811
25461
  CommonModule,
24812
25462
  ReactiveFormsModule,
24813
25463
  MatFormFieldModule,
25464
+ MatIconModule,
24814
25465
  FuncPipe,
24815
25466
  VdChipsComponent,
24816
25467
  VdChipDirective,
@@ -24841,8 +25492,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
24841
25492
  layout="row"
24842
25493
  flex>
24843
25494
  @if (field.chipTemplate; as chip) {
24844
- <ng-template vd-chip let-chip="chip">
24845
- <div [outerHTML]="field.chipTemplate(chip, formValue, formGroup, context)"></div>
25495
+ <ng-template vd-chip let-chip="chip">
25496
+ <span [outerHTML]="field.chipTemplate(chip, formValue, formGroup, context)"></span>
24846
25497
  </ng-template>
24847
25498
  }
24848
25499
  @if (field.autocompleteTemplate; as option) {
@@ -24908,7 +25559,7 @@ class VdListComponent extends AbstractSelectFormField {
24908
25559
  this.selectEl?.focus();
24909
25560
  }
24910
25561
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: VdListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
24911
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: VdListComponent, isStandalone: true, selector: "vd-list", host: { classAttribute: "vd-list" }, providers: [{ provide: MatFormFieldControl, useExisting: VdListComponent }], queries: [{ propertyName: "optionTemplate", first: true, predicate: VdListOptionDirective, descendants: true }], viewQueries: [{ propertyName: "selectEl", first: true, predicate: MatSelectionList, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-selection-list i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelectionList\" (selectionChange)=\"handleChange($event)\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled || readonly\" [hideSingleSelectionIndicator]=\"false\" flex>\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-list-option [value]=\"mapper ? option : option[optionValueProperty]\">\n @if (!optionTemplate?.templateRef) {\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other{{{option[optionTextProperty]}}}}</span>\n } @if (optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(optionTemplate.templateRef)!\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n }\n </mat-list-option>\n }\n <!-- #endregion -->\n</mat-selection-list>", styles: ["::ng-deep .vd-list{overflow:auto;max-height:100%}::ng-deep .mat-mdc-form-field-type-vd-list .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}::ng-deep .mat-mdc-form-field-type-vd-list .mdc-text-field{padding:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MatSelectionList, selector: "mat-selection-list", inputs: ["color", "compareWith", "multiple", "hideSingleSelectionIndicator", "disabled"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: MatListOption, selector: "mat-list-option", inputs: ["togglePosition", "color", "value", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
25562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: VdListComponent, isStandalone: true, selector: "vd-list", host: { classAttribute: "vd-list" }, providers: [{ provide: MatFormFieldControl, useExisting: VdListComponent }], queries: [{ propertyName: "optionTemplate", first: true, predicate: VdListOptionDirective, descendants: true }], viewQueries: [{ propertyName: "selectEl", first: true, predicate: MatSelectionList, descendants: true }, { propertyName: "filterInput", first: true, predicate: ["filterInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<mat-selection-list i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelectionList\" (selectionChange)=\"handleChange($event)\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled || readonly\" [hideSingleSelectionIndicator]=\"false\" flex>\r\n <!-- #region Options -->\r\n @for (option of filteredOptions; track option; let first = $first) {\r\n <mat-list-option [value]=\"mapper ? option : option[optionValueProperty]\">\r\n @if (!optionTemplate?.templateRef) {\r\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other{{{option[optionTextProperty]}}}}</span>\r\n } @if (optionTemplate?.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(optionTemplate.templateRef)!\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\r\n }\r\n </mat-list-option>\r\n }\r\n <!-- #endregion -->\r\n</mat-selection-list>", styles: ["::ng-deep .vd-list{overflow:auto;max-height:100%}::ng-deep .mat-mdc-form-field-type-vd-list .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}::ng-deep .mat-mdc-form-field-type-vd-list .mdc-text-field{padding:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MatSelectionList, selector: "mat-selection-list", inputs: ["color", "compareWith", "multiple", "hideSingleSelectionIndicator", "disabled"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: MatListOption, selector: "mat-list-option", inputs: ["togglePosition", "color", "value", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
24912
25563
  }
24913
25564
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: VdListComponent, decorators: [{
24914
25565
  type: Component,
@@ -24917,7 +25568,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
24917
25568
  MatSelectionList,
24918
25569
  MatListOption,
24919
25570
  FormsModule
24920
- ], template: "<mat-selection-list i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelectionList\" (selectionChange)=\"handleChange($event)\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled || readonly\" [hideSingleSelectionIndicator]=\"false\" flex>\n <!-- #region Options -->\n @for (option of filteredOptions; track option; let first = $first) {\n <mat-list-option [value]=\"mapper ? option : option[optionValueProperty]\">\n @if (!optionTemplate?.templateRef) {\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other{{{option[optionTextProperty]}}}}</span>\n } @if (optionTemplate?.templateRef) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(optionTemplate.templateRef)!\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\n }\n </mat-list-option>\n }\n <!-- #endregion -->\n</mat-selection-list>", styles: ["::ng-deep .vd-list{overflow:auto;max-height:100%}::ng-deep .mat-mdc-form-field-type-vd-list .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}::ng-deep .mat-mdc-form-field-type-vd-list .mdc-text-field{padding:0}\n"] }]
25571
+ ], template: "<mat-selection-list i18n-placeholder [(ngModel)]=\"value\" #select=\"matSelectionList\" (selectionChange)=\"handleChange($event)\" [multiple]=\"multiple\" [compareWith]=\"compareWith??defaultCompareWith\" [disabled]=\"disabled || readonly\" [hideSingleSelectionIndicator]=\"false\" flex>\r\n <!-- #region Options -->\r\n @for (option of filteredOptions; track option; let first = $first) {\r\n <mat-list-option [value]=\"mapper ? option : option[optionValueProperty]\">\r\n @if (!optionTemplate?.templateRef) {\r\n <span i18n=\"@@selection\">{option[optionTextProperty], select, option {option} other{{{option[optionTextProperty]}}}}</span>\r\n } @if (optionTemplate?.templateRef) {\r\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(optionTemplate.templateRef)!\" [ngTemplateOutletContext]=\"{ option: option }\"></ng-template>\r\n }\r\n </mat-list-option>\r\n }\r\n <!-- #endregion -->\r\n</mat-selection-list>", styles: ["::ng-deep .vd-list{overflow:auto;max-height:100%}::ng-deep .mat-mdc-form-field-type-vd-list .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}::ng-deep .mat-mdc-form-field-type-vd-list .mdc-text-field{padding:0}\n"] }]
24921
25572
  }], ctorParameters: () => [], propDecorators: { optionTemplate: [{
24922
25573
  type: ContentChild,
24923
25574
  args: [VdListOptionDirective]
@@ -25010,6 +25661,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
25010
25661
  `, styles: ["mat-form-field{width:100%;height:100%}\n"] }]
25011
25662
  }] });
25012
25663
 
25664
+ /**
25665
+ * @class MsaSelectRequiredDirective
25666
+ * @description Synchronizes Angular Material select required marker with tracked control required state.
25667
+ */
25668
+ class MsaSelectRequiredDirective {
25669
+ input;
25670
+ /**
25671
+ * @constructor
25672
+ * @param {VdSelectComponent} input Material select instance.
25673
+ */
25674
+ constructor(input) {
25675
+ this.input = input;
25676
+ }
25677
+ /**
25678
+ * @method ngDoCheck
25679
+ * @description Updates Material select required flag when control required state changes.
25680
+ */
25681
+ ngDoCheck() {
25682
+ const isRequired = hasRequiredValidator(this.input.ngControl?.control);
25683
+ if (isRequired !== this.input.required) {
25684
+ this.input.required = isRequired;
25685
+ }
25686
+ }
25687
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaSelectRequiredDirective, deps: [{ token: VdSelectComponent }], target: i0.ɵɵFactoryTarget.Directive });
25688
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: MsaSelectRequiredDirective, isStandalone: true, selector: "vd-select[formControl]:not([required]), vd-select[formControlName]:not([required])", ngImport: i0 });
25689
+ }
25690
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaSelectRequiredDirective, decorators: [{
25691
+ type: Directive,
25692
+ args: [{
25693
+ selector: 'vd-select[formControl]:not([required]), vd-select[formControlName]:not([required])',
25694
+ standalone: true
25695
+ }]
25696
+ }], ctorParameters: () => [{ type: VdSelectComponent }] });
25697
+
25013
25698
  /**
25014
25699
  * @class MsaGenericFormMsaSelectFieldComponent
25015
25700
  * @description Renders a MsaSelect case for `MsaGenericFormComponent`.
@@ -25099,7 +25784,7 @@ class MsaGenericFormMsaSelectFieldComponent extends MsaGenericFormFieldBaseCompo
25099
25784
  <mat-error>{{errorMessage}}</mat-error>
25100
25785
  }
25101
25786
  </mat-form-field>
25102
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i7.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i7.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass"] }, { kind: "directive", type: VdSelectOptionDirective, selector: "[vd-select-option]ng-template" }, { kind: "directive", type: VdSelectTriggerDirective, selector: "[vd-select-trigger]ng-template" }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
25787
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i7.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "component", type: i7.MatChipSet, selector: "mat-chip-set", inputs: ["disabled", "role", "tabIndex"] }, { kind: "component", type: VdSelectComponent, selector: "vd-select", inputs: ["triggerCssClass"] }, { kind: "directive", type: VdSelectOptionDirective, selector: "[vd-select-option]ng-template" }, { kind: "directive", type: VdSelectTriggerDirective, selector: "[vd-select-trigger]ng-template" }, { kind: "directive", type: MsaSelectRequiredDirective, selector: "vd-select[formControl]:not([required]), vd-select[formControlName]:not([required])" }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
25103
25788
  }
25104
25789
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormMsaSelectFieldComponent, decorators: [{
25105
25790
  type: Component,
@@ -25113,7 +25798,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
25113
25798
  FuncPipe,
25114
25799
  VdSelectComponent,
25115
25800
  VdSelectOptionDirective,
25116
- VdSelectTriggerDirective
25801
+ VdSelectTriggerDirective,
25802
+ MsaSelectRequiredDirective
25117
25803
  ], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: `
25118
25804
  <mat-form-field [class]="field.cssClass">
25119
25805
  <mat-label>{{field.label}}</mat-label>
@@ -25512,6 +26198,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
25512
26198
  `, styles: ["mat-form-field{width:100%;height:100%}\n"] }]
25513
26199
  }] });
25514
26200
 
26201
+ /**
26202
+ * @class MatSelectRequiredDirective
26203
+ * @description Synchronizes Angular Material select required marker with tracked control required state.
26204
+ */
26205
+ class MatSelectRequiredDirective {
26206
+ input;
26207
+ /**
26208
+ * @constructor
26209
+ * @param {MatSelect} input Material select instance.
26210
+ */
26211
+ constructor(input) {
26212
+ this.input = input;
26213
+ }
26214
+ /**
26215
+ * @method ngDoCheck
26216
+ * @description Updates Material select required flag when control required state changes.
26217
+ */
26218
+ ngDoCheck() {
26219
+ const isRequired = hasRequiredValidator(this.input.ngControl?.control);
26220
+ if (isRequired !== this.input.required) {
26221
+ this.input.required = isRequired;
26222
+ }
26223
+ }
26224
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MatSelectRequiredDirective, deps: [{ token: i2$2.MatSelect }], target: i0.ɵɵFactoryTarget.Directive });
26225
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: MatSelectRequiredDirective, isStandalone: true, selector: "mat-select[formControl]:not([required]), mat-select[formControlName]:not([required])", ngImport: i0 });
26226
+ }
26227
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MatSelectRequiredDirective, decorators: [{
26228
+ type: Directive,
26229
+ args: [{
26230
+ selector: 'mat-select[formControl]:not([required]), mat-select[formControlName]:not([required])',
26231
+ standalone: true
26232
+ }]
26233
+ }], ctorParameters: () => [{ type: i2$2.MatSelect }] });
26234
+
25515
26235
  /**
25516
26236
  * @class MsaGenericFormSelectFieldComponent
25517
26237
  * @description Renders a Select case for `MsaGenericFormComponent`.
@@ -25548,7 +26268,7 @@ class MsaGenericFormSelectFieldComponent extends MsaGenericFormFieldBaseComponen
25548
26268
  <mat-error>{{errorMessage}}</mat-error>
25549
26269
  }
25550
26270
  </mat-form-field>
25551
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
26271
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2$2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatSelectRequiredDirective, selector: "mat-select[formControl]:not([required]), mat-select[formControlName]:not([required])" }, { kind: "directive", type: DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
25552
26272
  }
25553
26273
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormSelectFieldComponent, decorators: [{
25554
26274
  type: Component,
@@ -25559,6 +26279,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
25559
26279
  MatSelectModule,
25560
26280
  MatIconModule,
25561
26281
  MatIconButton,
26282
+ MatSelectRequiredDirective,
25562
26283
  DisableControlDirective,
25563
26284
  FuncPipe
25564
26285
  ], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }], template: `
@@ -25779,7 +26500,7 @@ class MsaGenericFormTextFieldComponent extends MsaGenericFormFieldBaseComponent
25779
26500
  <mat-error>{{errorMessage}}</mat-error>
25780
26501
  }
25781
26502
  </mat-form-field>
25782
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: AutofocusDirective, selector: "[autoFocus]", inputs: ["focusDelay", "selectText", "autoFocus"] }, { kind: "directive", type: OnlyNumberDirective, selector: "[onlyNumber]", inputs: ["onlyNumber", "excludePrefix"] }, { kind: "directive", type: PrefixDirective, selector: "[prefix]", inputs: ["prefix"] }, { kind: "directive", type: ParseDecimalDirective, selector: "[parseDecimal]", inputs: ["parseDecimalEnabled"] }, { kind: "directive", type: RemoveWhitespaceDirective, selector: "[removeWhitespace]", inputs: ["removeWhitespace"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
26503
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i1$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatInputRequiredDirective, selector: "[matInput][formControl]:not([required]), [matInput][formControlName]:not([required])" }, { kind: "directive", type: AutofocusDirective, selector: "[autoFocus]", inputs: ["focusDelay", "selectText", "autoFocus"] }, { kind: "directive", type: OnlyNumberDirective, selector: "[onlyNumber]", inputs: ["onlyNumber", "excludePrefix"] }, { kind: "directive", type: PrefixDirective, selector: "[prefix]", inputs: ["prefix"] }, { kind: "directive", type: ParseDecimalDirective, selector: "[parseDecimal]", inputs: ["parseDecimalEnabled"] }, { kind: "directive", type: RemoveWhitespaceDirective, selector: "[removeWhitespace]", inputs: ["removeWhitespace"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
25783
26504
  }
25784
26505
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormTextFieldComponent, decorators: [{
25785
26506
  type: Component,
@@ -25790,6 +26511,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
25790
26511
  MatInputModule,
25791
26512
  MatIconModule,
25792
26513
  MatIconButton,
26514
+ MatInputRequiredDirective,
25793
26515
  AutofocusDirective,
25794
26516
  FuncPipe,
25795
26517
  OnlyNumberDirective,
@@ -25872,7 +26594,7 @@ class MsaGenericFormTextareaFieldComponent extends MsaGenericFormFieldBaseCompon
25872
26594
  <mat-error>{{errorMessage}}</mat-error>
25873
26595
  }
25874
26596
  </mat-form-field>
25875
- `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: PrefixDirective, selector: "[prefix]", inputs: ["prefix"] }, { kind: "directive", type: RemoveWhitespaceDirective, selector: "[removeWhitespace]", inputs: ["removeWhitespace"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
26597
+ `, isInline: true, styles: ["mat-form-field{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatInputRequiredDirective, selector: "[matInput][formControl]:not([required]), [matInput][formControlName]:not([required])" }, { kind: "directive", type: PrefixDirective, selector: "[prefix]", inputs: ["prefix"] }, { kind: "directive", type: RemoveWhitespaceDirective, selector: "[removeWhitespace]", inputs: ["removeWhitespace"] }, { kind: "pipe", type: FuncPipe, name: "func" }], viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }] });
25876
26598
  }
25877
26599
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MsaGenericFormTextareaFieldComponent, decorators: [{
25878
26600
  type: Component,
@@ -25883,6 +26605,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
25883
26605
  MatInputModule,
25884
26606
  MatIconModule,
25885
26607
  MatIconButton,
26608
+ MatInputRequiredDirective,
25886
26609
  FuncPipe,
25887
26610
  PrefixDirective,
25888
26611
  RemoveWhitespaceDirective
@@ -26424,7 +27147,7 @@ class VdGenericFormComponent {
26424
27147
  console.log(message, optionalParams);
26425
27148
  }
26426
27149
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: VdGenericFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
26427
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: VdGenericFormComponent, isStandalone: true, selector: "vd-generic-form", inputs: { formGroup: "formGroup", classType: "classType", formDefinition: "formDefinition", fieldGroups: "fieldGroups", groupName: "groupName", fieldSets: "fieldSets", context: "context", debugValue: "debugValue", readonly: "readonly", separatorKeysCodes: "separatorKeysCodes" }, outputs: { onInit: "init" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: VdEditorDirective, descendants: true }, { propertyName: "codeTemplate", first: true, predicate: VdCodeDirective, descendants: true }, { propertyName: "fileTemplate", first: true, predicate: VdFileDirective, descendants: true }, { propertyName: "customTemplate", first: true, predicate: VdCustomDirective, descendants: true }, { propertyName: "bottom", first: true, predicate: ["bottom"], descendants: true }, { propertyName: "customFields", first: true, predicate: ["customFields"], descendants: true }, { propertyName: "customFieldsTemplates", predicate: VdGenericFormCustomFieldDirective }], ngImport: i0, template: "@if (formGroup && fieldRows) {\n <div [formGroup]=\"formGroup!\">\n <!-- #region Fields -->\n @for (fields of fieldRows; track fields; let i = $index) {\n <div layout-gt-sm=\"row\" layout=\"column\">\n @for (field of fields; track field) {\n @if (!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))) {\n @switch (field.type) {\n <!-- #region Text input -->\n @case (FormFieldType.Text) {\n <msa-generic-form-text-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-text-field>\n }\n <!-- #endregion -->\n\n <!-- #region Textarea -->\n @case (FormFieldType.TextArea) {\n <msa-generic-form-textarea-field [field]=\"field\"\n [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-textarea-field>\n }\n <!-- #endregion -->\n\n <!-- #region Enum -->\n @case (FormFieldType.Enum) {\n <msa-generic-form-enum-field [field]=\"field\" [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-enum-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdSelect -->\n @case (FormFieldType.VdSelect) {\n <msa-generic-form-msa-select-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-msa-select-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdList -->\n @case (FormFieldType.VdList) {\n <msa-generic-form-msa-list-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-msa-list-field>\n }\n <!-- #endregion -->\n\n <!-- #region Chips -->\n @case (FormFieldType.Chips) {\n <msa-generic-form-chips-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [separatorKeysCodes]=\"separatorKeysCodes\"\n [autocompleteFilteredOptions]=\"autocompleteFilteredOptions\"\n [filterAutocomplete]=\"filterAutocomplete.bind(this)\"\n [autocompleteValueSelected]=\"autocompleteValueSelected.bind(this)\"\n [addChip]=\"addChip.bind(this)\"\n [onPasteChips]=\"onPasteChips.bind(this)\"\n [removeChip]=\"removeChip.bind(this)\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-chips-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdChips -->\n @case (FormFieldType.VdChips) {\n <msa-generic-form-msa-chips-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-msa-chips-field>\n }\n <!-- #endregion -->\n\n <!-- #region Select -->\n @case (FormFieldType.Select) {\n <msa-generic-form-select-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-select-field>\n }\n <!-- #endregion -->\n\n <!-- #region Autocomplete -->\n @case (FormFieldType.Autocomplete) {\n <msa-generic-form-autocomplete-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [autocompleteFilteredOptions]=\"autocompleteFilteredOptions\"\n [filterAutocomplete]=\"filterAutocomplete.bind(this)\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-autocomplete-field>\n }\n <!-- #endregion -->\n\n <!-- #region Date -->\n @case (FormFieldType.Date) {\n <msa-generic-form-date-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [datePickerHeaderComponent]=\"datePickerHeaderComponent\"\n [handleDatePickerFilterAsync]=\"handleDatePickerFilterAsync.bind(this)\"\n [handleDatePickerOpened]=\"handleDatePickerOpened.bind(this)\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-date-field>\n }\n <!-- #endregion -->\n\n <!-- #region Calendar -->\n @case (FormFieldType.Calendar) {\n <msa-generic-form-calendar-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [datePickerHeaderComponent]=\"datePickerHeaderComponent\"\n [handleCalendarFilterAsync]=\"handleCalendarFilterAsync.bind(this)\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-calendar-field>\n }\n <!-- #endregion -->\n\n <!-- #region Color input -->\n @case (FormFieldType.Color) {\n <msa-generic-form-color-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-color-field>\n }\n <!-- #endregion -->\n\n <!-- #region Checkbox -->\n @case (FormFieldType.Checkbox) {\n <msa-generic-form-checkbox-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\">\n </msa-generic-form-checkbox-field>\n }\n <!-- #endregion -->\n\n <!-- #region Radio -->\n @case(FormFieldType.Radio) {\n <msa-generic-form-radio-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-radio-field>\n }\n <!-- #endregion -->\n\n <!-- #region Editor -->\n @case (FormFieldType.Editor) {\n <msa-generic-form-editor-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [editorTemplate]=\"editorTemplate\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-editor-field>\n }\n <!-- #endregion -->\n\n <!-- #region Code -->\n @case (FormFieldType.Code) {\n <msa-generic-form-code-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [codeTemplate]=\"codeTemplate\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-code-field>\n }\n <!-- #endregion -->\n\n <!-- #region File -->\n @case (FormFieldType.File) {\n <msa-generic-form-file-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-file-field>\n }\n <!-- #endregion -->\n\n <!-- #region Custom -->\n @case (FormFieldType.Custom) {\n <msa-generic-form-custom-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [customTemplate]=\"customTemplate\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-custom-field>\n }\n <!-- #endregion -->\n }\n }\n }\n\n <!-- #region Template for custom fields -->\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == fields[0]?.row && customField.inline) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(customField?.templateRef)!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n </div>\n <!-- #region Template for custom fields -->\n @if (customFields) {\n <ng-container [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\n } @for (customField of customFieldsTemplates; track customField) {\n @if(customField?.templateRef && customField.row == ((($safeNavigationMigration(fields[0]?.row) | func:formValue:formGroup:context) ??0)+1) && !customField.inline) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(customField?.templateRef)!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n <!-- #endregion -->\n\n <!-- #region Form bottom -->\n @if (bottom) {\n <ng-container [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\n }\n <!-- #endregion -->\n\n <!-- #region Template for suffix buttons -->\n <ng-template #suffixButtons let-field>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n </ng-template>\n <!-- #endregion -->\n <!-- #region Debug value -->\n @if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n }\n <!-- #endregion -->\n </div>\n}", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mat-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .has-time input:first-child{width:84px;max-width:inherit;min-width:84px}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}.radio-form-field{width:100%}.radio-form-field ::ng-deep .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}.radio-form-field ::ng-deep .mat-mdc-floating-label{transform:translateY(-1.5em) scale(1)}.radio-form-field mat-radio-group{display:flex;flex-direction:row;gap:20px;padding-top:4px;margin-left:-12px}.radio-form-field .mat-mdc-form-field-infix{min-height:48px;display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type:
27150
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: VdGenericFormComponent, isStandalone: true, selector: "vd-generic-form", inputs: { formGroup: "formGroup", classType: "classType", formDefinition: "formDefinition", fieldGroups: "fieldGroups", groupName: "groupName", fieldSets: "fieldSets", context: "context", debugValue: "debugValue", readonly: "readonly", separatorKeysCodes: "separatorKeysCodes" }, outputs: { onInit: "init" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: VdEditorDirective, descendants: true }, { propertyName: "codeTemplate", first: true, predicate: VdCodeDirective, descendants: true }, { propertyName: "fileTemplate", first: true, predicate: VdFileDirective, descendants: true }, { propertyName: "customTemplate", first: true, predicate: VdCustomDirective, descendants: true }, { propertyName: "bottom", first: true, predicate: ["bottom"], descendants: true }, { propertyName: "customFields", first: true, predicate: ["customFields"], descendants: true }, { propertyName: "customFieldsTemplates", predicate: VdGenericFormCustomFieldDirective }], ngImport: i0, template: "@if (formGroup && fieldRows) {\n <div [formGroup]=\"formGroup!\">\n <!-- #region Fields -->\n @for (fields of fieldRows; track fields; let i = $index) {\n <div layout-gt-sm=\"row\" layout=\"column\">\n @for (field of fields; track field) {\n @if (!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))) {\n @switch (field.type) {\n <!-- #region Text input -->\n @case (FormFieldType.Text) {\n <msa-generic-form-text-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-text-field>\n }\n <!-- #endregion -->\n <!-- #region Textarea -->\n @case (FormFieldType.TextArea) {\n <msa-generic-form-textarea-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-textarea-field>\n }\n <!-- #endregion -->\n <!-- #region Enum -->\n @case (FormFieldType.Enum) {\n <msa-generic-form-enum-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-enum-field>\n }\n <!-- #endregion -->\n <!-- #region VdSelect -->\n @case (FormFieldType.VdSelect) {\n <msa-generic-form-msa-select-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-msa-select-field>\n }\n <!-- #endregion -->\n <!-- #region VdList -->\n @case (FormFieldType.VdList) {\n <msa-generic-form-msa-list-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-msa-list-field>\n }\n <!-- #endregion -->\n <!-- #region Chips -->\n @case (FormFieldType.Chips) {\n <msa-generic-form-chips-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [separatorKeysCodes]=\"separatorKeysCodes\" [autocompleteFilteredOptions]=\"autocompleteFilteredOptions\" [filterAutocomplete]=\"filterAutocomplete.bind(this)\" [autocompleteValueSelected]=\"autocompleteValueSelected.bind(this)\" [addChip]=\"addChip.bind(this)\" [onPasteChips]=\"onPasteChips.bind(this)\" [removeChip]=\"removeChip.bind(this)\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-chips-field>\n }\n <!-- #endregion -->\n <!-- #region VdChips -->\n @case (FormFieldType.VdChips) {\n <msa-generic-form-msa-chips-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-msa-chips-field>\n }\n <!-- #endregion -->\n <!-- #region Select -->\n @case (FormFieldType.Select) {\n <msa-generic-form-select-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-select-field>\n }\n <!-- #endregion -->\n <!-- #region Autocomplete -->\n @case (FormFieldType.Autocomplete) {\n <msa-generic-form-autocomplete-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [autocompleteFilteredOptions]=\"autocompleteFilteredOptions\" [filterAutocomplete]=\"filterAutocomplete.bind(this)\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-autocomplete-field>\n }\n <!-- #endregion -->\n <!-- #region Date -->\n @case (FormFieldType.Date) {\n <msa-generic-form-date-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [datePickerHeaderComponent]=\"datePickerHeaderComponent\" [handleDatePickerFilterAsync]=\"handleDatePickerFilterAsync.bind(this)\" [handleDatePickerOpened]=\"handleDatePickerOpened.bind(this)\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-date-field>\n }\n <!-- #endregion -->\n <!-- #region Calendar -->\n @case (FormFieldType.Calendar) {\n <msa-generic-form-calendar-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [datePickerHeaderComponent]=\"datePickerHeaderComponent\" [handleCalendarFilterAsync]=\"handleCalendarFilterAsync.bind(this)\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-calendar-field>\n }\n <!-- #endregion -->\n <!-- #region Color input -->\n @case (FormFieldType.Color) {\n <msa-generic-form-color-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-color-field>\n }\n <!-- #endregion -->\n <!-- #region Checkbox -->\n @case (FormFieldType.Checkbox) {\n <msa-generic-form-checkbox-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\">\n </msa-generic-form-checkbox-field>\n }\n <!-- #endregion -->\n <!-- #region Radio -->\n @case(FormFieldType.Radio) {\n <msa-generic-form-radio-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-radio-field>\n }\n <!-- #endregion -->\n <!-- #region Editor -->\n @case (FormFieldType.Editor) {\n <msa-generic-form-editor-field [field]=\"field\" [formGroup]=\"formGroup\" [editorTemplate]=\"editorTemplate\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-editor-field>\n }\n <!-- #endregion -->\n <!-- #region Code -->\n @case (FormFieldType.Code) {\n <msa-generic-form-code-field [field]=\"field\" [formGroup]=\"formGroup\" [codeTemplate]=\"codeTemplate\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-code-field>\n }\n <!-- #endregion -->\n <!-- #region File -->\n @case (FormFieldType.File) {\n <msa-generic-form-file-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-file-field>\n }\n <!-- #endregion -->\n <!-- #region Custom -->\n @case (FormFieldType.Custom) {\n <msa-generic-form-custom-field [field]=\"field\" [formGroup]=\"formGroup\" [customTemplate]=\"customTemplate\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-custom-field>\n }\n <!-- #endregion -->\n }\n }\n }\n <!-- #region Template for custom fields -->\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == fields[0]?.row && customField.inline) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(customField?.templateRef)!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n </div>\n <!-- #region Template for custom fields -->\n @if (customFields) {\n <ng-container [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\n } @for (customField of customFieldsTemplates; track customField) {\n @if(customField?.templateRef && customField.row == ((($safeNavigationMigration(fields[0]?.row) | func:formValue:formGroup:context) ??0)+1) && !customField.inline) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(customField?.templateRef)!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n <!-- #endregion -->\n <!-- #region Form bottom -->\n @if (bottom) {\n <ng-container [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\n }\n <!-- #endregion -->\n <!-- #region Template for suffix buttons -->\n <ng-template #suffixButtons let-field>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n </ng-template>\n <!-- #endregion -->\n <!-- #region Debug value -->\n @if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n }\n <!-- #endregion -->\n </div>\n}", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mat-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .has-time input:first-child{width:84px;max-width:inherit;min-width:84px}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}.radio-form-field{width:100%}.radio-form-field ::ng-deep .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}.radio-form-field ::ng-deep .mat-mdc-floating-label{transform:translateY(-1.5em) scale(1)}.radio-form-field mat-radio-group{display:flex;flex-direction:row;gap:20px;padding-top:4px;margin-left:-12px}.radio-form-field .mat-mdc-form-field-infix{min-height:48px;display:flex;align-items:center}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type:
26428
27151
  //--------------------
26429
27152
  MatAutocompleteModule }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "ngmodule", type: MatRadioModule }, { kind: "ngmodule", type:
26430
27153
  //--------------------
@@ -26474,7 +27197,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
26474
27197
  MsaGenericFormMsaSelectFieldComponent,
26475
27198
  MsaGenericFormMsaChipsFieldComponent,
26476
27199
  MsaGenericFormMsaListFieldComponent
26477
- ], template: "@if (formGroup && fieldRows) {\n <div [formGroup]=\"formGroup!\">\n <!-- #region Fields -->\n @for (fields of fieldRows; track fields; let i = $index) {\n <div layout-gt-sm=\"row\" layout=\"column\">\n @for (field of fields; track field) {\n @if (!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))) {\n @switch (field.type) {\n <!-- #region Text input -->\n @case (FormFieldType.Text) {\n <msa-generic-form-text-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-text-field>\n }\n <!-- #endregion -->\n\n <!-- #region Textarea -->\n @case (FormFieldType.TextArea) {\n <msa-generic-form-textarea-field [field]=\"field\"\n [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-textarea-field>\n }\n <!-- #endregion -->\n\n <!-- #region Enum -->\n @case (FormFieldType.Enum) {\n <msa-generic-form-enum-field [field]=\"field\" [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-enum-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdSelect -->\n @case (FormFieldType.VdSelect) {\n <msa-generic-form-msa-select-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-msa-select-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdList -->\n @case (FormFieldType.VdList) {\n <msa-generic-form-msa-list-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-msa-list-field>\n }\n <!-- #endregion -->\n\n <!-- #region Chips -->\n @case (FormFieldType.Chips) {\n <msa-generic-form-chips-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [separatorKeysCodes]=\"separatorKeysCodes\"\n [autocompleteFilteredOptions]=\"autocompleteFilteredOptions\"\n [filterAutocomplete]=\"filterAutocomplete.bind(this)\"\n [autocompleteValueSelected]=\"autocompleteValueSelected.bind(this)\"\n [addChip]=\"addChip.bind(this)\"\n [onPasteChips]=\"onPasteChips.bind(this)\"\n [removeChip]=\"removeChip.bind(this)\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-chips-field>\n }\n <!-- #endregion -->\n\n <!-- #region VdChips -->\n @case (FormFieldType.VdChips) {\n <msa-generic-form-msa-chips-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-msa-chips-field>\n }\n <!-- #endregion -->\n\n <!-- #region Select -->\n @case (FormFieldType.Select) {\n <msa-generic-form-select-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-select-field>\n }\n <!-- #endregion -->\n\n <!-- #region Autocomplete -->\n @case (FormFieldType.Autocomplete) {\n <msa-generic-form-autocomplete-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [autocompleteFilteredOptions]=\"autocompleteFilteredOptions\"\n [filterAutocomplete]=\"filterAutocomplete.bind(this)\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-autocomplete-field>\n }\n <!-- #endregion -->\n\n <!-- #region Date -->\n @case (FormFieldType.Date) {\n <msa-generic-form-date-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [datePickerHeaderComponent]=\"datePickerHeaderComponent\"\n [handleDatePickerFilterAsync]=\"handleDatePickerFilterAsync.bind(this)\"\n [handleDatePickerOpened]=\"handleDatePickerOpened.bind(this)\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-date-field>\n }\n <!-- #endregion -->\n\n <!-- #region Calendar -->\n @case (FormFieldType.Calendar) {\n <msa-generic-form-calendar-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [datePickerHeaderComponent]=\"datePickerHeaderComponent\"\n [handleCalendarFilterAsync]=\"handleCalendarFilterAsync.bind(this)\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-calendar-field>\n }\n <!-- #endregion -->\n\n <!-- #region Color input -->\n @case (FormFieldType.Color) {\n <msa-generic-form-color-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-color-field>\n }\n <!-- #endregion -->\n\n <!-- #region Checkbox -->\n @case (FormFieldType.Checkbox) {\n <msa-generic-form-checkbox-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\">\n </msa-generic-form-checkbox-field>\n }\n <!-- #endregion -->\n\n <!-- #region Radio -->\n @case(FormFieldType.Radio) {\n <msa-generic-form-radio-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-radio-field>\n }\n <!-- #endregion -->\n\n <!-- #region Editor -->\n @case (FormFieldType.Editor) {\n <msa-generic-form-editor-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [editorTemplate]=\"editorTemplate\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-editor-field>\n }\n <!-- #endregion -->\n\n <!-- #region Code -->\n @case (FormFieldType.Code) {\n <msa-generic-form-code-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [codeTemplate]=\"codeTemplate\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-code-field>\n }\n <!-- #endregion -->\n\n <!-- #region File -->\n @case (FormFieldType.File) {\n <msa-generic-form-file-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [readonly]=\"readonly ?? false\"\n [context]=\"context\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-file-field>\n }\n <!-- #endregion -->\n\n <!-- #region Custom -->\n @case (FormFieldType.Custom) {\n <msa-generic-form-custom-field [field]=\"field\"\n [formGroup]=\"formGroup\"\n [customTemplate]=\"customTemplate\"\n [attr.flex]=\"field.flex||0\"\n layout-margin>\n </msa-generic-form-custom-field>\n }\n <!-- #endregion -->\n }\n }\n }\n\n <!-- #region Template for custom fields -->\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == fields[0]?.row && customField.inline) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(customField?.templateRef)!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n </div>\n <!-- #region Template for custom fields -->\n @if (customFields) {\n <ng-container [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\n } @for (customField of customFieldsTemplates; track customField) {\n @if(customField?.templateRef && customField.row == ((($safeNavigationMigration(fields[0]?.row) | func:formValue:formGroup:context) ??0)+1) && !customField.inline) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(customField?.templateRef)!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n <!-- #endregion -->\n\n <!-- #region Form bottom -->\n @if (bottom) {\n <ng-container [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\n }\n <!-- #endregion -->\n\n <!-- #region Template for suffix buttons -->\n <ng-template #suffixButtons let-field>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\"\n mat-icon-button\n (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n </ng-template>\n <!-- #endregion -->\n <!-- #region Debug value -->\n @if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n }\n <!-- #endregion -->\n </div>\n}", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mat-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .has-time input:first-child{width:84px;max-width:inherit;min-width:84px}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}.radio-form-field{width:100%}.radio-form-field ::ng-deep .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}.radio-form-field ::ng-deep .mat-mdc-floating-label{transform:translateY(-1.5em) scale(1)}.radio-form-field mat-radio-group{display:flex;flex-direction:row;gap:20px;padding-top:4px;margin-left:-12px}.radio-form-field .mat-mdc-form-field-infix{min-height:48px;display:flex;align-items:center}\n"] }]
27200
+ ], template: "@if (formGroup && fieldRows) {\n <div [formGroup]=\"formGroup!\">\n <!-- #region Fields -->\n @for (fields of fieldRows; track fields; let i = $index) {\n <div layout-gt-sm=\"row\" layout=\"column\">\n @for (field of fields; track field) {\n @if (!field.hidden && !(field.hide && field.hide(formValue, formGroup, context))) {\n @switch (field.type) {\n <!-- #region Text input -->\n @case (FormFieldType.Text) {\n <msa-generic-form-text-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-text-field>\n }\n <!-- #endregion -->\n <!-- #region Textarea -->\n @case (FormFieldType.TextArea) {\n <msa-generic-form-textarea-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-textarea-field>\n }\n <!-- #endregion -->\n <!-- #region Enum -->\n @case (FormFieldType.Enum) {\n <msa-generic-form-enum-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-enum-field>\n }\n <!-- #endregion -->\n <!-- #region VdSelect -->\n @case (FormFieldType.VdSelect) {\n <msa-generic-form-msa-select-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-msa-select-field>\n }\n <!-- #endregion -->\n <!-- #region VdList -->\n @case (FormFieldType.VdList) {\n <msa-generic-form-msa-list-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-msa-list-field>\n }\n <!-- #endregion -->\n <!-- #region Chips -->\n @case (FormFieldType.Chips) {\n <msa-generic-form-chips-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [separatorKeysCodes]=\"separatorKeysCodes\" [autocompleteFilteredOptions]=\"autocompleteFilteredOptions\" [filterAutocomplete]=\"filterAutocomplete.bind(this)\" [autocompleteValueSelected]=\"autocompleteValueSelected.bind(this)\" [addChip]=\"addChip.bind(this)\" [onPasteChips]=\"onPasteChips.bind(this)\" [removeChip]=\"removeChip.bind(this)\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-chips-field>\n }\n <!-- #endregion -->\n <!-- #region VdChips -->\n @case (FormFieldType.VdChips) {\n <msa-generic-form-msa-chips-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-msa-chips-field>\n }\n <!-- #endregion -->\n <!-- #region Select -->\n @case (FormFieldType.Select) {\n <msa-generic-form-select-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-select-field>\n }\n <!-- #endregion -->\n <!-- #region Autocomplete -->\n @case (FormFieldType.Autocomplete) {\n <msa-generic-form-autocomplete-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [autocompleteFilteredOptions]=\"autocompleteFilteredOptions\" [filterAutocomplete]=\"filterAutocomplete.bind(this)\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-autocomplete-field>\n }\n <!-- #endregion -->\n <!-- #region Date -->\n @case (FormFieldType.Date) {\n <msa-generic-form-date-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [datePickerHeaderComponent]=\"datePickerHeaderComponent\" [handleDatePickerFilterAsync]=\"handleDatePickerFilterAsync.bind(this)\" [handleDatePickerOpened]=\"handleDatePickerOpened.bind(this)\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-date-field>\n }\n <!-- #endregion -->\n <!-- #region Calendar -->\n @case (FormFieldType.Calendar) {\n <msa-generic-form-calendar-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [datePickerHeaderComponent]=\"datePickerHeaderComponent\" [handleCalendarFilterAsync]=\"handleCalendarFilterAsync.bind(this)\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-calendar-field>\n }\n <!-- #endregion -->\n <!-- #region Color input -->\n @case (FormFieldType.Color) {\n <msa-generic-form-color-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-color-field>\n }\n <!-- #endregion -->\n <!-- #region Checkbox -->\n @case (FormFieldType.Checkbox) {\n <msa-generic-form-checkbox-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\">\n </msa-generic-form-checkbox-field>\n }\n <!-- #endregion -->\n <!-- #region Radio -->\n @case(FormFieldType.Radio) {\n <msa-generic-form-radio-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-radio-field>\n }\n <!-- #endregion -->\n <!-- #region Editor -->\n @case (FormFieldType.Editor) {\n <msa-generic-form-editor-field [field]=\"field\" [formGroup]=\"formGroup\" [editorTemplate]=\"editorTemplate\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-editor-field>\n }\n <!-- #endregion -->\n <!-- #region Code -->\n @case (FormFieldType.Code) {\n <msa-generic-form-code-field [field]=\"field\" [formGroup]=\"formGroup\" [codeTemplate]=\"codeTemplate\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-code-field>\n }\n <!-- #endregion -->\n <!-- #region File -->\n @case (FormFieldType.File) {\n <msa-generic-form-file-field [field]=\"field\" [formGroup]=\"formGroup\" [readonly]=\"readonly ?? false\" [context]=\"context\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-file-field>\n }\n <!-- #endregion -->\n <!-- #region Custom -->\n @case (FormFieldType.Custom) {\n <msa-generic-form-custom-field [field]=\"field\" [formGroup]=\"formGroup\" [customTemplate]=\"customTemplate\" [attr.flex]=\"field.flex||0\" [attr.data-row]=\"field.row\" layout-margin>\n </msa-generic-form-custom-field>\n }\n <!-- #endregion -->\n }\n }\n }\n <!-- #region Template for custom fields -->\n @for (customField of customFieldsTemplates; track customField) {\n @if (customField?.templateRef && customField.row == fields[0]?.row && customField.inline) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(customField?.templateRef)!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n </div>\n <!-- #region Template for custom fields -->\n @if (customFields) {\n <ng-container [ngTemplateOutlet]=\"customFields\" [ngTemplateOutletContext]=\"{formGroup: formGroup, row: fields[0].row}\"></ng-container>\n } @for (customField of customFieldsTemplates; track customField) {\n @if(customField?.templateRef && customField.row == ((($safeNavigationMigration(fields[0]?.row) | func:formValue:formGroup:context) ??0)+1) && !customField.inline) {\n <ng-template [ngTemplateOutlet]=\"$safeNavigationMigration(customField?.templateRef)!\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-template>\n }\n }\n <!-- #endregion -->\n }\n <!-- #endregion -->\n <!-- #region Form bottom -->\n @if (bottom) {\n <ng-container [ngTemplateOutlet]=\"bottom\" [ngTemplateOutletContext]=\"{formGroup: formGroup}\"></ng-container>\n }\n <!-- #endregion -->\n <!-- #region Template for suffix buttons -->\n <ng-template #suffixButtons let-field>\n @for (suffixButton of field.suffixButtons; track suffixButton) {\n <ng-container matSuffix>\n @if (!suffixButton.hide || !suffixButton.hide(formValue, context)) {\n <button type=\"button\" mat-icon-button (click)=\"suffixButton.event && suffixButton.event(formValue, context)\">\n <mat-icon fontSet=\"material-symbols-outlined\">{{suffixButton.icon}}</mat-icon>\n </button>\n }\n </ng-container>\n }\n </ng-template>\n <!-- #endregion -->\n <!-- #region Debug value -->\n @if (debugValue) {\n <code>\n <pre>{{formValue | json}}</pre>\n </code>\n }\n <!-- #endregion -->\n </div>\n}", styles: [".mat-checkbox-wrap mat-error{transform:translate(36px,-20px);max-width:93%;font-size:var(--mat-typography-caption-font-size, 12px)}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-form-field-icon-suffix .color-picker{width:40px;display:block}::ng-deep .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .has-time input:first-child{width:84px;max-width:inherit;min-width:84px}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-form-field-infix{padding-top:7px!important;padding-bottom:7px!important}::ng-deep .mat-mdc-form-field-type-mat-chip-grid .mat-mdc-chip{padding-top:0!important;padding-bottom:0!important;margin-top:2px!important;margin-bottom:2px!important;margin-left:4px!important}.radio-form-field{width:100%}.radio-form-field ::ng-deep .mat-mdc-form-field-infix{padding-top:0!important;padding-bottom:0!important}.radio-form-field ::ng-deep .mat-mdc-floating-label{transform:translateY(-1.5em) scale(1)}.radio-form-field mat-radio-group{display:flex;flex-direction:row;gap:20px;padding-top:4px;margin-left:-12px}.radio-form-field .mat-mdc-form-field-infix{min-height:48px;display:flex;align-items:center}\n"] }]
26478
27201
  }], propDecorators: { formGroup: [{
26479
27202
  type: Input
26480
27203
  }], classType: [{
@@ -26922,9 +27645,6 @@ function FormField(args) {
26922
27645
  return function (target, propertyKey) {
26923
27646
  /* Get property name */
26924
27647
  var propertyName = args.name || propertyKey;
26925
- /* Get property type */
26926
- var propertyType = Reflect.getMetadata("design:type", target, propertyKey)?.name;
26927
- console.log('propertyType', Reflect.getMetadata("design:type", target, propertyKey));
26928
27648
  /* Get old form fields */
26929
27649
  let previousFormFields = Reflect.getMetadata(formFieldsMetadataKey, target);
26930
27650
  /* Override the field with the args, if exists */
@@ -27581,6 +28301,42 @@ var MenuScope;
27581
28301
  MenuScope[MenuScope["Admin"] = 1] = "Admin";
27582
28302
  })(MenuScope || (MenuScope = {}));
27583
28303
 
28304
+ /**
28305
+ * Class decorator to define a table with its configuration.
28306
+ * @param tableDefinition Optional partial table definition to customize the table's behavior and appearance.
28307
+ * @returns A function that takes the target class and applies the table definition metadata.
28308
+ */
28309
+ function Table(tableDefinition) {
28310
+ return function (target) {
28311
+ if (tableDefinition?.columns) {
28312
+ /* Add action menus from table definition, if any */
28313
+ var actionColmun = tableDefinition.columns?.find(x => x.name == 'action');
28314
+ if (!actionColmun) {
28315
+ actionColmun = new TableColumn({
28316
+ index: 2000,
28317
+ name: 'action',
28318
+ columnSets: ['action', 'common'],
28319
+ type: TableColumnType.Action,
28320
+ disabled: true,
28321
+ rowMenuItems: actions,
28322
+ configurable: false,
28323
+ stickyEnd: true
28324
+ });
28325
+ /* Add the action column into the table columns */
28326
+ tableDefinition.columns.push(actionColmun);
28327
+ }
28328
+ /* Get custom action, if any */
28329
+ var actions = tableDefinition?.actions;
28330
+ if (actions != null && actionColmun != null) {
28331
+ actionColmun.rowMenuItems ??= [];
28332
+ actions.forEach(y => actionColmun.rowMenuItems.push(y));
28333
+ }
28334
+ }
28335
+ /* Save the table defintion in the metadata */
28336
+ Reflect.defineMetadata(TABLE_DEFINITION_METADATA_KEY, tableDefinition, target);
28337
+ };
28338
+ }
28339
+
27584
28340
  /**
27585
28341
  * @class
27586
28342
  */
@@ -30140,7 +30896,7 @@ class VdNavigationDrawerComponent {
30140
30896
  }
30141
30897
  }
30142
30898
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: VdNavigationDrawerComponent, deps: [{ token: forwardRef(() => VdLayoutComponent) }, { token: i1$6.Router, optional: true }, { token: i1$3.DomSanitizer }, { token: VdMediaService }], target: i0.ɵɵFactoryTarget.Component });
30143
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: VdNavigationDrawerComponent, isStandalone: true, selector: "vd-navigation-drawer", inputs: { sidenavTitle: "sidenavTitle", icon: "icon", logo: "logo", avatar: "avatar", color: "color", navigationRoute: "navigationRoute", backgroundUrl: "backgroundUrl", sideGt: "sideGt", name: "name", email: "email" }, queries: [{ propertyName: "_drawerMenu", predicate: VdNavigationDrawerMenuDirective, descendants: true }, { propertyName: "_toolbar", predicate: VdNavigationDrawerToolbarDirective, descendants: true }], ngImport: i0, template: "<mat-toolbar [color]=\"color\" [style.background-image]=\"backgroundImage\" [class.vd-toolbar-background]=\"!!isBackgroundAvailable\" class=\"vd-nagivation-drawer-toolbar\" [ngClass]=\"{'drawer-mini': mini && !expanded}\" dense flex layout=\"column\">\r\n <ng-content select=\"[vd-navigation-drawer-toolbar]\"></ng-content>\r\n @if (!isCustomToolbar && !mini) {\r\n @if (email && name) {\r\n <div class=\"vd-navigation-drawer-name\">{{name}}</div>\r\n }\r\n @if (email || name) {\r\n <div class=\"vd-navigation-drawer-menu-toggle\" href (click)=\"toggleMenu()\">\r\n <span class=\"vd-navigation-drawer-label\">{{ email || name }}</span>\r\n @if (isMenuAvailable) {\r\n <button mat-icon-button class=\"vd-navigation-drawer-menu-button\">\r\n @if (!menuToggled) {\r\n <mat-icon>arrow_drop_down</mat-icon>\r\n }\r\n @if (menuToggled) {\r\n <mat-icon>arrow_drop_up</mat-icon>\r\n }\r\n </button>\r\n }\r\n </div>\r\n }\r\n }\r\n @if (mini && !expanded) {\r\n <div layout=\"column\" layout-align=\"center center\" flex>\r\n <button mat-icon-button (click)=\"toggleMenu()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">format_list_bulleted</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n</mat-toolbar>\r\n\r\n<!-- Main Content: Expands when menu is NOT toggled -->\r\n<div class=\"vd-navigation-drawer-content scrollbar-primary vd-collapse-container\"\r\n [class.is-expanded]=\"!menuToggled\"\r\n [ngClass]=\"{'drawer-mini': mini}\">\r\n <div class=\"vd-collapse-inner\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n\r\n<!-- Menu Content: Expands when menu IS toggled -->\r\n<div class=\"vd-navigation-drawer-menu-content vd-collapse-container\"\r\n [class.is-expanded]=\"menuToggled\"\r\n [ngClass]=\"{'drawer-mini': mini}\">\r\n <div class=\"vd-collapse-inner\">\r\n <ng-content select=\"[vd-navigation-drawer-menu]\"></ng-content>\r\n </div>\r\n</div>", styles: [":host{width:100%}:host .vd-collapse-container{display:grid;grid-template-rows:0fr;transition:grid-template-rows .15s ease-in-out}:host .vd-collapse-container.is-expanded{grid-template-rows:1fr}:host .vd-collapse-inner{min-height:0;overflow:hidden}:host .vd-navigation-drawer-content.ng-animating,:host .vd-navigation-drawer-menu-content.ng-animating{overflow:hidden}:host .vd-navigation-drawer-content ::ng-deep .mat-mdc-nav-list,:host .vd-navigation-drawer-menu-content ::ng-deep .mat-mdc-nav-list{padding-top:0!important;padding-bottom:12px}:host .vd-navigation-drawer-content.drawer-mini ::ng-deep .mat-mdc-nav-list,:host .vd-navigation-drawer-menu-content.drawer-mini ::ng-deep .mat-mdc-nav-list{padding-bottom:0!important}:host mat-toolbar:not(.drawer-mini){padding:16px}:host mat-toolbar.drawer-mini{padding:0!important}:host mat-toolbar.vd-nagivation-drawer-toolbar{flex-direction:column;align-items:stretch}:host mat-toolbar.vd-toolbar-background{background-repeat:no-repeat;background-size:cover}:host mat-toolbar.vd-nagivation-drawer-toolbar:not(.drawer-mini){flex-direction:column;height:auto!important;display:block!important}:host mat-toolbar .vd-navigation-drawer-toolbar-content{flex-direction:row;box-sizing:border-box;display:flex;align-items:center;align-content:center;max-width:100%;justify-content:flex-start}:host mat-toolbar .vd-navigation-drawer-toolbar-content .vd-nagivation-drawer-toolbar-avatar{border-radius:50%;height:60px;width:60px;margin:0 12px 12px 0}:host mat-toolbar .vd-navigation-drawer-toolbar-content .vd-navigation-drawer-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-menu-toggle{flex-direction:row;box-sizing:border-box;display:flex;cursor:pointer}:host mat-toolbar .vd-navigation-drawer-menu-toggle .vd-navigation-drawer-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-menu-toggle .vd-navigation-drawer-menu-button{height:24px;line-height:24px;width:24px;padding:0!important}:host>div{overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i4$5.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30899
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: VdNavigationDrawerComponent, isStandalone: true, selector: "vd-navigation-drawer", inputs: { sidenavTitle: "sidenavTitle", icon: "icon", logo: "logo", avatar: "avatar", color: "color", navigationRoute: "navigationRoute", backgroundUrl: "backgroundUrl", sideGt: "sideGt", name: "name", email: "email" }, queries: [{ propertyName: "_drawerMenu", predicate: VdNavigationDrawerMenuDirective, descendants: true }, { propertyName: "_toolbar", predicate: VdNavigationDrawerToolbarDirective, descendants: true }], ngImport: i0, template: "<mat-toolbar [color]=\"color\" [style.background-image]=\"backgroundImage\" [class.vd-toolbar-background]=\"!!isBackgroundAvailable\" class=\"vd-nagivation-drawer-toolbar\" [ngClass]=\"{'drawer-mini': mini && !expanded}\" dense flex layout=\"column\">\r\n <ng-content select=\"[vd-navigation-drawer-toolbar]\"></ng-content>\r\n @if (!isCustomToolbar && !mini) {\r\n @if (email && name) {\r\n <div class=\"vd-navigation-drawer-name\">{{name}}</div>\r\n }\r\n @if (email || name) {\r\n <div class=\"vd-navigation-drawer-menu-toggle\" href (click)=\"toggleMenu()\">\r\n <span class=\"vd-navigation-drawer-label\">{{ email || name }}</span>\r\n @if (isMenuAvailable) {\r\n <button mat-icon-button class=\"vd-navigation-drawer-menu-button\">\r\n @if (!menuToggled) {\r\n <mat-icon>arrow_drop_down</mat-icon>\r\n }\r\n @if (menuToggled) {\r\n <mat-icon>arrow_drop_up</mat-icon>\r\n }\r\n </button>\r\n }\r\n </div>\r\n }\r\n }\r\n @if (mini && !expanded) {\r\n <div layout=\"column\" layout-align=\"center center\" flex>\r\n <button mat-icon-button (click)=\"toggleMenu()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">format_list_bulleted</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n</mat-toolbar>\r\n<!-- Main Content: Expands when menu is NOT toggled -->\r\n<div class=\"vd-navigation-drawer-content scrollbar-primary vd-collapse-container\" [class.is-expanded]=\"!menuToggled\" [ngClass]=\"{'drawer-mini': mini}\">\r\n <div class=\"vd-collapse-inner\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n<!-- Menu Content: Expands when menu IS toggled -->\r\n<div class=\"vd-navigation-drawer-menu-content vd-collapse-container\" [class.is-expanded]=\"menuToggled\" [ngClass]=\"{'drawer-mini': mini}\">\r\n <div class=\"vd-collapse-inner\">\r\n <ng-content select=\"[vd-navigation-drawer-menu]\"></ng-content>\r\n </div>\r\n</div>", styles: [":host{width:100%}:host .vd-collapse-container{grid-template-rows:0fr;height:0%;transition:grid-template-rows .15s ease-in-out}:host .vd-collapse-container.is-expanded{grid-template-rows:1fr;height:calc(100% - 58px)}:host .vd-collapse-inner{min-height:0;overflow:hidden}:host .vd-navigation-drawer-content.ng-animating,:host .vd-navigation-drawer-menu-content.ng-animating{overflow:hidden}:host .vd-navigation-drawer-content ::ng-deep .mat-mdc-nav-list,:host .vd-navigation-drawer-menu-content ::ng-deep .mat-mdc-nav-list{padding-top:0!important;padding-bottom:12px}:host .vd-navigation-drawer-content.drawer-mini ::ng-deep .mat-mdc-nav-list,:host .vd-navigation-drawer-menu-content.drawer-mini ::ng-deep .mat-mdc-nav-list{padding-bottom:0!important}:host mat-toolbar:not(.drawer-mini){padding:16px}:host mat-toolbar.drawer-mini{padding:0!important}:host mat-toolbar.vd-nagivation-drawer-toolbar{flex-direction:column;align-items:stretch}:host mat-toolbar.vd-toolbar-background{background-repeat:no-repeat;background-size:cover}:host mat-toolbar.vd-nagivation-drawer-toolbar:not(.drawer-mini){flex-direction:column;height:auto!important;display:block!important}:host mat-toolbar .vd-navigation-drawer-toolbar-content{flex-direction:row;box-sizing:border-box;display:flex;align-items:center;align-content:center;max-width:100%;justify-content:flex-start}:host mat-toolbar .vd-navigation-drawer-toolbar-content .vd-nagivation-drawer-toolbar-avatar{border-radius:50%;height:60px;width:60px;margin:0 12px 12px 0}:host mat-toolbar .vd-navigation-drawer-toolbar-content .vd-navigation-drawer-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-menu-toggle{flex-direction:row;box-sizing:border-box;display:flex;cursor:pointer}:host mat-toolbar .vd-navigation-drawer-menu-toggle .vd-navigation-drawer-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-menu-toggle .vd-navigation-drawer-menu-button{height:24px;line-height:24px;width:24px;padding:0!important}:host>div{overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i4$5.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }], changeDetection: i0.ChangeDetectionStrategy.Eager });
30144
30900
  }
30145
30901
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: VdNavigationDrawerComponent, decorators: [{
30146
30902
  type: Component,
@@ -30149,7 +30905,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
30149
30905
  MatToolbarModule,
30150
30906
  MatIcon,
30151
30907
  MatIconButton
30152
- ], template: "<mat-toolbar [color]=\"color\" [style.background-image]=\"backgroundImage\" [class.vd-toolbar-background]=\"!!isBackgroundAvailable\" class=\"vd-nagivation-drawer-toolbar\" [ngClass]=\"{'drawer-mini': mini && !expanded}\" dense flex layout=\"column\">\r\n <ng-content select=\"[vd-navigation-drawer-toolbar]\"></ng-content>\r\n @if (!isCustomToolbar && !mini) {\r\n @if (email && name) {\r\n <div class=\"vd-navigation-drawer-name\">{{name}}</div>\r\n }\r\n @if (email || name) {\r\n <div class=\"vd-navigation-drawer-menu-toggle\" href (click)=\"toggleMenu()\">\r\n <span class=\"vd-navigation-drawer-label\">{{ email || name }}</span>\r\n @if (isMenuAvailable) {\r\n <button mat-icon-button class=\"vd-navigation-drawer-menu-button\">\r\n @if (!menuToggled) {\r\n <mat-icon>arrow_drop_down</mat-icon>\r\n }\r\n @if (menuToggled) {\r\n <mat-icon>arrow_drop_up</mat-icon>\r\n }\r\n </button>\r\n }\r\n </div>\r\n }\r\n }\r\n @if (mini && !expanded) {\r\n <div layout=\"column\" layout-align=\"center center\" flex>\r\n <button mat-icon-button (click)=\"toggleMenu()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">format_list_bulleted</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n</mat-toolbar>\r\n\r\n<!-- Main Content: Expands when menu is NOT toggled -->\r\n<div class=\"vd-navigation-drawer-content scrollbar-primary vd-collapse-container\"\r\n [class.is-expanded]=\"!menuToggled\"\r\n [ngClass]=\"{'drawer-mini': mini}\">\r\n <div class=\"vd-collapse-inner\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n\r\n<!-- Menu Content: Expands when menu IS toggled -->\r\n<div class=\"vd-navigation-drawer-menu-content vd-collapse-container\"\r\n [class.is-expanded]=\"menuToggled\"\r\n [ngClass]=\"{'drawer-mini': mini}\">\r\n <div class=\"vd-collapse-inner\">\r\n <ng-content select=\"[vd-navigation-drawer-menu]\"></ng-content>\r\n </div>\r\n</div>", styles: [":host{width:100%}:host .vd-collapse-container{display:grid;grid-template-rows:0fr;transition:grid-template-rows .15s ease-in-out}:host .vd-collapse-container.is-expanded{grid-template-rows:1fr}:host .vd-collapse-inner{min-height:0;overflow:hidden}:host .vd-navigation-drawer-content.ng-animating,:host .vd-navigation-drawer-menu-content.ng-animating{overflow:hidden}:host .vd-navigation-drawer-content ::ng-deep .mat-mdc-nav-list,:host .vd-navigation-drawer-menu-content ::ng-deep .mat-mdc-nav-list{padding-top:0!important;padding-bottom:12px}:host .vd-navigation-drawer-content.drawer-mini ::ng-deep .mat-mdc-nav-list,:host .vd-navigation-drawer-menu-content.drawer-mini ::ng-deep .mat-mdc-nav-list{padding-bottom:0!important}:host mat-toolbar:not(.drawer-mini){padding:16px}:host mat-toolbar.drawer-mini{padding:0!important}:host mat-toolbar.vd-nagivation-drawer-toolbar{flex-direction:column;align-items:stretch}:host mat-toolbar.vd-toolbar-background{background-repeat:no-repeat;background-size:cover}:host mat-toolbar.vd-nagivation-drawer-toolbar:not(.drawer-mini){flex-direction:column;height:auto!important;display:block!important}:host mat-toolbar .vd-navigation-drawer-toolbar-content{flex-direction:row;box-sizing:border-box;display:flex;align-items:center;align-content:center;max-width:100%;justify-content:flex-start}:host mat-toolbar .vd-navigation-drawer-toolbar-content .vd-nagivation-drawer-toolbar-avatar{border-radius:50%;height:60px;width:60px;margin:0 12px 12px 0}:host mat-toolbar .vd-navigation-drawer-toolbar-content .vd-navigation-drawer-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-menu-toggle{flex-direction:row;box-sizing:border-box;display:flex;cursor:pointer}:host mat-toolbar .vd-navigation-drawer-menu-toggle .vd-navigation-drawer-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-menu-toggle .vd-navigation-drawer-menu-button{height:24px;line-height:24px;width:24px;padding:0!important}:host>div{overflow:hidden}\n"] }]
30908
+ ], template: "<mat-toolbar [color]=\"color\" [style.background-image]=\"backgroundImage\" [class.vd-toolbar-background]=\"!!isBackgroundAvailable\" class=\"vd-nagivation-drawer-toolbar\" [ngClass]=\"{'drawer-mini': mini && !expanded}\" dense flex layout=\"column\">\r\n <ng-content select=\"[vd-navigation-drawer-toolbar]\"></ng-content>\r\n @if (!isCustomToolbar && !mini) {\r\n @if (email && name) {\r\n <div class=\"vd-navigation-drawer-name\">{{name}}</div>\r\n }\r\n @if (email || name) {\r\n <div class=\"vd-navigation-drawer-menu-toggle\" href (click)=\"toggleMenu()\">\r\n <span class=\"vd-navigation-drawer-label\">{{ email || name }}</span>\r\n @if (isMenuAvailable) {\r\n <button mat-icon-button class=\"vd-navigation-drawer-menu-button\">\r\n @if (!menuToggled) {\r\n <mat-icon>arrow_drop_down</mat-icon>\r\n }\r\n @if (menuToggled) {\r\n <mat-icon>arrow_drop_up</mat-icon>\r\n }\r\n </button>\r\n }\r\n </div>\r\n }\r\n }\r\n @if (mini && !expanded) {\r\n <div layout=\"column\" layout-align=\"center center\" flex>\r\n <button mat-icon-button (click)=\"toggleMenu()\">\r\n <mat-icon fontSet=\"material-symbols-outlined\">format_list_bulleted</mat-icon>\r\n </button>\r\n </div>\r\n }\r\n</mat-toolbar>\r\n<!-- Main Content: Expands when menu is NOT toggled -->\r\n<div class=\"vd-navigation-drawer-content scrollbar-primary vd-collapse-container\" [class.is-expanded]=\"!menuToggled\" [ngClass]=\"{'drawer-mini': mini}\">\r\n <div class=\"vd-collapse-inner\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n<!-- Menu Content: Expands when menu IS toggled -->\r\n<div class=\"vd-navigation-drawer-menu-content vd-collapse-container\" [class.is-expanded]=\"menuToggled\" [ngClass]=\"{'drawer-mini': mini}\">\r\n <div class=\"vd-collapse-inner\">\r\n <ng-content select=\"[vd-navigation-drawer-menu]\"></ng-content>\r\n </div>\r\n</div>", styles: [":host{width:100%}:host .vd-collapse-container{grid-template-rows:0fr;height:0%;transition:grid-template-rows .15s ease-in-out}:host .vd-collapse-container.is-expanded{grid-template-rows:1fr;height:calc(100% - 58px)}:host .vd-collapse-inner{min-height:0;overflow:hidden}:host .vd-navigation-drawer-content.ng-animating,:host .vd-navigation-drawer-menu-content.ng-animating{overflow:hidden}:host .vd-navigation-drawer-content ::ng-deep .mat-mdc-nav-list,:host .vd-navigation-drawer-menu-content ::ng-deep .mat-mdc-nav-list{padding-top:0!important;padding-bottom:12px}:host .vd-navigation-drawer-content.drawer-mini ::ng-deep .mat-mdc-nav-list,:host .vd-navigation-drawer-menu-content.drawer-mini ::ng-deep .mat-mdc-nav-list{padding-bottom:0!important}:host mat-toolbar:not(.drawer-mini){padding:16px}:host mat-toolbar.drawer-mini{padding:0!important}:host mat-toolbar.vd-nagivation-drawer-toolbar{flex-direction:column;align-items:stretch}:host mat-toolbar.vd-toolbar-background{background-repeat:no-repeat;background-size:cover}:host mat-toolbar.vd-nagivation-drawer-toolbar:not(.drawer-mini){flex-direction:column;height:auto!important;display:block!important}:host mat-toolbar .vd-navigation-drawer-toolbar-content{flex-direction:row;box-sizing:border-box;display:flex;align-items:center;align-content:center;max-width:100%;justify-content:flex-start}:host mat-toolbar .vd-navigation-drawer-toolbar-content .vd-nagivation-drawer-toolbar-avatar{border-radius:50%;height:60px;width:60px;margin:0 12px 12px 0}:host mat-toolbar .vd-navigation-drawer-toolbar-content .vd-navigation-drawer-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-menu-toggle{flex-direction:row;box-sizing:border-box;display:flex;cursor:pointer}:host mat-toolbar .vd-navigation-drawer-menu-toggle .vd-navigation-drawer-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:host mat-toolbar .vd-navigation-drawer-menu-toggle .vd-navigation-drawer-menu-button{height:24px;line-height:24px;width:24px;padding:0!important}:host>div{overflow:hidden}\n"] }]
30153
30909
  }], ctorParameters: () => [{ type: VdLayoutComponent, decorators: [{
30154
30910
  type: Inject,
30155
30911
  args: [forwardRef(() => VdLayoutComponent)]
@@ -30333,6 +31089,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
30333
31089
  args: ['mediaStyles']
30334
31090
  }] } });
30335
31091
 
31092
+ /**
31093
+ * Decorator function to define columns for a table object.
31094
+ * @param type The constructor function of the table object.
31095
+ * @returns A decorator function.
31096
+ */
31097
+ function ColumnObject(type) {
31098
+ return function (target, propertyKey) {
31099
+ /* Retrieve table definition */
31100
+ var tableDef = getTableDefinition(type);
31101
+ /* Retrieve columns from the table definition */
31102
+ var columns = tableDef.columns;
31103
+ /* Update column names with property key prefix */
31104
+ columns?.forEach(x => x.name = `${propertyKey}.${x.name}`);
31105
+ /* Get existing table columns from metadata */
31106
+ let previousTableColumns = Reflect.getMetadata(TABLE_COLUMNS_METADATA_KEY, target);
31107
+ /* Create a copy of the existing columns array and append new columns */
31108
+ let tableColumns = previousTableColumns ? previousTableColumns.concat(columns ?? []) : [];
31109
+ /* Set column index if not already set */
31110
+ tableColumns.forEach((x, i) => x.index ??= i);
31111
+ /* Sort the columns by index */
31112
+ Utils.sortArray(tableColumns, 'index');
31113
+ /* Override the table columns in the metadata */
31114
+ Reflect.defineMetadata(TABLE_COLUMNS_METADATA_KEY, tableColumns, target);
31115
+ };
31116
+ }
31117
+
30336
31118
  /**
30337
31119
  * VdTableFieldDirective class
30338
31120
  */
@@ -30518,5 +31300,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
30518
31300
  * Generated bundle index. Do not edit.
30519
31301
  */
30520
31302
 
30521
- export { AbstractMatFormField, AbstractSelectFormField, ActionItem, Api, ApiResponse, AppEvent, AppEventType, AppSetting, AppStorage, AsyncValidationDirective, AuditEntity, AuditUser, AuthHelper, AuthUser, AutofocusDirective, BaseComponent, BaseDirective, BaseEntity, BaseInterceptor, BaseService, BindPipe, CachingInterceptor, Column, ColumnObject, Common, CommonError, CommonHandlerContext, ConfirmExitGuard, ContextHelper, DIALOG_PROVIDER, DIALOG_PROVIDER_FACTORY, DataSourceFilterDirective, DataSourcePipe, DatePickerHeaderComponent, DisableControlDirective, Display, DisplayNameNumberProjection, DisplayNameProjection, DynamicBuilder, DynamicComponentCompiler, EXPORT_DIALOG_COMPONENT, EmptyStringResetDirective, EnumMetadata, EnumPipe, EnumService, EqualValidator, ErrorMessageBindingStrategy, EventQueueService, Facet, FacetValue, FieldFuncPipe, FileControlDirective, FileService, FileSizePipe, FilterClearComponent, FilterDateComponent, FilterGlue, FilterInputComponent, FilterOperator, FilterPipe, FilterSelectComponent, FirstLetterPipe, Form, FormArrayPipe, FormBuilderConfiguration, FormControlPipe, FormDefinition, FormField, FormFieldDefinition, FormFieldGroup, FormFieldGroupDefinition, FormFieldType, FormGroupPipe, FuncPipe, GenericEmbeddedListComponent, GenericFormBaseComponent, GenericFormComponent, GenericListComponent, GenericReactiveFormComponent, GenericService, GlobalRoles, Grid, GroupFilterPipe, HtmlControlTemplateDirective, IAbstractControl, Icon, ImageFileControlDirective, IpVersion, KeyValue, KeysPipe, LayoutToggle, LoadingScreenInterceptor, LoadingScreenService, MEDIA_PROVIDER, MEDIA_PROVIDER_FACTORY, MatFormFieldEditorDirective, MatFormFieldRadioDirective, MatFormFieldReadonlyDirective, Menu, MenuClient, MenuDepartment, MenuFormIncludesResolve, MenuItem, MenuItemClient, MenuItemDepartment, MenuItemFormIncludesResolve, MenuItemService, MenuItemTarget, MenuListProjectionResolve, MenuResolve, MenuScope, MenuSettings, MenuSettingsResolve, MessageType, ModifiableEntity, MonthNamePipe, MsaEditFormActionsComponent, MsaEnumDisplayComponent, NameNumberProjection, NameProjection, NativeElementInjectorDirective, NumericValueType, OnlyNumberDirective, OrderPipe, Pagination, PaginatorIntl, ParseDecimalDirective, Permission, PlaceholderPipe, PrefixDirective, PrintService, PropertyJoinPipe, ReactiveFormConfig, ReactiveTypedFormsModule, RemoveWhitespaceDirective, ResetFormType, RxFormArray, RxFormBuilder, RxFormControl, RxFormControlDirective, RxFormGroup, RxReactiveFormsModule, RxwebFormDirective, RxwebValidators, SafeHtmlPipe, Salutation, SaveAction, SplitPipe, SubMenuResolve, SuffixButton, Table, TableColumn, TableColumnConfig, TableColumnType, TableConfig, TableDataSource, TableDefinition, TableQueryConfig, TableStaticDataSource, TaskDialogData, Templates, TimePipe, TitleCase, TitleProjection, TruncatePipe, TypedForm, TypedFormBuilder, UniqueValidatorDirective, UrlValidationType, Utils, ValidationAlphabetLocale, ValueAccessorBase, ValuesPipe, VdAlertDialogComponent, VdChipsComponent, VdCodeDirective, VdConfirmDialogComponent, VdCustomDirective, VdDelayedHoverDirective, VdDialogActionsDirective, VdDialogComponent, VdDialogContentDirective, VdDialogHeaderActionsComponent, VdDialogHeaderComponent, VdDialogMaximizeDirective, VdDialogService, VdDialogTitleDirective, VdDynamicMenuComponent, VdDynamicTableComponent, VdDynamicTableConfigDialogComponent, VdEditorDirective, VdFileDirective, VdFileInputComponent, VdFileModule, VdFilterOptionDirective, VdGenericFormComponent, VdGenericFormCustomFieldDirective, VdLayoutCardOverComponent, VdLayoutCloseDirective, VdLayoutCompactComponent, VdLayoutComponent, VdLayoutFooterComponent, VdLayoutManageListCloseDirective, VdLayoutManageListComponent, VdLayoutManageListOpenDirective, VdLayoutManageListToggleDirective, VdLayoutNavComponent, VdLayoutNavListCloseDirective, VdLayoutNavListComponent, VdLayoutNavListOpenDirective, VdLayoutNavListToggleDirective, VdLayoutOpenDirective, VdLayoutToggleDirective, VdListOptionDirective, VdListToolbarComponent, VdMediaService, VdMediaToggleDirective, VdMenuComponent, VdNavigationDrawerComponent, VdNavigationDrawerMenuDirective, VdNavigationDrawerToolbarDirective, VdPromptDialogComponent, VdSelectComponent, VdSelectOptionDirective, VdSelectTriggerDirective, VdTableFieldDirective, VdTaskDialogComponent, allOf, allOfAsync, alpha, alphaAsync, alphaNumeric, alphaNumericAsync, and, ascii, async, blacklist, choice, choiceAsync, compare, compose, contains, containsAsync, creditCard, creditCardAsync, cusip, custom, customAsync, dataUri, date, dateAsync, different, digit, disable, elementClass, email, endpointMetadataKey, endsWith, endsWithAsync, error, escape, even, extension, extensionAsync, factor, factorAsync, file, fileAsync, fileSize, fileSizeAsync, formDefinitionMetadataKey, formFieldGroupsMetadataKey, formFieldsMetadataKey, getDisplay, getEndpoint, getFormDefinition, getFormGroups, getTableDefinition, graphql, greaterThan, greaterThanAsync, greaterThanEqualTo, greaterThanEqualToAsync, grid, headerMetadataKey, hexColor, iban, ibanAsync, image, imageAsync, json, latLong, latitude, leapYear, lessThan, lessThanAsync, lessThanEqualTo, lessThanEqualToAsync, longitude, lowerCase, ltrim, mac, mask, maxDate, maxDateAsync, maxLength, maxLengthAsync, maxNumber, maxNumberAsync, maxTime, maxTimeAsync, minDate, minDateAsync, minLength, minLengthAsync, minNumber, minNumberAsync, minTime, minTimeAsync, mixinDisableRipple, mixinDisabled, model, noneOf, noneOfAsync, not, notEmpty, numeric, numericAsync, odd, oneOf, oneOfAsync, or, parseProjectionString, password, passwordAsync, pattern, patternAsync, port, prefix, primeNumber, prop, propArray, propObject, range, rangeAsync, required, requiredTrue, rtrim, rule, sanitize, startsWith, startsWithAsync, stripLow, suffix, tableColumnsMetadataKey, tableDefinitionMetadataKey, time, timeAsync, toBoolean, toDate, toDouble, toFloat, toInt, toString, trim, unique, updateOn, upperCase, url, urlAsync, whitelist };
31303
+ export { AbstractMatFormField, AbstractSelectFormField, ActionItem, Api, ApiResponse, AppEvent, AppEventType, AppSetting, AppStorage, AsyncValidationDirective, AuditEntity, AuditUser, AuthHelper, AuthUser, AutofocusDirective, BaseComponent, BaseDirective, BaseEntity, BaseInterceptor, BaseService, BindPipe, CachingInterceptor, Column, ColumnObject, Common, CommonError, CommonHandlerContext, ConfirmExitGuard, ContextHelper, DIALOG_PROVIDER, DIALOG_PROVIDER_FACTORY, DataSourceFilterDirective, DataSourcePipe, DatePickerHeaderComponent, DisableControlDirective, Display, DisplayNameNumberProjection, DisplayNameProjection, DynamicBuilder, DynamicComponentCompiler, EXPORT_DIALOG_COMPONENT, EmptyStringResetDirective, EnumMetadata, EnumPipe, EnumService, EqualValidator, ErrorMessageBindingStrategy, EventQueueService, Facet, FacetValue, FieldFuncPipe, FileControlDirective, FileService, FileSizePipe, FilterClearComponent, FilterDateComponent, FilterGlue, FilterInputComponent, FilterOperator, FilterPipe, FilterSelectComponent, FirstLetterPipe, Form, FormArrayPipe, FormBuilderConfiguration, FormControlPipe, FormDefinition, FormField, FormFieldDefinition, FormFieldGroup, FormFieldGroupDefinition, FormFieldType, FormGroupPipe, FuncPipe, GenericEmbeddedListComponent, GenericFormBaseComponent, GenericFormComponent, GenericListComponent, GenericReactiveFormComponent, GenericService, GlobalRoles, Grid, GroupFilterPipe, HtmlControlTemplateDirective, IAbstractControl, Icon, ImageFileControlDirective, IpVersion, KeyValue, KeysPipe, LayoutToggle, LoadingScreenInterceptor, LoadingScreenService, MEDIA_PROVIDER, MEDIA_PROVIDER_FACTORY, MatFormFieldEditorDirective, MatFormFieldRadioDirective, MatFormFieldReadonlyDirective, MatInputRequiredDirective, MatSelectRequiredDirective, Menu, MenuClient, MenuDepartment, MenuFormIncludesResolve, MenuItem, MenuItemClient, MenuItemDepartment, MenuItemFormIncludesResolve, MenuItemService, MenuItemTarget, MenuListProjectionResolve, MenuResolve, MenuScope, MenuSettings, MenuSettingsResolve, MessageType, ModifiableEntity, MonthNamePipe, MsaEditFormActionsComponent, MsaEnumDisplayComponent, MsaSelectRequiredDirective, NameNumberProjection, NameProjection, NativeElementInjectorDirective, NumericValueType, OnlyNumberDirective, OrderPipe, Pagination, PaginatorIntl, ParseDecimalDirective, Permission, PlaceholderPipe, PrefixDirective, PrintService, PropertyJoinPipe, ReactiveFormConfig, ReactiveTypedFormsModule, RemoveWhitespaceDirective, ResetFormType, RxFormArray, RxFormBuilder, RxFormControl, RxFormControlDirective, RxFormGroup, RxReactiveFormsModule, RxwebFormDirective, RxwebValidators, SafeHtmlPipe, Salutation, SaveAction, SplitPipe, SubMenuResolve, SuffixButton, TABLE_COLUMNS_METADATA_KEY, TABLE_DEFINITION_METADATA_KEY, Table, TableColumn, TableColumnConfig, TableColumnType, TableConfig, TableDataSource, TableDefinition, TableQueryConfig, TableStaticDataSource, TaskDialogData, Templates, TimePipe, TitleCase, TitleProjection, TruncatePipe, TypedForm, TypedFormBuilder, UniqueValidatorDirective, UrlValidationType, Utils, ValidationAlphabetLocale, ValueAccessorBase, ValuesPipe, VdAlertDialogComponent, VdChipsComponent, VdCodeDirective, VdConfirmDialogComponent, VdCustomDirective, VdDelayedHoverDirective, VdDialogActionsDirective, VdDialogComponent, VdDialogContentDirective, VdDialogHeaderActionsComponent, VdDialogHeaderComponent, VdDialogMaximizeDirective, VdDialogService, VdDialogTitleDirective, VdDynamicMenuComponent, VdDynamicTableComponent, VdDynamicTableConfigDialogComponent, VdEditorDirective, VdFileDirective, VdFileInputComponent, VdFileModule, VdFilterOptionDirective, VdGenericFormComponent, VdGenericFormCustomFieldDirective, VdLayoutCardOverComponent, VdLayoutCloseDirective, VdLayoutCompactComponent, VdLayoutComponent, VdLayoutFooterComponent, VdLayoutManageListCloseDirective, VdLayoutManageListComponent, VdLayoutManageListOpenDirective, VdLayoutManageListToggleDirective, VdLayoutNavComponent, VdLayoutNavListCloseDirective, VdLayoutNavListComponent, VdLayoutNavListOpenDirective, VdLayoutNavListToggleDirective, VdLayoutOpenDirective, VdLayoutToggleDirective, VdListOptionDirective, VdListToolbarComponent, VdMediaService, VdMediaToggleDirective, VdMenuComponent, VdNavigationDrawerComponent, VdNavigationDrawerMenuDirective, VdNavigationDrawerToolbarDirective, VdPromptDialogComponent, VdSelectComponent, VdSelectOptionDirective, VdSelectTriggerDirective, VdTableFieldDirective, VdTaskDialogComponent, allOf, allOfAsync, alpha, alphaAsync, alphaNumeric, alphaNumericAsync, and, ascii, async, blacklist, choice, choiceAsync, compare, compose, contains, containsAsync, creditCard, creditCardAsync, cusip, custom, customAsync, dataUri, date, dateAsync, different, digit, disable, elementClass, email, endpointMetadataKey, endsWith, endsWithAsync, error, escape, even, extension, extensionAsync, factor, factorAsync, file, fileAsync, fileSize, fileSizeAsync, formDefinitionMetadataKey, formFieldGroupsMetadataKey, formFieldsMetadataKey, getDisplay, getEndpoint, getFormDefinition, getFormGroups, getTableDefinition, graphql, greaterThan, greaterThanAsync, greaterThanEqualTo, greaterThanEqualToAsync, grid, hasRequiredValidator, headerMetadataKey, hexColor, iban, ibanAsync, image, imageAsync, json, latLong, latitude, leapYear, lessThan, lessThanAsync, lessThanEqualTo, lessThanEqualToAsync, longitude, lowerCase, ltrim, mac, mask, maxDate, maxDateAsync, maxLength, maxLengthAsync, maxNumber, maxNumberAsync, maxTime, maxTimeAsync, minDate, minDateAsync, minLength, minLengthAsync, minNumber, minNumberAsync, minTime, minTimeAsync, mixinDisableRipple, mixinDisabled, model, noneOf, noneOfAsync, not, notEmpty, numeric, numericAsync, odd, oneOf, oneOfAsync, or, parseProjectionArray, parseProjectionString, password, passwordAsync, pattern, patternAsync, port, prefix, primeNumber, prop, propArray, propObject, range, rangeAsync, required, requiredTrue, rtrim, rule, sanitize, startsWith, startsWithAsync, stripLow, suffix, time, timeAsync, toBoolean, toDate, toDouble, toFloat, toInt, toString, trim, unique, updateOn, upperCase, url, urlAsync, whitelist };
30522
31304
  //# sourceMappingURL=messaia-cdk.mjs.map