File

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

Implements

OnInit

Metadata

Index

Properties
Methods
Inputs
Outputs
HostBindings
Accessors

Constructor

constructor(frameLayoutService: TalyFrameLayoutService, talyPageDataService: TalyPageDataService, frameNavigationService: TalyFrameNavigationService)
Parameters :
Name Type Optional
frameLayoutService TalyFrameLayoutService No
talyPageDataService TalyPageDataService No
frameNavigationService TalyFrameNavigationService No

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[]
Public frameLayoutService
Type : TalyFrameLayoutService
Public frameNavigationService
Type : TalyFrameNavigationService
Decorators :
@Optional()
isCollapsed
Default value : false
Decorators :
@HostBinding('class.is-collapsed')
isForbidden
Default value : false
isStacked
Default value : false
Decorators :
@HostBinding('class.is-stacked')
Public talyPageDataService
Type : 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,
  Input,
  OnInit,
  Optional,
  Output,
  inject
} 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 {
  @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(
    public frameLayoutService: TalyFrameLayoutService,
    public talyPageDataService: TalyPageDataService,
    @Optional() public frameNavigationService: TalyFrameNavigationService
  ) {
    frameLayoutService.isStackedLayoutObservable
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((value) => (this.isStacked = value));
    frameLayoutService.collapseNavigationUser$
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((value) => (this.isCollapsed = value));
    frameNavigationService.currentSectionStates$
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((value) => (this.currentSectionStates = value));
    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);
  }

  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);
  }
}
<ng-container *ngIf="hasService; else noService">
  <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)!"
    [sectionStates]="(frameNavigationService.currentSectionStates$ | async)!"
    [compact]="(frameLayoutService.compactNavigationBreakpoint$ | async)!"
    [horizontal]="isStacked"
    [collapsed]="(frameLayoutService.collapseNavigationUser$ | async)!"
    class="navigation"
    [isForbidden]="isForbidden"
  >
  </frame-navigation-view>
  }
</ng-container>

<ng-template #noService>
  <strong>⚠️ Action required</strong>
  <br />There is no <code>FrameNavigationService</code> implementation given. Please read the
  documentation to provide one.
</ng-template>

./navigation.component.scss

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

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

: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 ""