File

libs/common/frame/src/frame-parts/navigation/navigation.component.ts

Implements

OnInit OnChanges

Metadata

Index

Properties
Methods
Inputs
Outputs
HostBindings
Accessors

Constructor

constructor()

Inputs

hasJumpNavigationMenu
Type : boolean
Default value : false
navigationConfig
Type : NavigationConfig

Outputs

resizeEvent
Type : EventEmitter

HostBindings

class.is-collapsed
Type : boolean
Default value : false
class.is-stacked
Type : boolean
Default value : false

Methods

gotoSection
gotoSection(id: string)
Parameters :
Name Type Optional
id string No
Returns : void
onResize
onResize(value: number)
Parameters :
Name Type Optional
value number No
Returns : void

Properties

currentSectionStates
Type : SectionWithState[]
frameLayoutService
Default value : inject(TalyFrameLayoutService)
frameNavigationService
Default value : inject(TalyFrameNavigationService, { optional: true })
isCollapsed
Default value : false
Decorators :
@HostBinding('class.is-collapsed')
isForbidden
Default value : false
isStacked
Default value : false
Decorators :
@HostBinding('class.is-stacked')
talyPageDataService
Default value : inject(TalyPageDataService)
toggleButtonLabel
Type : object
Default value : { collapsed: $localize`:@@frame.navigation.progress-indicator.toggle.collapsed:show progress indicator`, expanded: $localize`:@@frame.navigation.progress-indicator.toggle.expanded:hide progress indicator` }

Accessors

hasService
gethasService()
import { TalyPageDataService } from '@allianz/taly-core';
import {
  Component,
  DestroyRef,
  EventEmitter,
  HostBinding,
  inject,
  Input,
  OnChanges,
  OnInit,
  Output,
  SimpleChanges
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { LocalizeFn } from '@angular/localize/init';
import { TalyFrameLayoutService } from '../../services/frame-layout.service';
import { TalyFrameNavigationService } from '../../services/taly-frame-navigation-service';
import { NavigationConfig, SectionWithState } from './model';
import { StepState } from './navigation-step-state';

declare let $localize: LocalizeFn;

@Component({
  selector: 'frame-navigation',
  templateUrl: './navigation.component.html',
  styleUrls: ['./navigation.component.scss'],
  standalone: false
})
export class NavigationComponent implements OnInit, OnChanges {
  frameLayoutService = inject(TalyFrameLayoutService);
  talyPageDataService = inject(TalyPageDataService);
  frameNavigationService = inject(TalyFrameNavigationService, { optional: true });

  @HostBinding('class.is-stacked')
  isStacked = false;

  @HostBinding('class.is-collapsed')
  isCollapsed = false;

  @Input()
  @HostBinding('class.has-jump-menu')
  hasJumpNavigationMenu = false;

  @Input() navigationConfig?: NavigationConfig;

  @Output() resizeEvent = new EventEmitter();

  currentSectionStates!: SectionWithState[];

  isForbidden = false;

  // used in the template as aria-labels
  toggleButtonLabel = {
    collapsed: $localize`:@@frame.navigation.progress-indicator.toggle.collapsed:show progress indicator`,
    expanded: $localize`:@@frame.navigation.progress-indicator.toggle.expanded:hide progress indicator`
  };

  private destroyRef = inject(DestroyRef);

  constructor() {
    this.frameLayoutService.isStackedLayoutObservable
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((value) => (this.isStacked = value));
    this.frameLayoutService.collapseNavigationUser$
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((value) => (this.isCollapsed = value));
    this.frameNavigationService?.currentSectionStates$
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((value) => (this.currentSectionStates = value));
    this.talyPageDataService.pageData$
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((value) => {
        this.isForbidden = value.navigation?.preventClickNavigation ?? false;
      });
  }

  ngOnInit() {
    // we check for the jumpNavigationMenu configuration first because sections are always set
    // (even if not defined in the journey configuration because we extract them from the page list)
    if (this.hasJumpNavigationMenu) return;

    this.frameNavigationService?.setSections(this.navigationConfig?.sections);
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes['navigationConfig']?.firstChange === false) {
      this.frameNavigationService?.setSections(this.navigationConfig?.sections);
    }
  }

  gotoSection(id: string) {
    const ALLOWED_STATES_FOR_NAVIGATE = [StepState.COMPLETE, StepState.CURRENT];
    const targetSection = this.currentSectionStates.find((section) => section.sectionId === id);
    if (
      !this.isForbidden &&
      targetSection?.state &&
      ALLOWED_STATES_FOR_NAVIGATE.includes(targetSection.state)
    ) {
      this.frameNavigationService?.gotoSection(id);
    }
  }

  get hasService() {
    return !!this.frameNavigationService;
  }

  onResize(value: number) {
    this.resizeEvent.next(value);
  }
}
@if (hasService) {
<div class="toggle">
  <button
    nxButton="tertiary small"
    (click)="frameLayoutService.toggleNavigation()"
    class="toggle-button"
    [attr.aria-label]="isCollapsed ? toggleButtonLabel.collapsed : toggleButtonLabel.expanded"
  >
    <nx-icon name="chevron-left-small" class="chevron-icon"></nx-icon>
    <nx-icon name="chevron-left-small" class="chevron-icon"></nx-icon>
  </button>
</div>
@if (hasJumpNavigationMenu) {
<frame-jump-navigation-menu
  data-testid="jump-menu"
  [jumpNavigationMenu]="navigationConfig!.jumpNavigationMenu!"
  (resizeEvent)="onResize($event)"
></frame-jump-navigation-menu>
} @else {
<frame-navigation-view
  (goto)="gotoSection($event)"
  [sections]="(frameNavigationService?.visibleSections$ | async) ?? undefined"
  [sectionStates]="(frameNavigationService?.currentSectionStates$ | async) ?? []"
  [compact]="(frameLayoutService.compactNavigationBreakpoint$ | async)!"
  [horizontal]="isStacked"
  [collapsed]="(frameLayoutService.collapseNavigationUser$ | async)!"
  class="navigation"
  [isForbidden]="isForbidden"
>
</frame-navigation-view>
} } @else {
<strong>⚠️ Action required</strong>
<br />There is no <code>FrameNavigationService</code> implementation given. Please read the
documentation to provide one. }

./navigation.component.scss

@use '../../../styles/spacing.scss' as *;

:host {
  display: block;
  position: sticky;
  top: var(--header-height);
}

.toggle {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 24px;
}

:host-context(.is-stacked) {
  max-width: 100%;
  width: var(--grid-max-width);
  margin-left: auto;
  margin-right: auto;
  @include frame-spacing;
}

:host(.is-stacked) .toggle {
  display: none;
}

:host:not(.is-stacked) {
  padding: 16px;
  padding-left: 32px;
}

:host(.is-collapsed) {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0;
  padding-top: 16px;

  .toggle-button {
    transform: rotate(180deg);
  }
}

:host(.has-jump-menu) {
  // z-index added for the nx-sidebar handle to be clickable
  z-index: 10;
  padding: 0;
  height: calc(100vh - var(--header-height));

  .toggle {
    display: none;
  }
}

:host .toggle-button {
  cursor: pointer;
  width: var(--button-small-medium-height);
  padding: 0;
  margin: 0;

  .chevron-icon {
    font-size: 24px;
  }

  .chevron-icon:last-child {
    margin-left: -18px;
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""