assets-navigator/asset-selector/asset-selector.component.ts
Displays a hierarchical tree selector for assets.
| providers | {
    provide: NG_VALUE_ACCESSOR, multi: true, useExisting: forwardRef(() => AssetSelectorComponent)
}{
    provide: NG_VALIDATORS, useExisting: forwardRef(() => AssetSelectorComponent), multi: true
} | 
| selector | c8y-asset-selector | 
| templateUrl | ./asset-selector.component.html | 
| Properties | 
| Methods | 
| 
 | 
| Inputs | 
| Outputs | 
| active | 
| Type : GroupNode | 
| Defines the node, which should be displayed as active. | 
| asset | 
| Type : IIdentified | 
| Default value : undefined | 
| The asset to use as root. | 
| config | 
| Type : AssetSelectorOptions | 
| Default value : {} | 
| Config object containing all options for the asset selector. | 
| container | 
| Type : string | "body" | 
| Default value : 'body' | 
| index | 
| Type : number | 
| Default value : 0 | 
| Used only for miller-view, displays the column level for the current node. E.g if the index is one, this will be second column. | 
| rootNode | 
| Type : GroupNode | 
| The node to use as root. You can either set this, or the asset to start from. | 
| selected | 
| Type : Array<Partial<IManagedObject>> | IIdentified[] | IIdentified | 
| Default value : [] | 
| An array of predefined nodes. | 
| selectedDevice | 
| Type : IManagedObject | 
| Default value : undefined | 
| The selected device. | 
| selectedItems | 
| Type : IIdentified[] | IIdentified | 
| Default value : [] | 
| All currently selected assets. | 
| onLoad | 
| Type : EventEmitter | 
| Emits the current loading state of the node. | 
| onRowSelected | 
| Type : EventEmitter | 
| Used only for miller view. Emit the selected node and use it as a 'rootNode' for the new column. | 
| onSelected | 
| Type : EventEmitter | 
| Emits if one item was selected (all currently selected nodes). | 
| Async applyFilter | ||||||||
| applyFilter(filter: string) | ||||||||
| Applies a filter. 
                        Parameters :
                        
                         
 
                        Returns :          any | 
| back | 
| back() | 
| Changes the current root to one level back. 
                        Returns :          void | 
| clearFilters | 
| clearFilters() | 
| Clears the current filter. 
                        Returns :          void | 
| clearSelectedDevices | 
| clearSelectedDevices() | 
| 
                        Returns :          void | 
| groupNameFilter | 
| groupNameFilter(nameFilter: string, moId, showUnassignedDevices?: boolean) | 
| 
                        Returns :          any | 
| handleNextMillerViewColumn | ||||||||||||
| handleNextMillerViewColumn(node: GroupNode, index: number) | ||||||||||||
| Checks when a node was selected, if a new column needs to be added. 
                        Parameters :
                        
                         
 
                        Returns :          booleanTrue if the click was handled and a new column was added. | 
| isGroupSelected | 
| isGroupSelected() | 
| 
                        Returns :          boolean | 
| isUnassignedDevicesNode | 
| isUnassignedDevicesNode() | 
| Check if the UnassignedDevice node is the rootNode. 
                        Returns :          boolean | 
| Async ngOnChanges | ||||||
| ngOnChanges(changes: SimpleChanges) | ||||||
| 
                        Parameters :
                        
                         
 
                        Returns :          any | 
| Async onSearchResultClick | ||||||
| onSearchResultClick(mo: IManagedObject) | ||||||
| Called if the user clicks on a search result. 
                        Parameters :
                        
                         
 
                        Returns :          any | 
| onSearchResultReset | ||||||
| onSearchResultReset(term: string) | ||||||
| Called when the user resets the search result. 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| createDefaultRootNode | 
| createDefaultRootNode() | 
| 
                        Returns :          any | 
| Async createManagedObjectRootNode | ||||||
| createManagedObjectRootNode(asset: IIdentified) | ||||||
| 
                        Parameters :
                        
                         
 
                        Returns :      unknown | 
| deselect | ||||||||
| deselect(selectedMo: IManagedObject) | ||||||||
| Removes a managed object from the selected array and emits the change. 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| deselectAll | ||||||||
| deselectAll(selectedMo?: IManagedObject) | ||||||||
| Deselects all expect the given one. 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| emitChange | ||||||||||||
| emitChange(selected: IIdentified | IIdentified[], item: IManagedObject, isSelected: boolean) | ||||||||||||
| 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| getIndexOfSelected | ||||||||||||
| getIndexOfSelected(selected: Array | ||||||||||||
| Returns the index of the currently selected item. 
                        Parameters :
                        
                         
 
                        Returns :          anyAn index, or -1 if not found. | 
| select | ||||||||
| select(selectedMo: IManagedObject) | ||||||||
| Adds an managed object to the selected array and emits the change. 
                        Parameters :
                        
                         
 
                        Returns :          void | 
| filterText | 
| Type : string | 
| Default value : '' | 
| The current filter applied. | 
| root | 
| Type : boolean | 
| Default value : false | 
| Displays the global search at all times if the miller view is used on root group level. | 
| config | 
| Type : AssetSelectorOptions | 
| Default value : {} | 
| Config object containing all options for the asset selector. | 
| isLoading | 
| Type : boolean | 
| Default value : false | 
| The loading state of the current node. | 
| onSelected | 
| Default value : new EventEmitter<AssetSelectionChangeEvent>() | 
| Emit the selected asset or assets. | 
| selected | 
| Type : Array<Partial<IManagedObject>> | IIdentified[] | IIdentified | 
| An array of predefined nodes. | 
<div
  class="p-b-8 bg-inherit"
  [ngClass]="{ 'p-l-16 p-absolute p-r-16': config.view === 'miller' }"
  style="left: 0; right: 4px"
  [ngStyle]="{ 'z-index': config.singleColumn ? '30' : '20' }"
  *ngIf="!selectedDevice && index === 0 && (config.search || config.singleColumn)"
>
  <p class="text-medium m-b-4 p-t-8">
    {{ config.label | translate }}
  </p>
  <c8y-search-input
    *ngIf="config.search && root"
    (onClick)="onSearchResultClick($event)"
    (reset)="onSearchResultReset($event)"
    [mode]="'select'"
    [container]="container"
  ></c8y-search-input>
</div>
<div *ngIf="selectedDevice" class="p-r-16">
  <div class="d-flex p-b-4">
    <p *ngIf="selectedDevice; else multiAssets" class="text-medium p-t-8 m-r-8">
      {{ 'Selected asset' | translate }}
    </p>
    <ng-template #multiAssets>
      <p class="text-medium m-r-8">{{ 'Selected assets' | translate }}</p>
    </ng-template>
    <button
      class="btn btn-default btn-xs a-s-center m-t-4 m-l-auto"
      (click)="clearSelectedDevices()"
      title="{{ 'Edit' | translate }}"
    >
      {{ 'Change' | translate }}
    </button>
  </div>
  <div class="d-flex">
    <i [c8yIcon]="'check-circle'" class="text-success p-l-0 p-r-8"></i>
    <i
      c8yIcon="{{ selectedDevice.type === 'c8y_DeviceGroup' ? 'c8y-group' : 'exchange' }}"
      class="m-r-4 icon-20"
    ></i>
    <span>{{ selectedDevice.name }}</span>
  </div>
</div>
<!-- miller columns header -->
<div
  *ngIf="
    config.view === 'miller' &&
    ((config.showFilter && !rootNode.root) || config.columnHeaders || config.singleColumn) &&
    !selectedDevice
  "
  class="miller-column__header sticky-top bg-inherit separator-top-bottom"
  [ngClass]="{ 'm-t-72 ': config.search, 'm-t-32': !config.search && config.singleColumn }"
  [ngStyle]="{ top: config.search && !config.singleColumn ? '72px' : '0' }"
>
  <p
    class="text-12 text-muted text-truncate m-b-4"
    *ngIf="config.singleColumn && index !== 0"
    title="{{ rootNode.breadcrumb || rootNode.label | translate }}"
  >
    <i c8yIcon="home" class="m-r-4"></i>
    {{ rootNode.breadcrumb || rootNode.label | translate }}
  </p>
  <div *ngIf="config.columnHeaders || config.singleColumn" class="d-flex a-i-center p-b-4">
    <button
      class="btn btn-default btn-xs m-r-8 p-t-0 p-b-0 p-l-4 p-r-4 l-h-1"
      *ngIf="config.singleColumn && !rootNode.root && index !== 0"
      title="{{ 'Back' | translate }}"
      (click)="back()"
    >
      <i c8yIcon="angle-left"></i>
    </button>
    <label
      *ngIf="!rootNode.root && index === 0 && (config.groupsSelectable || !rootNode.isGroup())"
      class="c8y-radio checkbox-inline m-r-8"
    >
      <input
        type="radio"
        (change)="select(rootNode.mo)"
        [checked]="isGroupSelected()"
        title="{{ 'Select group' | translate }}"
      /><span></span>
    </label>
    <p
      class="text-truncate"
      title="{{ rootNode.label | translate }}"
      *ngIf="config.columnHeaders"
      [ngClass]="{
        'text-label-small': !config.singleColumn,
        'text-medium': config.singleColumn
      }"
    >
      <i
        *ngIf="config.singleColumn || (!rootNode.root && index === 0)"
        c8yIcon="c8y-group-open"
        class="icon-20 c8y-icon-duocolor m-r-4"
      ></i>
      {{ rootNode.label | translate }}
    </p>
  </div>
  <div *ngIf="!rootNode.root && config.showFilter" [ngClass]="{ 'p-t-4': config.columnHeaders }">
    <div class="input-group input-group-sm input-group-search">
      <input
        [(ngModel)]="filterText"
        placeholder="{{ 'Filter this column…' | translate }}"
        class="form-control"
        (keyup.enter)="applyFilter('*' + filterText + '*')"
      />
      <span class="input-group-btn">
        <button
          title="{{ 'Apply filter' | translate }}"
          class="btn btn-clean p-r-8 p-l-4"
          (click)="applyFilter('*' + filterText + '*')"
        >
          <i c8yIcon="filter"></i>
        </button>
        <button
          title=" {{ 'Clear filters' | translate }}"
          class="btn btn-clean p-r-8 p-l-4"
          (click)="clearFilters()"
          *ngIf="filterText.length"
        >
          <i c8yIcon="times"></i>
        </button>
      </span>
    </div>
  </div>
</div>
<c8y-asset-selector-node
  *ngIf="rootNode && !selectedDevice"
  [node]="rootNode"
  [preselected]="selected"
  [multi]="config.multi"
  [view]="config.view"
  [index]="index"
  [selectedItems]="selectedItems"
  [active]="active"
  class="d-block bg-inherit p-relative"
  [ngClass]="{ 'collapse show': !rootNode.root && !rootNode.hidden && config.view !== 'miller' }"
  style="z-index: 9"
></c8y-asset-selector-node>