File

core/navigator/navigator-node.component.ts

Description

Navigator node renderer.

Implements

AfterViewInit OnChanges OnDestroy

Metadata

Index

Properties
Methods
Inputs
Outputs
Accessors

Constructor

constructor(router: Router)
Parameters :
Name Type Optional
router Router No

Inputs

isRoot
Type : boolean

Determines whether the navigator node is a root node (top node in the hierarchy).

node
Type : NavigatorNode

Navigator node.

Outputs

nodeClick
Type : EventEmitter<string>

Event emitter responsible for broadcasting one of the following events: "icon", "expander" or "link" as string value.

The type of event depends on where you click on the navigator node:

  • clicking the icon will broadcast the event "icon",
  • clicking the expander will broadcast the event "expander",
  • clicking the label will broadcast the event "link".

Methods

click
click(from: "icon" | "expander" | "link", $event?: MouseEvent)

Click event handler.

Parameters :
Name Type Optional Default value Description
from "icon" | "expander" | "link" No 'link'

Source of the click event.

$event MouseEvent Yes
Returns : void
expandCollapse
expandCollapse(open: unknown, forNode: ClickOptions)

Expands or collapses the navigator node and its children recursively.

Parameters :
Name Type Optional Default value Description
open unknown No

Open or close the node.

forNode ClickOptions No {}

Click options.

Returns : void
expandRecursiveParent
expandRecursiveParent(nodes: NavigatorNode[], clickOption: ClickOptions)

Expands the parent nodes recursively.

Parameters :
Name Type Optional Default value Description
nodes NavigatorNode[] No

The nodes that should be tried to get opened.

clickOption ClickOptions No { expander: true }

The click options to perform on the parent nodes.

Returns : void
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : void

Properties

isActive$
Type : unknown
Default value : merge( this.nodeInit$, this.router.events.pipe(filter(e => e instanceof ActivationEnd)) ).pipe( map(() => { if (isUndefined(this.node.path)) { return false; } // on exact match, for empty routes '' we need a special // handling as there seems to be a bug with angular, as it // does not show the primary outlet in this cases. const currentUrlTree = this.router.parseUrl(this.router.url); if ( this.node.routerLinkExact && !currentUrlTree.root.children['primary'] && this.node.path === '/' ) { return true; } return this.router.isActive(this.node.path, { paths: this.node.routerLinkExact ? 'exact' : 'subset', queryParams: 'ignored', fragment: 'ignored', matrixParams: 'ignored' }); }), distinctUntilChanged(), tap(isActive => { if (isActive) { this.expandCollapse(true); this.expandRecursiveParent(this.node.parents); } }) )

A observable which emits, as soon as the active state of the node changes.

nodeInit$
Type : unknown
Default value : new Subject<void>()

A subject that is triggered as soon as the navigator node is initialized.

Accessors

expandTitle
getexpandTitle()

Returns the expander title.

@if (node.component) {
  <ng-container
    *c8yComponentOutlet="node.component; environmentInjector: node.injector"
  ></ng-container>
}

@if (!node.component) {
  <div
    class="slot"
    [hidden]="node.hidden"
    (dragstart)="node.dragStart($event)"
    (dragend)="node.dragEnd($event)"
    (drop)="node.drop($event)"
    [draggable]="node.draggable"
    [ngClass]="{ dragged: node.dragged, disabled: node.loading }"
  >
    <ng-container>
      <div
        class="link"
        tabindex="-1"
        [routerLink]="node.canNavigate ? node.path : undefined"
        [ngClass]="{
          active: isActive$ | async,
          'dragged-hover': node.draggedHover && !node.dragged
        }"
        (dragover)="node.canDrop && $event.preventDefault()"
        (dragenter)="node.canDrop && node.dragEnter($event)"
        (dragleave)="node.canDrop && node.dragLeave($event)"
      >
        <ng-container *ngTemplateOutlet="navicon"></ng-container>
        <button
          class="btn-clean"
          title="{{ node.translateLabel ? (node.label | translate) : node.label }}"
          [attr.aria-expanded]="node.hasChildren ? node.open : null"
          type="button"
          draggable="false"
          [attr.data-cy]="node.label"
          [attr.id]="isRoot ? node.id : undefined"
          (click)="click(node.canNavigate ? 'link' : 'expander', $event)"
          [ngClass]="{
            'root-link': isRoot,
            open: node.open && node.hasChildren,
            parent: node.hasChildren
          }"
        >
          <ng-container *ngTemplateOutlet="inner"></ng-container>
        </button>
      </div>
    </ng-container>
    @if (node.children.length) {
      <div
        class="children panel-expand expand"
        [collapse]="!node.open"
        [isAnimated]="true"
      >
        @for (childNode of node.children; track childNode) {
          <c8y-navigator-node
            [node]="childNode"
            (nodeClick)="nodeClick.emit($event)"
          ></c8y-navigator-node>
        }
      </div>
    }
  </div>
}

<!-- icon -->
<ng-template #navicon>
  <!-- loader -->
  @if (node.loading && !isRoot) {
    <i
      class="icon-spin loadingIndicator"
      [c8yIcon]="'circle-o-notch'"
      [ngClass]="{ 'm-l-16': isRoot, 'm-l-8': !isRoot }"
    ></i>
  }
  <ng-container #icon></ng-container>
</ng-template>

<ng-template #inner>
  <!--title  -->
  <span>{{ node.translateLabel ? (node.label | translate) : node.label }}</span>

  <!--expander  -->
  @if (node.hasChildren) {
    <i
      class="expander"
      [c8yIcon]="'chevron-down'"
      [attr.aria-label]="expandTitle"
      role="button"
      (click)="click('expander', $event)"
      data-cy="c8y-navigator-node--expander"
    ></i>
  }

  <!--  Popover confirm  -->
  <c8y-popover-confirm
    triggers="focus"
    containerClass="navigator-popover"
  ></c8y-popover-confirm>
</ng-template>

results matching ""

    No results matching ""