File

core/search/search-input.component.ts

Metadata

Index

Properties
Methods
Inputs
Outputs
HostListeners
Accessors

Constructor

constructor(router: Router, inventory: InventoryService, inventorySearchService: InventorySearchService, cd: ChangeDetectorRef)
Parameters :
Name Type Optional
router Router No
inventory InventoryService No
inventorySearchService InventorySearchService No
cd ChangeDetectorRef No

Inputs

container
Type : string | "body"
Default value : ''
customDataQuery
Type : UnaryFunction<string, Observable<IResultList<IManagedObject>>>

A custom query setter used to override the standard query. In order to obtain data.

customPlaceholder
Type : string

A custom placeholder in the search bar.

enableCustomTemplatePlaceholder
Type : boolean
Default value : false

Unlocks the ability to place a custom template under the search input.

externalTerm
Type : EventEmitter<string>

Event, which is used to set a new external term. Passing null will re-execute the query to BE. This allows new filters to be applied to the currently selected term.

groupsOnly
Type : boolean
Default value : false
mode
Type : "search" | "select" | "wildcardsearch"
Default value : 'search'

Outputs

filter
Type : EventEmitter
onClick
Type : EventEmitter
onOpenToggle
Type : EventEmitter
reset
Type : EventEmitter
search
Type : EventEmitter

HostListeners

document:keydown
Arguments : '$event'
document:keydown(event: KeyboardEvent)

Methods

keyDown
keyDown(event: KeyboardEvent)
Parameters :
Name Type Optional
event KeyboardEvent No
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
Async ngOnInit
ngOnInit()
Returns : any
onFilter
onFilter(search: string)
Parameters :
Name Type Optional
search string No
Returns : void
onKeydownHandler
onKeydownHandler(event: KeyboardEvent)
Decorators :
@HostListener('document:keydown', ['$event'])
Parameters :
Name Type Optional
event KeyboardEvent No
Returns : void
onOpenAssetTable
onOpenAssetTable()
Returns : void
onOpenChange
onOpenChange(isOpen: boolean)
Parameters :
Name Type Optional
isOpen boolean No
Returns : void
onReset
onReset(status: literal type)
Parameters :
Name Type Optional
status literal type No
Returns : void
onSearch
onSearch(search: string)
Parameters :
Name Type Optional
search string No
Returns : void
open
open(event: Event, mo: IManagedObject, term?: unknown)
Parameters :
Name Type Optional
event Event No
mo IManagedObject No
term unknown Yes
Returns : void

Properties

customQuery
Type : function
defaultPlaceholder
Type : unknown
Default value : gettext('Search for groups or assets…')
deviceType
Type : unknown
Default value : ManagedObjectType
isLoading
Type : unknown
Default value : false
noMatch
Type : unknown
Default value : false
recentlyRegisteredResults$
Type : Observable<IResultList<IManagedObject>>
recentSearchResults
Type : IManagedObject[]
Default value : []
Readonly RESET_TEXT
Type : unknown
Default value : gettext('Clear search results')
results$
Type : Observable<IResultList<IManagedObject>>
Readonly SEARCH_TEXT
Type : unknown
Default value : gettext('Search')
selected
Type : unknown
term
Type : string
Default value : ''

Accessors

customDataQuery
setcustomDataQuery(query: UnaryFunction>>)

A custom query setter used to override the standard query. In order to obtain data.

Parameters :
Name Type Optional
query UnaryFunction<string | Observable<IResultList<IManagedObject>>> No
Returns : void
@if (mode === 'search' || mode === 'wildcardsearch') {
  <div
    class="dropdown"
    #searchDropdown="bs-dropdown"
    [insideClick]="true"
    (isOpenChange)="onOpenChange($event)"
    [cdkTrapFocus]="searchDropdown.isOpen"
    dropdown
  >
    <button
      class="main-header-button dropdown-toggle c8y-dropdown"
      [title]="'Search' | translate"
      type="button"
      dropdownToggle
      data-cy="search-input--search-btn"
    >
      <i
        class="icon-2x"
        c8yIcon="search"
      ></i>
    </button>

    <div
      class="search-header-menu dropdown-menu dropdown-menu-right"
      id="searchDropdown"
      *dropdownMenu
    >
      <ng-container *ngTemplateOutlet="form"></ng-container>
    </div>
  </div>
}

@if (mode === 'select') {
  <div class="search-header-inline">
    <ng-container *ngTemplateOutlet="form"></ng-container>
  </div>
}
<ng-template #form>
  <form
    [ngClass]="{ 'c8y-search-form': mode === 'search' || mode === 'wildcardsearch' }"
    novalidate
    #searchForm="ngForm"
  >
    <c8y-typeahead
      (onIconClick)="onReset($event)"
      [icon]="term ? 'times' : 'search'"
      [title]="(term ? RESET_TEXT : SEARCH_TEXT) | translate"
      placeholder="{{ customPlaceholder ? customPlaceholder : defaultPlaceholder }}"
      name="selected"
      [(ngModel)]="selected"
      (keydown)="keyDown($event)"
      [allowFreeEntries]="false"
      [container]="container"
      [highlightFirstItem]="false"
      [ngClass]="{ 'input-group-search input-group-lg': mode !== 'select' }"
    >
      @if (enableCustomTemplatePlaceholder) {
        <div>
          <ng-content></ng-content>
        </div>
      }

      <!-- filter buttons -->
      @if (term.length !== 0 && mode === 'search') {
        <c8y-li
          class="m-l-32 m-r-32"
          [selectable]="false"
        >
          <div class="d-flex">
            <p class="m-r-4 text-muted">
              <em translate>Searching by exact match. Click for other search options:</em>
            </p>
            <div class="btn-group btn-group-sm">
              <button
                class="btn btn-default"
                title="{{ 'Starts with' | translate }}"
                type="button"
                data-cy="search-input--search-starts-with"
                (click)="onFilter(term + '*')"
              >
                {{ 'Starts with' | translate }}
              </button>
              <button
                class="btn btn-default"
                title="{{ 'Contains' | translate }}"
                type="button"
                data-cy="search-input--search-contains"
                (click)="onFilter('*' + term + '*')"
              >
                {{ 'Contains' | translate }}
              </button>
              <button
                class="btn btn-default"
                title="{{ 'Ends with' | translate }}"
                type="button"
                data-cy="search-input--search-ends-with"
                (click)="onFilter('*' + term)"
              >
                {{ 'Ends with' | translate }}
              </button>
            </div>
          </div>
        </c8y-li>
      }

      <!-- Recent search -->
      @if (term.length === 0 && recentSearchResults.length > 0) {
        <c8y-li
          class="m-l-32 m-r-32"
          [selectable]="false"
        >
          <div class="legend">
            <span
              class="text-bold text-muted"
              translate
            >
              Recent search views
            </span>
          </div>
        </c8y-li>
      }
      @for (result of term.length === 0 ? recentSearchResults : []; track result.id) {
        <c8y-li
          class="c8y-list__item--link m-l-32 m-r-32"
          (click)="open($event, result, result.name)"
        >
          <c8y-li-icon>
            @if (result | shouldShowMo: deviceType.DEVICE) {
              <device-status [mo]="result"></device-status>
            } @else {
              <i
                class="c8y-icon-duocolor"
                [c8yIcon]="result | getGroupIcon | async"
              ></i>
            }
          </c8y-li-icon>
          {{ result.name || '--' }}
        </c8y-li>
      }

      <!-- Recently registered devices -->
      @if (
        term.length === 0 && (recentlyRegisteredResults$ | async)?.data?.length > 0 && !groupsOnly
      ) {
        <c8y-li
          class="m-l-32 m-r-32"
          [selectable]="false"
        >
          <div class="legend">
            <span
              class="text-bold text-muted"
              translate
            >
              Recently registered devices
            </span>
          </div>
        </c8y-li>
      }
      <c8y-li
        class="c8y-list__item--link m-l-32 m-r-32"
        *c8yFor="
          let result of term.length === 0 && !groupsOnly
            ? recentlyRegisteredResults$
            : { data: [] };
          loadMore: 'none'
        "
        (click)="open($event, result, result.name)"
      >
        <c8y-li-icon>
          @if (result | shouldShowMo: deviceType.DEVICE) {
            <device-status [mo]="result"></device-status>
          } @else {
            <i
              class="c8y-icon-duocolor"
              [c8yIcon]="result | getGroupIcon | async"
            ></i>
          }
        </c8y-li-icon>
        {{ result.name || '--' }}
      </c8y-li>

      <!-- Search results -->
      @if (term.length !== 0) {
        <c8y-li
          class="m-l-32 m-r-32"
          [selectable]="false"
        >
          <div class="legend">
            <span
              class="text-bold text-muted"
              translate
            >
              Search results
            </span>
          </div>
        </c8y-li>
      }
      <c8y-li
        class="c8y-list__item--link m-l-32 m-r-32"
        [title]="result.name"
        *c8yFor="
          let result of results$;
          loadMore: 'auto';
          notFound: notFoundTemplate;
          loadingTemplate: loading;
          loadNextLabel: 'Find more…'
        "
        (click)="open($event, result, result.name)"
        data-cy="search-input--search-results"
      >
        <c8y-li-icon>
          @if (result | shouldShowMo: deviceType.DEVICE) {
            <device-status [mo]="result"></device-status>
          } @else {
            <i
              class="c8y-icon-duocolor"
              [c8yIcon]="result | getGroupIcon | async"
            ></i>
          }
        </c8y-li-icon>
        {{ result.name || '--' }}
      </c8y-li>

      <!-- No search results found entry -->
      <ng-template #notFoundTemplate>
        @if (noMatch) {
          <c8y-ui-empty-state
            [icon]="'search'"
            [title]="'No match found.' | translate"
            data-cy="search-input--empty-state"
            [ngClass]="{ 'p-4': mode === 'search' || mode === 'wildcardsearch' }"
            [horizontal]="true"
          >
            @if (mode === 'search') {
              <small translate>
                Try to filter or open the asset grid to show all devices and groups.
              </small>
            }
            @if (mode === 'select' || mode === 'wildcardsearch') {
              <small translate>Try to rephrase your search word.</small>
            }
          </c8y-ui-empty-state>
        }
      </ng-template>

      <!-- loading bar first entries -->
      @if (isLoading) {
        <c8y-li>
          <c8y-loading></c8y-loading>
        </c8y-li>
      }

      <!-- loading bar for loading more entries (inventory roles) -->
      <ng-template #loading>
        <c8y-li>
          <c8y-loading></c8y-loading>
        </c8y-li>
      </ng-template>

      <!-- more filter possibilities -->
      @if (mode === 'search' || mode === 'wildcardsearch') {
        <c8y-li
          class="m-t-24 bg-level-2 p-t-16 p-b-16 p-l-24 p-r-24 sticky-bottom"
          [selectable]="false"
        >
          <div class="d-flex a-i-center">
            <i
              class="text-info m-r-4"
              c8yIcon="info-circle"
            ></i>
            <p
              class="m-r-8"
              translate
            >
              Need more filter possibilities?
            </p>
            <button
              class="m-l-16 btn btn-default btn-sm"
              title="{{ 'Go to the asset data table' | translate }}"
              type="button"
              (mousedown)="onOpenAssetTable()"
              data-cy="search-input--asset-table-btn"
            >
              {{ 'Go to the asset data table' | translate }}
            </button>
          </div>
        </c8y-li>
      }
    </c8y-typeahead>
  </form>
</ng-template>

results matching ""

    No results matching ""