@verisoft/ui-govcz 21.0.9 → 21.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, Pipe, ChangeDetectionStrategy, CUSTOM_ELEMENTS_SCHEMA, EventEmitter, Output, Input, inject, Optional, Self, input, SimpleChange, Injectable, ChangeDetectorRef, Injector, ViewContainerRef, ViewChild, ViewEncapsulation, HostListener, NO_ERRORS_SCHEMA, output, ContentChild, ContentChildren, NgModule, Inject, effect, Directive, forwardRef, InjectionToken } from '@angular/core';
2
+ import { Component, Pipe, ChangeDetectionStrategy, CUSTOM_ELEMENTS_SCHEMA, EventEmitter, Output, Input, inject, Optional, Self, input, reflectComponentType, Injectable, ChangeDetectorRef, Injector, ViewContainerRef, ViewChild, ViewEncapsulation, HostListener, NO_ERRORS_SCHEMA, output, ContentChild, ContentChildren, NgModule, Inject, effect, Directive, forwardRef, InjectionToken } from '@angular/core';
3
3
  import * as i1 from '@angular/router';
4
4
  import { RouterModule, Router, RouterOutlet, RouterLink, RouterLinkActive, ActivatedRoute } from '@angular/router';
5
5
  import * as i2 from '@gov-design-system-ce/angular';
@@ -502,86 +502,76 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
502
502
  type: Input
503
503
  }] } });
504
504
 
505
- /* eslint-disable @typescript-eslint/no-explicit-any */
506
505
  class DynamicComponentFactoryService {
507
- componentFactoryResolver;
508
- constructor(componentFactoryResolver) {
509
- this.componentFactoryResolver = componentFactoryResolver;
510
- }
511
- ngOnDestroy() {
512
- this.unsubscribeComponentEvents(this);
513
- }
514
- async createDynamicComponent(componentType, viewContainerRef, inputs, injector = undefined) {
515
- const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType);
506
+ outputSubscriptions = new WeakMap();
507
+ createDynamicComponent(componentType, viewContainerRef, inputs, injector = undefined) {
516
508
  viewContainerRef.clear();
517
- const component = viewContainerRef.createComponent(componentFactory, undefined, injector);
518
- this.setComponentDataInt(componentFactory, component, inputs);
519
- this.fireComponentEvents(component.instance, inputs);
509
+ const component = viewContainerRef.createComponent(componentType, {
510
+ injector,
511
+ });
512
+ this.setComponentDataInt(componentType, component, inputs);
513
+ this.fireComponentEvents(componentType, component.instance, inputs);
520
514
  return component;
521
515
  }
516
+ cleanupComponent(instance) {
517
+ this.unsubscribeComponentEvents(instance);
518
+ }
522
519
  setComponentData(component, inputs) {
523
- const factory = this.componentFactoryResolver.resolveComponentFactory(component.componentType);
524
- this.setComponentDataInt(factory, component, inputs);
520
+ this.setComponentDataInt(component.componentType, component, inputs);
525
521
  }
526
522
  unsubscribeComponentEvents(instance) {
527
- const subscriptionStoreKey = '__outputSubscriptions__';
528
- const subscriptions = instance[subscriptionStoreKey];
523
+ const subscriptions = this.outputSubscriptions.get(instance);
529
524
  if (subscriptions) {
530
525
  subscriptions.forEach((sub) => sub.unsubscribe());
531
526
  subscriptions.clear();
527
+ this.outputSubscriptions.delete(instance);
532
528
  }
533
529
  }
534
- fireComponentEvents(instance, inputs) {
530
+ fireComponentEvents(componentType, instance, inputs) {
535
531
  if (!instance || typeof instance !== 'object')
536
532
  return;
537
- this.fireInputComponentEvents(instance, inputs);
538
- this.fireOutputComponentEvents(instance, inputs);
533
+ this.fireOutputComponentEvents(componentType, instance, inputs);
539
534
  }
540
- setComponentDataInt(factory, component, inputs) {
535
+ setComponentDataInt(componentType, component, inputs) {
541
536
  if (inputs) {
542
- const propertyNames = factory.inputs.map((x) => x.propName);
537
+ const propertyNames = this.getInputNames(componentType);
543
538
  const inputsHash = new Set(propertyNames);
544
539
  Object.keys(inputs)
545
540
  .filter((x) => inputsHash.has(x))
546
541
  .forEach((x) => {
547
- component.instance[x] = inputs[x];
542
+ component.setInput(x, inputs[x]);
548
543
  });
549
544
  }
550
545
  }
551
- fireInputComponentEvents(instance, inputs) {
552
- const onChangeComponent = instance;
553
- if (onChangeComponent.ngOnChanges && inputs) {
554
- const changeEventArgs = Object.keys(inputs).reduce((changes, key) => {
555
- const inputValue = inputs[key];
556
- changes[key] = new SimpleChange(undefined, inputValue, true);
557
- return changes;
558
- }, {});
559
- onChangeComponent.ngOnChanges(changeEventArgs);
560
- }
561
- }
562
- fireOutputComponentEvents(instance, inputs) {
563
- const outputs = Object.keys(inputs).filter((key) => {
564
- const emitter = instance[key];
565
- return emitter instanceof EventEmitter;
566
- });
567
- const subscriptionStoreKey = '__outputSubscriptions__';
568
- if (!(subscriptionStoreKey in instance)) {
569
- instance[subscriptionStoreKey] = new Map();
546
+ fireOutputComponentEvents(componentType, instance, inputs) {
547
+ const outputNames = new Set(this.getOutputNames(componentType));
548
+ const outputs = Object.keys(inputs ?? {}).filter((key) => outputNames.has(key));
549
+ let subscriptions = this.outputSubscriptions.get(instance);
550
+ if (!subscriptions) {
551
+ subscriptions = new Map();
552
+ this.outputSubscriptions.set(instance, subscriptions);
570
553
  }
571
- const subscriptions = instance[subscriptionStoreKey];
572
554
  for (const outputKey of outputs) {
573
- const eventEmitter = instance[outputKey];
555
+ const outputRef = instance[outputKey];
574
556
  const callback = inputs[outputKey];
575
- if (eventEmitter && typeof callback === 'function') {
557
+ if (outputRef &&
558
+ typeof outputRef.subscribe === 'function' &&
559
+ typeof callback === 'function') {
576
560
  if (subscriptions.has(outputKey)) {
577
561
  subscriptions.get(outputKey).unsubscribe();
578
562
  }
579
- const subscription = eventEmitter.subscribe((value) => callback(value));
563
+ const subscription = outputRef.subscribe((value) => callback(value));
580
564
  subscriptions.set(outputKey, subscription);
581
565
  }
582
566
  }
583
567
  }
584
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DynamicComponentFactoryService, deps: [{ token: i0.ComponentFactoryResolver }], target: i0.ɵɵFactoryTarget.Injectable });
568
+ getInputNames(componentType) {
569
+ return (reflectComponentType(componentType)?.inputs.map((input) => input.propName) ?? []);
570
+ }
571
+ getOutputNames(componentType) {
572
+ return (reflectComponentType(componentType)?.outputs.map((output) => output.propName) ?? []);
573
+ }
574
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DynamicComponentFactoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
585
575
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DynamicComponentFactoryService, providedIn: 'root' });
586
576
  }
587
577
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DynamicComponentFactoryService, decorators: [{
@@ -589,7 +579,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
589
579
  args: [{
590
580
  providedIn: 'root',
591
581
  }]
592
- }], ctorParameters: () => [{ type: i0.ComponentFactoryResolver }] });
582
+ }] });
593
583
 
594
584
  class DynamicComponent {
595
585
  componentType;
@@ -598,6 +588,7 @@ class DynamicComponent {
598
588
  factoryServices = inject(DynamicComponentFactoryService);
599
589
  changeDetectorRef = inject(ChangeDetectorRef);
600
590
  injector = inject(Injector);
591
+ componentRef;
601
592
  ngOnChanges() {
602
593
  this.createComponent();
603
594
  }
@@ -605,9 +596,20 @@ class DynamicComponent {
605
596
  this.createComponent();
606
597
  this.changeDetectorRef.detectChanges();
607
598
  }
599
+ ngOnDestroy() {
600
+ this.destroyCurrentComponent();
601
+ }
608
602
  createComponent() {
609
603
  if (this.container) {
610
- this.factoryServices.createDynamicComponent(this.componentType, this.container, this.data, this.injector);
604
+ this.destroyCurrentComponent();
605
+ this.componentRef = this.factoryServices.createDynamicComponent(this.componentType, this.container, this.data, this.injector);
606
+ }
607
+ }
608
+ destroyCurrentComponent() {
609
+ if (this.componentRef) {
610
+ this.factoryServices.cleanupComponent(this.componentRef.instance);
611
+ this.componentRef.destroy();
612
+ this.componentRef = undefined;
611
613
  }
612
614
  }
613
615
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DynamicComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -674,7 +676,7 @@ class ConfirmDialogComponent extends UnsubscribeComponent {
674
676
  provide: CONFIRM_DIALOG_COMPONENT_TOKEN,
675
677
  useExisting: ConfirmDialogComponent,
676
678
  },
677
- ], usesInheritance: true, ngImport: i0, template: "<gov-dialog\n [open]=\"visible\"\n [attr.block-close]=\"data.closable !== undefined ? !data.closable : false\"\n [attr.block-backdrop-close]=\"data.closable !== undefined ? !data.closable : false\" \n [style.--dialog-max-width]=\"data.width\"\n [style.--dialog-max-height]=\"data.height\"\n role=\"dialog\"\n accessible-close-label=\"Close dialog box with more information\"\n (gov-close)=\"data.cancelButtonFn ? dialogClick(false) : (visible = false)\"\n>\n <gov-icon\n type=\"components\"\n [name]=\"data.headerIcon\"\n slot=\"icon\"\n [color]=\"data.severity | govColor\"\n />\n \n <h2 slot=\"title\">{{ data.title ?? 'Title' }}</h2>\n\n @if (data && data.innerHTML) {\n <div [innerHTML]=\"data.innerHTML\"></div>\n } @else if (data.componentType) {\n <v-dynamic-component\n [componentType]=\"data.componentType\"\n [data]=\"$any(data.data)\"\n ></v-dynamic-component>\n }\n\n <gov-button\n color=\"primary\"\n size=\"m\"\n type=\"solid\"\n slot=\"footer\"\n (gov-click)=\"data.confirmButtonFn ? dialogClick(true) : (visible = false)\"\n >\n {{ data.confirmButtonText ?? 'Yes'}}\n </gov-button>\n \n <gov-button\n [ngClass]=\"!data.showCancelButton ? 'd-none' : ''\"\n color=\"primary\"\n size=\"m\"\n type=\"outlined\"\n slot=\"footer\"\n [disabled]=\"!data.showCancelButton\"\n (gov-click)=\"data.cancelButtonFn ? dialogClick(false) : (visible = false)\"\n >\n {{ data.cancelButtonText ?? 'No' }}\n </gov-button>\n</gov-dialog>\n", styles: [":host ::ng-deep dialog{max-width:var(--dialog-max-width, 95%);max-height:var(--dialog-max-height, 95%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: GovDesignSystemModule }, { kind: "component", type: i2.GovButton, selector: "gov-button", inputs: ["color", "disabled", "download", "expanded", "expandedMobile", "focusable", "href", "hreflang", "identifier", "loading", "name", "nativeType", "referrerpolicy", "rel", "size", "target", "type"] }, { kind: "component", type: i2.GovDialog, selector: "gov-dialog", inputs: ["accessibleCloseLabel", "accessibleCloseLabelledBy", "accessibleDescribedBy", "accessibleLabelledBy", "blockBackdropClose", "blockClose", "labelTag", "open", "role"] }, { kind: "component", type: i2.GovIcon, selector: "gov-icon", inputs: ["color", "name", "size", "type"] }, { kind: "component", type: DynamicComponent, selector: "v-dynamic-component", inputs: ["componentType", "data"] }, { kind: "pipe", type: GovColorPipe, name: "govColor" }] });
679
+ ], usesInheritance: true, ngImport: i0, template: "<gov-dialog\n [open]=\"visible\"\n [attr.block-close]=\"data.closable !== undefined ? !data.closable : false\"\n [attr.block-backdrop-close]=\"\n data.closable !== undefined ? !data.closable : false\n \"\n [style.--dialog-max-width]=\"data.width\"\n [style.--dialog-max-height]=\"data.height\"\n role=\"dialog\"\n accessible-close-label=\"Close dialog box with more information\"\n (gov-close)=\"data.cancelButtonFn ? dialogClick(false) : (visible = false)\"\n>\n <gov-icon\n type=\"components\"\n [name]=\"data.headerIcon\"\n slot=\"icon\"\n [color]=\"data.severity | govColor\"\n />\n\n <h2 slot=\"title\">{{ data.title ?? 'Title' }}</h2>\n\n @if (data && data.innerHTML) {\n <div [innerHTML]=\"data.innerHTML\"></div>\n } @else if (data.componentType) {\n <v-dynamic-component\n [componentType]=\"data.componentType\"\n [data]=\"$any(data.data)\"\n ></v-dynamic-component>\n }\n\n <gov-button\n color=\"primary\"\n size=\"m\"\n type=\"solid\"\n slot=\"footer\"\n [disabled]=\"data.confirmButtonDisabled\"\n (gov-click)=\"data.confirmButtonFn ? dialogClick(true) : (visible = false)\"\n >\n {{ data.confirmButtonText ?? 'Yes' }}\n </gov-button>\n\n <gov-button\n [ngClass]=\"!data.showCancelButton ? 'd-none' : ''\"\n color=\"primary\"\n size=\"m\"\n type=\"outlined\"\n slot=\"footer\"\n [disabled]=\"!data.showCancelButton\"\n (gov-click)=\"data.cancelButtonFn ? dialogClick(false) : (visible = false)\"\n >\n {{ data.cancelButtonText ?? 'No' }}\n </gov-button>\n</gov-dialog>\n", styles: [":host ::ng-deep dialog{max-width:var(--dialog-max-width, 95%);max-height:var(--dialog-max-height, 95%)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: GovDesignSystemModule }, { kind: "component", type: i2.GovButton, selector: "gov-button", inputs: ["color", "disabled", "download", "expanded", "expandedMobile", "focusable", "href", "hreflang", "identifier", "loading", "name", "nativeType", "referrerpolicy", "rel", "size", "target", "type"] }, { kind: "component", type: i2.GovDialog, selector: "gov-dialog", inputs: ["accessibleCloseLabel", "accessibleCloseLabelledBy", "accessibleDescribedBy", "accessibleLabelledBy", "blockBackdropClose", "blockClose", "labelTag", "open", "role"] }, { kind: "component", type: i2.GovIcon, selector: "gov-icon", inputs: ["color", "name", "size", "type"] }, { kind: "component", type: DynamicComponent, selector: "v-dynamic-component", inputs: ["componentType", "data"] }, { kind: "pipe", type: GovColorPipe, name: "govColor" }] });
678
680
  }
679
681
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
680
682
  type: Component,
@@ -688,7 +690,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
688
690
  provide: CONFIRM_DIALOG_COMPONENT_TOKEN,
689
691
  useExisting: ConfirmDialogComponent,
690
692
  },
691
- ], template: "<gov-dialog\n [open]=\"visible\"\n [attr.block-close]=\"data.closable !== undefined ? !data.closable : false\"\n [attr.block-backdrop-close]=\"data.closable !== undefined ? !data.closable : false\" \n [style.--dialog-max-width]=\"data.width\"\n [style.--dialog-max-height]=\"data.height\"\n role=\"dialog\"\n accessible-close-label=\"Close dialog box with more information\"\n (gov-close)=\"data.cancelButtonFn ? dialogClick(false) : (visible = false)\"\n>\n <gov-icon\n type=\"components\"\n [name]=\"data.headerIcon\"\n slot=\"icon\"\n [color]=\"data.severity | govColor\"\n />\n \n <h2 slot=\"title\">{{ data.title ?? 'Title' }}</h2>\n\n @if (data && data.innerHTML) {\n <div [innerHTML]=\"data.innerHTML\"></div>\n } @else if (data.componentType) {\n <v-dynamic-component\n [componentType]=\"data.componentType\"\n [data]=\"$any(data.data)\"\n ></v-dynamic-component>\n }\n\n <gov-button\n color=\"primary\"\n size=\"m\"\n type=\"solid\"\n slot=\"footer\"\n (gov-click)=\"data.confirmButtonFn ? dialogClick(true) : (visible = false)\"\n >\n {{ data.confirmButtonText ?? 'Yes'}}\n </gov-button>\n \n <gov-button\n [ngClass]=\"!data.showCancelButton ? 'd-none' : ''\"\n color=\"primary\"\n size=\"m\"\n type=\"outlined\"\n slot=\"footer\"\n [disabled]=\"!data.showCancelButton\"\n (gov-click)=\"data.cancelButtonFn ? dialogClick(false) : (visible = false)\"\n >\n {{ data.cancelButtonText ?? 'No' }}\n </gov-button>\n</gov-dialog>\n", styles: [":host ::ng-deep dialog{max-width:var(--dialog-max-width, 95%);max-height:var(--dialog-max-height, 95%)}\n"] }]
693
+ ], template: "<gov-dialog\n [open]=\"visible\"\n [attr.block-close]=\"data.closable !== undefined ? !data.closable : false\"\n [attr.block-backdrop-close]=\"\n data.closable !== undefined ? !data.closable : false\n \"\n [style.--dialog-max-width]=\"data.width\"\n [style.--dialog-max-height]=\"data.height\"\n role=\"dialog\"\n accessible-close-label=\"Close dialog box with more information\"\n (gov-close)=\"data.cancelButtonFn ? dialogClick(false) : (visible = false)\"\n>\n <gov-icon\n type=\"components\"\n [name]=\"data.headerIcon\"\n slot=\"icon\"\n [color]=\"data.severity | govColor\"\n />\n\n <h2 slot=\"title\">{{ data.title ?? 'Title' }}</h2>\n\n @if (data && data.innerHTML) {\n <div [innerHTML]=\"data.innerHTML\"></div>\n } @else if (data.componentType) {\n <v-dynamic-component\n [componentType]=\"data.componentType\"\n [data]=\"$any(data.data)\"\n ></v-dynamic-component>\n }\n\n <gov-button\n color=\"primary\"\n size=\"m\"\n type=\"solid\"\n slot=\"footer\"\n [disabled]=\"data.confirmButtonDisabled\"\n (gov-click)=\"data.confirmButtonFn ? dialogClick(true) : (visible = false)\"\n >\n {{ data.confirmButtonText ?? 'Yes' }}\n </gov-button>\n\n <gov-button\n [ngClass]=\"!data.showCancelButton ? 'd-none' : ''\"\n color=\"primary\"\n size=\"m\"\n type=\"outlined\"\n slot=\"footer\"\n [disabled]=\"!data.showCancelButton\"\n (gov-click)=\"data.cancelButtonFn ? dialogClick(false) : (visible = false)\"\n >\n {{ data.cancelButtonText ?? 'No' }}\n </gov-button>\n</gov-dialog>\n", styles: [":host ::ng-deep dialog{max-width:var(--dialog-max-width, 95%);max-height:var(--dialog-max-height, 95%)}\n"] }]
692
694
  }], ctorParameters: () => [{ type: i1$3.DialogService }, { type: i0.ChangeDetectorRef }] });
693
695
 
694
696
  class TooltipComponent {