libs/pfe-connector/src/lib/runtime-utils/pfe-dynamic-page/pfe-dynamic-page.component.ts

Extends

PFEBuildingBlockPage

Implements

OnInit

Metadata

Relationships

Index

Properties
Methods

Constructor

constructor()

Methods

onPageComplete
onPageComplete()
Returns : void
onPageWaiting
onPageWaiting()
Returns : void
handleBuildBlocksChanged
handleBuildBlocksChanged(: [AbstractBuildingBlock[], AbstractBuildingBlock[]], allowedRetries: number)

Whenever the set of Building Blocks has changed ensure that the matching facades are created & connected or respectively disconnected and deleted from our internal facade map. We chose this approach instead of reusing facades as the underlying component is in fact deleted and recreated by the Angular renderer so we would have to introduce extra logic to re-initialize that component. It's easier to pretend that we encounter a Building Block the first time.

Parameters :
Name Type Optional Default value
[AbstractBuildingBlock[], AbstractBuildingBlock[]] No
allowedRetries number No 2
Returns : void
handlePageStatusUpdates
handlePageStatusUpdates(newStatus: ABSTRACT_PAGE_STATUS)
Parameters :
Name Type Optional
newStatus ABSTRACT_PAGE_STATUS No
Returns : void
onPageDestroy
onPageDestroy()
Returns : void
onPageReady
onPageReady()
Returns : void

Properties

blocks
Type : DynamicFormBBConfiguration[]
Default value : []
id
Type : string
Default value : ''
connect$
Type : unknown
Default value : new Subject<void>()
disconnect$
Type : unknown
Default value : new Subject<void>()
facadeMap
Type : unknown
Default value : new Map<string, AbstractBuildingBlockFacade>()
pageData
Type : PageDataForTemplate
Default value : {}
status
Type : unknown
Default value : ABSTRACT_PAGE_STATUS.WAITING
import { PfeNavigationService } from '@allianz/ngx-pfe';
import { createStaticAclTagProvider } from '@allianz/taly-acl/angular';
import { Stage, TalyPageDataService } from '@allianz/taly-core';
import { BuildingBlockMetaService } from '@allianz/taly-core/building-blocks';
import { TalyFrameSidebarService } from '@allianz/taly-core/frame';
import {
  DynamicFormBBConfiguration,
  isDynamicFormBbConfig,
  NotificationConfig,
  PageConfiguration
} from '@allianz/taly-core/schemas';
import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  effect,
  inject,
  OnInit
} from '@angular/core';
import { PFEBuildingBlockPage } from '../../pfe-building-block-page';
import { DynamicBuildingBlockMetaService } from '../dynamic-building-block-meta-service/dynamic-building-block-meta-service';
import { PfeRuntimeConfigService } from '../pfe-runtime-config/pfe-runtime-config.service';

@Component({
  selector: 'pfe-dynamic-page',
  templateUrl: './pfe-dynamic-page.component.html',
  providers: [
    createStaticAclTagProvider('pfe-dynamic-page'),
    {
      provide: BuildingBlockMetaService,
      useClass: DynamicBuildingBlockMetaService
    }
  ],
  standalone: false,
  // This component imperatively updates state (blocks, title, notifications) via effects.
  // It must use Eager change detection so that those updates are reflected in the view.
  // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
  changeDetection: ChangeDetectionStrategy.Eager
})
export class PfeDynamicPageComponent extends PFEBuildingBlockPage implements OnInit {
  blocks: DynamicFormBBConfiguration[] = [];

  override id = '';

  protected title = '';
  protected subtitle = '';
  protected notifications: NotificationConfig[] = [];
  protected notificationColumnSpan = 12;

  private pfeNavigationService = inject(PfeNavigationService);
  private runtimeConfigService = inject(PfeRuntimeConfigService);
  private talyPageDataService = inject(TalyPageDataService);
  private sidebarService = inject(TalyFrameSidebarService);
  private cdr = inject(ChangeDetectorRef);

  constructor() {
    super();

    effect(async () => {
      if (!this.id || !this.runtimeConfigService.pagesConfig()) {
        return;
      }

      const currentPageConfig = this.runtimeConfigService
        .pagesConfig()
        .pages?.find((page) => page.id === this.id);

      if (!currentPageConfig) {
        const firstPage = await this.pfeNavigationService.getFirstPage();
        if (!firstPage) {
          console.error(
            `Unable to find the configuration for page "${this.id}" or determine the first page.`
          );
          return;
        }

        console.warn(
          `Unable to find the configuration for page "${this.id}". Navigating to the first page.`
        );
        this.pfeNavigationService.navigateToPageId(firstPage);
        return;
      }

      this.renderPageContent(currentPageConfig);
      this.renderPageTitle(currentPageConfig);
      this.renderNotifications(currentPageConfig);
      this.renderFrame(currentPageConfig);
      this.cdr.markForCheck();
    });
  }

  override ngOnInit(): void {
    super.ngOnInit();
    this.id = this.pfeNavigationService.currentPageId$.value as string;
    this.talyPageDataService.setPageId(this.id);
  }

  private renderPageContent(currentPageConfig: PageConfiguration) {
    this.blocks = (currentPageConfig?.blocks ?? []).filter(
      (block): block is DynamicFormBBConfiguration => {
        if (!isDynamicFormBbConfig(block)) {
          console.warn(
            `Skipping Building Block '${block.id}': Building Blocks cannot be used in TALY runtime web components. Only Dynamic Forms are supported.`
          );
          return false;
        }
        return true;
      }
    );

    this.sidebarService.setVisibility(this.blocks.some((block) => block.sidebar));
  }

  private renderFrame(currentPageConfig: PageConfiguration) {
    this.talyPageDataService.storeData({
      ...currentPageConfig.pageData,
      stage: (currentPageConfig.title as Stage)?.showAsStage
        ? (currentPageConfig.title as Stage)
        : undefined,
      smallPrint: currentPageConfig.smallPrint ? currentPageConfig.smallPrint : undefined,
      sidebar: currentPageConfig.sidebar ? currentPageConfig.sidebar : undefined
    });
  }

  private renderNotifications(currentPageConfig: PageConfiguration) {
    this.notifications = currentPageConfig.notificationsGroup?.items ?? [];
    this.notificationColumnSpan = currentPageConfig.notificationsGroup?.columnSpan ?? 12;
  }

  private renderPageTitle(currentPageConfig: PageConfiguration) {
    this.title = '';
    this.subtitle = '';

    if (typeof currentPageConfig.title === 'string') {
      this.title = currentPageConfig.title;
    } else if (
      typeof currentPageConfig.title === 'object' &&
      currentPageConfig.title.showAsStage !== true
    ) {
      this.title = currentPageConfig.title.headline;
      this.subtitle = currentPageConfig.title?.subline || '';
    }
  }
}
@if (title) {
<div
  class="section-wrapper page-headline-wrapper"
  data-testid="page-headline"
  data-section-name="page title"
>
  <taly-internal-headline type="page" [subline]="subtitle | interpolateFromStore | async">
    {{ title | interpolateFromStore | async }}
  </taly-internal-headline>
</div>
}
<frame-notifications-group
  [notifications]="notifications"
  [columnSpan]="notificationColumnSpan"
  class="frame-notifications-group"
></frame-notifications-group>
@for (block of blocks; track block.id;) { @if (block.sidebar) {
<div
  *talyFrameSidebar
  class="section-wrapper section"
  [style.--background-color]="'transparent'"
  data-section-name="section"
>
  <div class="block-wrapper" *aclTag="block.id">
    <taly-dynamic-form-bb class="building-block-element" [id]="block.id"></taly-dynamic-form-bb>
  </div>
</div>
} @else {
<div
  class="section-wrapper section"
  [style.--background-color]="'transparent'"
  data-section-name="section"
>
  <div class="block-wrapper" *aclTag="block.id">
    <taly-dynamic-form-bb class="building-block-element" [id]="block.id"></taly-dynamic-form-bb>
  </div>
</div>
} }
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""