File
    Implements
    
    
    
    Index
    
        
                
                    | Properties | 
                
                    |  | 
                
                    | Methods | 
                
                    |  | 
                
                    | Inputs | 
                
                    |  | 
                
                    | HostBindings | 
                
                    |  | 
                    
                        | Accessors | 
                    
                        |  | 
        
    
    
    
        
            
                
                    | hasFooter | 
                
                    | Type : boolean | 
                
                    | Default value : false | 
                        
                            |  | 
            
        
        
            
                
                    | hasOfferCode | 
                
                    | Type : boolean | 
                
                    | Default value : false | 
                        
                            |  | 
            
        
        
            
                
                    | hasSmallPrint | 
                
                    | Type : boolean | 
                
                    | Default value : false | 
                        
                            |  | 
            
        
    
    
    
    
        Methods
    
    
    
        
            
                | navigateBack | 
            
                | navigateBack() | 
            
                |  | 
            
                |  | 
        
    
    
        
            
                | navigateNext | 
            
                | navigateNext() | 
            
                |  | 
            
                |  | 
        
    
    
    
        
            
                | triggerCustomAction | 
            
                | triggerCustomAction(customAction: CustomAction) | 
            
                |  | 
            
                | 
                     
                        
                     | 
        
    
    
    
    
    
        
            
                | Readonly
                        defaultBackLabel | 
                
                    | Default value : $localize`:@@page-action.back-button-label:Back` | 
                    
                        |  | 
        
    
    
        
            
                | Readonly
                        defaultCancelLabel | 
                
                    | Default value : $localize`:@@page-action.cancel-button-label:Cancel` | 
                    
                        |  | 
        
    
    
        
            
                | Readonly
                        defaultNextLabel | 
                
                    | Default value : $localize`:@@page-action.next-button-label:Next` | 
                    
                        |  | 
        
    
    
    
    
        Accessors
    
        
        
        
            
                
                    | shouldRemoveSpacing | 
                
                    | get shouldRemoveSpacing() | 
                            
                                |  | 
            
        
        
            
                
                    | nextButtonLabel | 
                
                    | get nextButtonLabel() | 
                            
                                |  | 
            
        
        
            
                
                    | backButtonLabel | 
                
                    | get backButtonLabel() | 
                            
                                |  | 
            
        
        
            
                
                    | cancelButtonLabel | 
                
                    | get cancelButtonLabel() | 
                            
                                |  | 
            
        
        
            
                
                    | pageActionConfig | 
                
                    | get pageActionConfig() | 
                            
                                |  | 
            
        
        
        import {
  BackLinkAdapterService,
  BackLinkConfigElement,
  BackLinkUtilsService
} from '@allianz/taly-common/web-components';
import {
  CHANNEL,
  CHANNEL_TOKEN,
  CustomAction,
  NO_MARGIN,
  PageActionConfig,
  TalyBusinessEventService,
  TalyPageDataService
} from '@allianz/taly-core';
import { Component, DestroyRef, HostBinding, inject, Input, OnInit } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { LocalizeFn } from '@angular/localize/init';
import { TalyFrameNavigationService } from '../../services/taly-frame-navigation-service';
import { PageActionStatus } from './model';
declare let $localize: LocalizeFn;
@Component({
  selector: 'frame-actions',
  templateUrl: './actions.component.html',
  styleUrls: ['./actions.component.scss'],
  standalone: false
})
export class ActionsComponent implements OnInit {
  private backLinkData: BackLinkConfigElement | undefined;
  pageActionStatus: PageActionStatus | undefined;
  private talyPageDataService = inject(TalyPageDataService);
  private backLinkUtilsService = inject(BackLinkUtilsService);
  private businessEventService = inject(TalyBusinessEventService);
  private frameNavigationService = inject(TalyFrameNavigationService, { optional: true });
  private backLinkAdapterService = inject(BackLinkAdapterService, { optional: true });
  private _channel = inject(CHANNEL_TOKEN);
  private destroyRef = inject(DestroyRef);
  protected hasMargin = !inject(NO_MARGIN);
  @Input() hasSmallPrint = false;
  @Input() hasFooter = false;
  @Input() hasOfferCode = false;
  readonly defaultNextLabel = $localize`:@@page-action.next-button-label:Next`;
  readonly defaultBackLabel = $localize`:@@page-action.back-button-label:Back`;
  readonly defaultCancelLabel = $localize`:@@page-action.cancel-button-label:Cancel`;
  @HostBinding('class.expert-layout')
  get isExpert() {
    return this._channel === CHANNEL.EXPERT;
  }
  @HostBinding('class.retail-layout')
  get isRetail() {
    return this._channel === CHANNEL.RETAIL;
  }
  @HostBinding('class.no-spacing')
  get shouldRemoveSpacing() {
    return !this.hasSmallPrint && !this.hasFooter && !this.hasOfferCode && !this.hasMargin;
  }
  ngOnInit() {
    this.frameNavigationService?.pageActionStatus$
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((status) => {
        this.pageActionStatus = status;
        this.backLinkData = this.getBackLinkData();
      });
  }
  private getBackLinkData(): BackLinkConfigElement | undefined {
    const backLinkFeatureActiveForActions =
      this.backLinkUtilsService.isBackLinkFeatureActiveForActions(
        Boolean(this.pageActionStatus?.isLastPage)
      );
    return backLinkFeatureActiveForActions ? this.backLinkAdapterService?.backLinkData : undefined;
  }
  get nextButtonLabel() {
    if (this.backLinkData?.nextButtonLabel) {
      return this.backLinkData.nextButtonLabel;
    }
    return this.pageActionConfig?.nextButtonLabel;
  }
  get backButtonLabel() {
    return this.pageActionConfig?.backButtonLabel;
  }
  get cancelButtonLabel() {
    return this.pageActionConfig?.cancelButtonLabel;
  }
  get pageActionConfig(): PageActionConfig | undefined {
    return this.talyPageDataService.pageData?.pageActionConfig;
  }
  get pageId$() {
    return this.talyPageDataService.pageId$;
  }
  navigateBack() {
    // The Back button has two event listeners attached: One from Angular, one from Trackify.
    // Apparently the browser waits for the first event handler (Angular) to complete before triggering the next one.
    // This leads to the Trackify event ("back button clicked") being fired after the PFE triggers the
    // pageChanged event. This leads to a weird chain of events for the tracking experts.
    // See https://github.developer.allianz.io/gcj/ngx-pfe/issues/681 for details.
    // The slightly hacky solution here is to postpone the Angular event by a single tick, using setTimeout.
    // As an alternative we could trigger the Trackify event manually, but this would require us to
    // add the Trackify library or PFE as a direct dependency to this component (see this commit in PFE:
    // https://github.developer.allianz.io/gcj/ngx-pfe/commit/71d080b32c3ebb5cf5c7548ecde9e3edf5cfaac2).
    window.setTimeout(() => {
      this.frameNavigationService?.navigateBack();
    });
  }
  navigateNext() {
    // The Next button has two event listeners attached: One from Angular, one from Trackify.
    // Apparently the browser waits for the first event handler (Angular) to complete before triggering the next one.
    // This leads to the Trackify event ("next button clicked") being fired after the PFE triggers the
    // pageChanged event. This leads to a weird chain of events for the tracking experts.
    // See https://github.developer.allianz.io/gcj/ngx-pfe/issues/681 for details.
    // The slightly hacky solution here is to postpone the Angular event by a single tick, using setTimeout.
    // As an alternative we could trigger the Trackify event manually, but this would require us to
    // add the Trackify library or PFE as a direct dependency to this component (see this commit in PFE:
    // https://github.developer.allianz.io/gcj/ngx-pfe/commit/71d080b32c3ebb5cf5c7548ecde9e3edf5cfaac2).
    window.setTimeout(() => {
      if (this.backLinkData) {
        window.location.href = this.backLinkData.path;
        return;
      }
      this.frameNavigationService?.navigateNext();
    });
  }
  saveOffer() {
    this.frameNavigationService?.saveOffer();
  }
  cancel() {
    this.frameNavigationService?.cancel();
  }
  triggerCustomAction(customAction: CustomAction) {
    this.businessEventService.handleBusinessEvent({
      handlerType: customAction.handlerType,
      config: customAction.config
    });
  }
}
     
    
        <!-- TODO: Provide an option to override the default templates. -->
<ng-container *ngTemplateOutlet="isExpert === true ? defaultExpertTemplate : defaultRetailTemplate">
</ng-container>
<ng-template #defaultRetailTemplate>
  <div class="action-button-container" [class.has-margin]="hasMargin">
    @if (!pageActionStatus?.nextHidden) {
    <button
      data-testid="retail-next-button"
      class="button"
      nxButton="block primary"
      (click)="navigateNext()"
      [attr.trackId]="'btn_Nav'"
      [attr.trackValue]="'forward'"
      [disabled]="pageActionStatus?.nextDisabled"
      *aclTag="(pageId$ | async) + '/next-button'"
    >
      {{ (nextButtonLabel | conditionalLabel | async) || defaultNextLabel }}
    </button>
    } @if (pageActionStatus?.showSaveOfferButton) {
    <button
      data-testid="retail-saveOffer-button"
      class="button"
      nxButton="block secondary"
      (click)="saveOffer()"
      [attr.trackId]="'btn_SaveOffer'"
      [attr.trackValue]="'saveOffer'"
      i18n="@@page-action.save-offer-button-label"
      *aclTag="(pageId$ | async) + '/save-offer-button'"
    >
      Save and email proposal
    </button>
    } @if (pageActionStatus?.customActions?.length) { @for (customAction of
    pageActionStatus?.customActions; track customAction.id) {
    <button
      [attr.data-testid]="'retail-' + customAction.id + '-button'"
      class="button"
      nxButton="block secondary"
      (click)="triggerCustomAction(customAction)"
      [attr.trackId]="'btn_' + customAction.id"
      [attr.trackValue]="customAction.id"
      *aclTag="(pageId$ | async) + '/' + customAction.id"
    >
      @if (customAction.icon) {
      <nx-icon [name]="customAction.icon" nxIconPositionStart></nx-icon>
      }
      {{ customAction.label }}
    </button>
    } } @if (!pageActionStatus?.backHidden) {
    <button
      data-testid="retail-back-button"
      class="button"
      nxPlainButton
      (click)="navigateBack()"
      [attr.trackId]="'btn_Nav'"
      [attr.trackValue]="'backward'"
      [disabled]="pageActionStatus?.backDisabled"
      *aclTag="(pageId$ | async) + '/back-button'"
    >
      <nx-icon name="arrow-left" nxIconPositionStart></nx-icon
      >{{ (backButtonLabel | conditionalLabel | async) || defaultBackLabel }}
    </button>
    }
  </div>
</ng-template>
<ng-template #defaultExpertTemplate>
  <div class="buttons-container" [class.has-margin]="hasMargin">
    <div class="extra-button-container">
      @if (pageActionStatus?.showCancelButton) {
      <button
        data-testid="expert-cancel-button"
        nxPlainButton
        (click)="cancel()"
        [attr.trackId]="'btn_Cancel'"
        [attr.trackValue]="'cancel'"
        *aclTag="(pageId$ | async) + '/cancel-button'"
      >
        <nx-icon name="close" nxIconPositionStart></nx-icon>
        {{ (cancelButtonLabel | conditionalLabel | async) || defaultCancelLabel }}
      </button>
      } @if (pageActionStatus?.showSaveOfferButton) {
      <button
        data-testid="expert-saveOffer-button"
        class="button"
        nxPlainButton
        (click)="saveOffer()"
        [attr.trackId]="'btn_SaveOffer'"
        [attr.trackValue]="'saveOffer'"
        *aclTag="(pageId$ | async) + '/save-offer-button'"
      >
        <nx-icon name="save-o" nxIconPositionStart></nx-icon>
        <ng-container i18n="@@page-action.save-offer-button-label">
          Save and email proposal
        </ng-container>
      </button>
      } @if (pageActionStatus?.customActions?.length) { @for (customAction of
      pageActionStatus?.customActions; track customAction.id) {
      <button
        [attr.data-testid]="'expert-' + customAction.id + '-button'"
        class="button"
        nxPlainButton
        (click)="triggerCustomAction(customAction)"
        [attr.trackId]="'btn_' + customAction.id"
        [attr.trackValue]="customAction.id"
        *aclTag="(pageId$ | async) + '/' + customAction.id"
      >
        @if (customAction.icon) {
        <nx-icon [name]="customAction.icon" nxIconPositionStart></nx-icon>
        }
        {{ customAction.label }}
      </button>
      } }
    </div>
    <div class="action-button-container">
      @if (!pageActionStatus?.nextHidden) {
      <button
        data-testid="expert-next-button"
        class="button"
        nxButton="primary small-medium"
        (click)="navigateNext()"
        [attr.trackId]="'btn_Nav'"
        [attr.trackValue]="'forward'"
        [disabled]="pageActionStatus?.nextDisabled"
        *aclTag="(pageId$ | async) + '/next-button'"
      >
        {{ (nextButtonLabel | conditionalLabel | async) || defaultNextLabel }}
      </button>
      } @if (!pageActionStatus?.backHidden) {
      <button
        data-testid="expert-back-button"
        class="button"
        [nxButton]="
          pageActionStatus?.backButtonUseTertiaryStyle
            ? 'tertiary small-medium'
            : 'secondary small-medium'
        "
        (click)="navigateBack()"
        [attr.trackId]="'btn_Nav'"
        [attr.trackValue]="'backward'"
        [disabled]="pageActionStatus?.backDisabled"
        *aclTag="(pageId$ | async) + '/back-button'"
      >
        {{ (backButtonLabel | conditionalLabel | async) || defaultBackLabel }}
      </button>
      }
    </div>
  </div>
</ng-template>
     
    
                
                @use '../../../styles/breakpoints.scss' as *;
@use '../../../styles/spacing.scss' as *;
:host {
  display: block;
  padding-block: var(--vertical-outer-section-spacing);
  width: 100%;
  > .action-button-container.has-margin,
  > .buttons-container.has-margin {
    @include frame-spacing;
  }
  .action-button-container {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    gap: 32px;
    width: 100%;
    @media (min-width: $breakpoint-m) {
      margin-inline: auto;
      min-width: 256px;
      width: max-content;
    }
  }
}
:host-context(.is-stacked),
:host-context(.is-centered) {
  .buttons-container {
    margin-inline: auto;
  }
}
// removes padding-bottom if no buttons are visible
:host(.expert-layout):has(.buttons-container .extra-button-container:empty):has(
    .buttons-container .action-button-container:empty
  ) {
  padding-bottom: 0;
}
:host(.retail-layout):has(.action-button-container:empty) {
  padding-bottom: 0;
}
:host(.no-spacing) {
  padding-bottom: 0;
}
:host(.retail-layout.no-spacing):has(.action-button-container:empty),
:host(.expert-layout.no-spacing):has(.buttons-container .extra-button-container:empty):has(
    .buttons-container .action-button-container:empty
  ) {
  padding: 0;
}
:host(.expert-layout) {
  .buttons-container {
    display: flex;
    justify-content: space-between;
  }
  .extra-button-container {
    display: flex;
    gap: 32px;
    width: 100%;
  }
  .action-button-container {
    justify-content: flex-start;
    align-items: flex-end;
    flex-direction: row-reverse;
    gap: 16px;
    margin-left: 80px;
  }
  .button {
    min-width: 128px;
  }
}
.buttons-container.has-margin {
  max-width: 100%;
  width: var(--grid-max-width);
}
.button {
  margin: 0;
  min-width: 256px;
}
:host(:empty) {
  padding: 0;
}
     
    
        
        
            
                Legend
            
            
            
            
                Html element with directive