All files / list-details/si-details-pane-header si-details-pane-header.component.ts

100% Statements 20/20
100% Branches 4/4
100% Functions 7/7
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100                                                                1x 21x         21x                 21x                   21x               21x   21x 21x 21x   21x     21x 27x 6x 6x   6x             48x       4x       1x          
/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
import {
  booleanAttribute,
  ChangeDetectionStrategy,
  Component,
  ElementRef,
  inject,
  input,
  Signal,
  viewChild
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { ActivatedRoute, Router } from '@angular/router';
import { SiTranslatePipe, t, TranslatableString } from '@siemens/element-translate-ng/translate';
 
import { SiDetailsPaneComponent } from '../si-details-pane/si-details-pane.component';
import { SiListDetailsComponent } from '../si-list-details.component';
 
/** @experimental */
@Component({
  selector: 'si-details-pane-header',
  imports: [SiTranslatePipe],
  templateUrl: './si-details-pane-header.component.html',
  styleUrl: './si-details-pane-header.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: {
    class: 'nav nav-tabs' // To allow nav-link styling.
  }
})
export class SiDetailsPaneHeaderComponent {
  private parent = inject(SiListDetailsComponent);
 
  /**
   * Optional title to be displayed.
   */
  readonly title = input<TranslatableString>();
 
  /**
   * You can hide the back button in the mobile view by setting true. Required
   * in add, edit workflows on mobile sizes. During add or edit, the back button
   * should be hidden. Default value is `false`.
   *
   * @defaultValue false
   */
  readonly hideBackButton = input(false, { transform: booleanAttribute });
 
  /**
   * Details back button text. Required for a11y.
   *
   * @defaultValue
   * ```
   * t(() => $localize`:@@SI_LIST_DETAILS.BACK:Back`)
   * ```
   */
  readonly backButtonText = input(t(() => $localize`:@@SI_LIST_DETAILS.BACK:Back`));
 
  /**
   * The URL to navigate to when the back buttons is clicked.
   * This is only used when the `si-details-pane` is used with a router-outlet.
   *
   * @defaultValue '../'
   */
  readonly backButtonUrl = input('../');
 
  private isRouterBased = inject(SiDetailsPaneComponent).isRouterBased;
  private router = inject(Router, { optional: true });
  private activatedRoute = inject(ActivatedRoute, { optional: true });
 
  private readonly backButton = viewChild<ElementRef<HTMLElement>>('backButton');
 
  constructor() {
    this.parent.transferFocusToDetails.pipe(takeUntilDestroyed()).subscribe(shouldFocus => {
      if (shouldFocus) {
        const backButton = this.backButton();
        if (backButton) {
          // Needed so it's no longer "inert" and loaded.
          setTimeout(() => backButton?.nativeElement?.focus());
        }
      }
    });
  }
 
  protected get hasLargeSize(): Signal<boolean> {
    return this.parent.hasLargeSize;
  }
 
  protected backClicked(): void {
    this.parent.detailsBackClicked({
      animationDone: this.isRouterBased()
        ? // We navigate back after the animation is done.
          // This ensures, that the details pane visible while animating.
          () => this.router!.navigate([this.backButtonUrl()], { relativeTo: this.activatedRoute })
        : undefined
    });
  }
}