@WidgetComponent

nm-rating-search

File

src/app/shared/widgets/search/rating-search-widget.component.ts

Implements

OnDestroy

Metadata

selector nm-rating-search
styleUrls rating-search-widget.component.scss
templateUrl ./rating-search-widget.component.html

Index

Widget inputs
Widget outputs
Properties
Methods

Constructor

constructor(translateService: TranslateService, appDataStore: AppdataStore, localstorageService: LocalStorageService, widgetframeService: WidgetframeService, appContext: AppContext, cd: ChangeDetectorRef)
Parameters :
Name Type Optional
translateService TranslateService no
appDataStore AppdataStore no
localstorageService LocalStorageService no
widgetframeService WidgetframeService no
appContext AppContext no
cd ChangeDetectorRef no

Methods

Public configureWidget
configureWidget(config: WidgetConfig)
Decorators : WidgetConfigure
Parameters :
Name Type Optional
config WidgetConfig<RatingSearchConfiguration> no
Returns : void
doSearch
doSearch()
Returns : void
Private initToolboxEdits
initToolboxEdits()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
onAdvancedSearchChanged
onAdvancedSearchChanged(data: any)
Parameters :
Name Type Optional
data any no
Returns : void
onAttributesChanged
onAttributesChanged(attributes: Attribute[])
Parameters :
Name Type Optional
attributes Attribute[] no
Returns : void
onExpandToggle
onExpandToggle($event: boolean)
Parameters :
Name Type Optional
$event boolean no
Returns : void
onModeChange
onModeChange()
Returns : void
onWorklistSelect
onWorklistSelect(worklist: )
Parameters :
Name Optional
worklist no
Returns : void
reset
reset()
Returns : void
searchListStringChange
searchListStringChange()
Returns : void
searchStringChange
searchStringChange()
Returns : void

Properties

Private advancedData
advancedData: any
Type : any
Public advancedSearch
advancedSearch: boolean
Type : boolean
Default value : false
Public attributesOutput
attributesOutput:
Default value : new Subject<Attribute[]>()
Decorators : WidgetOutput
Public bulkEdit
bulkEdit:
Default value : new Subject<any>()
Decorators : WidgetOutput
Public configuration
configuration: WidgetConfig<RatingSearchConfiguration>
Type : WidgetConfig<RatingSearchConfiguration>
Decorators : WidgetConfiguration
Public data
data: RatingSearchData
Type : RatingSearchData
Default value : { searchMode: SEARCHMODE_STANDARD, }
Public dataOutput
dataOutput:
Default value : new Subject()
Decorators : WidgetOutput
Public locale
locale:
Default value : new Subject()
Decorators : WidgetInput
Public nodeIconsSelectors
nodeIconsSelectors: Selectors
Type : Selectors
Public nodeMenuSelectors
nodeMenuSelectors: Selectors
Type : Selectors
Public prefix
prefix: string
Type : string
Public reloadLookups
reloadLookups:
Default value : new ReplaySubject<string[]>()
Decorators : WidgetInput
Public resetPressed
resetPressed:
Default value : new Subject()
Decorators : WidgetOutput
Public searchFavorites
searchFavorites: boolean
Type : boolean
Default value : false
Public searchingDataOutput
searchingDataOutput:
Default value : new Subject()
Decorators : WidgetOutput
Public searchInputLabel
searchInputLabel: string
Type : string
Private searchListEntry
searchListEntry: LocalStorageEntry
Type : LocalStorageEntry
Private searchModeEntry
searchModeEntry: LocalStorageEntry
Type : LocalStorageEntry
Public searchmodes
searchmodes: []
Type : []
Default value : [ { identifier: SEARCHMODE_STANDARD, label: "product-search", }, { identifier: SEARCHMODE_WORKLIST, label: "worklist", }, { identifier: SEARCHMODE_LIST, label: "list-search", }, ]
Public searchmodeSelect
searchmodeSelect:
Default value : true
searchOnFieldsChanged
searchOnFieldsChanged: any
Type : any
Private searchStringEntry
searchStringEntry: LocalStorageEntry
Type : LocalStorageEntry
Public searchTemplatesUri
searchTemplatesUri: string
Type : string
Public staticFolders
staticFolders: any[]
Type : any[]
Public termOutput
termOutput:
Default value : new ReplaySubject(1)
Decorators : WidgetOutput
Private unsubscribe
unsubscribe:
Default value : NgUnsubscribe.create()
Public withHeader
withHeader: boolean
Type : boolean
import { ChangeDetectorRef, Component, OnDestroy } from "@angular/core";
import { merge, ReplaySubject, Subject } from "rxjs";
import * as uriTemplates_ from "uri-templates";
import { FormWidgetField } from "./advanced/search-advanced.component";
import { Attribute } from "../../components/edit-attribute/attribute";
import {
  DeletionMode,
  Scope,
} from "../../components/local-storage/local-storage-constants";
import {
  LocalStorageEntry,
  LocalStorageService,
} from "../../components/local-storage/local-storage.service";
import {
  WidgetComponent,
  WidgetConfiguration,
  WidgetConfigure,
  WidgetInput,
  WidgetOutput,
} from "../widget.metadata";
import { NgUnsubscribe } from "../../ng-unsubscribe";
import { getOrDefault, WidgetConfig } from "../widget.configuration";
import { WidgetframeService } from "../widgetframe/widgetframe.service";
import { SelectFilterParams } from "../interfaces/list.interfaces";
import { AppContext } from "../../components/app-context/app.context";
import { filter, map, takeUntil } from "rxjs/operators";
import { TranslateService } from "@ngx-translate/core";
import { NodeLoader } from "../worklist-select/node-loader";
import { AppdataStore } from "../../components/appdata/appdata.store";
import { Selectors } from "../../components/app-context/api";

const uriTemplates = uriTemplates_;

export interface RatingSearchConfiguration {
  title: string;
  header: string;
  infoTitle: string;
  infoText: string;
  wikiLink: string;
  isCollapsible: boolean;
  searchMode: string;
  lookups: any;
  fields: FormWidgetField[];
  searchInputLabel: string;
  directSearch: boolean;
  localstoragePrefix: string;
  staticFolders: any[];
  attributeUrl: string;
  advancedSearch: boolean;
  selectFilterParams: SelectFilterParams;
  searchFavorites: boolean;
  searchTemplatesUri: string;
  searchmodeSelect: boolean;
  withHeader: boolean;
  searchOnFieldsChanged: boolean;
  selectors: {
    nodeMenu?: Selectors;
    nodeIcons?: Selectors;

    // fallback, used, when the more specific selectors are not defined
    menu: Selectors;
    icons: Selectors;
  };
}

export interface RatingSearchData {
  searchMode?: string;
  productNo?: string;
  worklist?: string;
  fields?: any;
  attributes?: Attribute[];
  parameter?: string;
  list?: string;
}

const SEARCHMODE_STANDARD = "number";
const SEARCHMODE_LIST = "list";
const SEARCHMODE_WORKLIST = "worklist";

@WidgetComponent("nm-rating-search")
@Component({
  selector: "nm-rating-search",
  templateUrl: "./rating-search-widget.component.html",
  styleUrls: ["./rating-search-widget.component.scss"],
})
export class RatingSearchWidgetComponent implements OnDestroy {
  public searchmodeSelect = true;
  public advancedSearch: boolean = false;
  public searchFavorites: boolean = false;
  public searchTemplatesUri: string;
  public staticFolders: any[];

  public searchmodes = [
    {
      identifier: SEARCHMODE_STANDARD,
      label: "product-search",
    },
    {
      identifier: SEARCHMODE_WORKLIST,
      label: "worklist",
    },
    {
      identifier: SEARCHMODE_LIST,
      label: "list-search",
    },
  ];

  public searchInputLabel: string;

  @WidgetConfiguration()
  public configuration: WidgetConfig<RatingSearchConfiguration>;
  @WidgetInput()
  public locale = new Subject();
  @WidgetInput()
  public reloadLookups = new ReplaySubject<string[]>();

  @WidgetOutput()
  public bulkEdit = new Subject<any>();
  @WidgetOutput("term")
  public termOutput = new ReplaySubject(1);
  @WidgetOutput()
  public resetPressed = new Subject();
  @WidgetOutput("attributes")
  public attributesOutput = new Subject<Attribute[]>();
  @WidgetOutput("data")
  public dataOutput = new Subject();
  //Same as data, but will only output when search is pressed so we know the data-set that was used to perform the last executed search
  @WidgetOutput("searchingData")
  public searchingDataOutput = new Subject();

  private searchStringEntry: LocalStorageEntry;
  private searchModeEntry: LocalStorageEntry;
  private searchListEntry: LocalStorageEntry;

  private unsubscribe = NgUnsubscribe.create();
  public data: RatingSearchData = {
    searchMode: SEARCHMODE_STANDARD,
  };
  public withHeader: boolean;
  searchOnFieldsChanged: any;

  public prefix: string;
  public nodeMenuSelectors: Selectors;
  public nodeIconsSelectors: Selectors;
  private advancedData: any;

  constructor(
    private translateService: TranslateService,
    private appDataStore: AppdataStore,
    private localstorageService: LocalStorageService,
    private widgetframeService: WidgetframeService,
    private appContext: AppContext,
    private cd: ChangeDetectorRef
  ) {}

  @WidgetConfigure()
  public configureWidget(config: WidgetConfig<RatingSearchConfiguration>) {
    this.searchInputLabel = getOrDefault(
      this.configuration.configuration.searchInputLabel,
      "product.or.article.number"
    );
    this.advancedSearch = getOrDefault(
      this.configuration.configuration.advancedSearch,
      false
    );
    this.searchFavorites = getOrDefault(
      this.configuration.configuration.searchFavorites,
      false
    );
    this.searchTemplatesUri = getOrDefault(
      this.configuration.configuration.searchTemplatesUri,
      "/api/core/search-templates"
    );
    this.searchmodeSelect = getOrDefault(
      this.configuration.configuration.searchmodeSelect,
      true
    );

    let prefix = getOrDefault(
      this.configuration.configuration.localstoragePrefix,
      "rating-"
    );

    this.staticFolders = getOrDefault(
      this.configuration.configuration.staticFolders,
      NodeLoader.defaultStaticFolders()
    );

    this.searchStringEntry = this.localstorageService.getLocalStorageEntry(
      prefix + "search",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.searchModeEntry = this.localstorageService.getLocalStorageEntry(
      prefix + "searchmode",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.searchListEntry = this.localstorageService.getLocalStorageEntry(
      prefix + "list-search",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.withHeader = getOrDefault(
      this.configuration.configuration.withHeader,
      true
    );
    this.searchOnFieldsChanged = getOrDefault(
      this.configuration.configuration.searchOnFieldsChanged,
      true
    );

    this.prefix = prefix;

    const selectors: any = this.configuration.configuration.selectors || {};
    this.nodeMenuSelectors = getOrDefault(
      selectors.nodeMenu || selectors.menu,
      {
        target: ["nm-worklist-tree-selector", "nm-worklist-tree-selector-node"],
        type: "menu",
      }
    );

    this.nodeIconsSelectors = getOrDefault(
      selectors.nodeIcons || selectors.icons,
      {
        target: ["nm-worklist-tree-selector", "nm-worklist-tree-selector-node"],
        type: "icons",
      }
    );

    if (this.searchModeEntry.exists()) {
      this.data.searchMode = this.searchModeEntry.value;
    }

    if (this.searchStringEntry.exists()) {
      this.data.productNo = this.searchStringEntry.value;

      if (this.data.searchMode === SEARCHMODE_STANDARD && this.data.productNo) {
        this.termOutput.next(this.data.productNo);
        if (this.searchOnFieldsChanged) {
          this.doSearch();
        }
      }
    }

    if (this.searchListEntry.exists()) {
      this.data.list = this.searchListEntry.value;
    }

    this.initToolboxEdits();

    this.dataOutput.next(this.data);
  }

  ngOnDestroy(): void {
    this.unsubscribe.destroy();
  }

  doSearch() {
    this.searchingDataOutput.next(this.data);
  }

  searchStringChange() {
    this.searchStringEntry.value = this.data.productNo;
    this.dataOutput.next(this.data);
    this.termOutput.next(this.data.productNo);
  }

  searchListStringChange() {
    this.searchListEntry.value = this.data.list;
    this.dataOutput.next(this.data);
  }

  onModeChange() {
    this.searchModeEntry.value = this.data.searchMode;
    if (this.data.searchMode === SEARCHMODE_STANDARD) {
      delete this.data.list;
      delete this.data.parameter;
      delete this.data.worklist;
    } else if (
      this.data.searchMode === SEARCHMODE_LIST ||
      this.data.searchMode === SEARCHMODE_WORKLIST
    ) {
      delete this.data.productNo;
      if (this.data.searchMode === SEARCHMODE_LIST) {
        delete this.data.worklist;
      } else {
        delete this.data.list;
      }
    }
    this.dataOutput.next(this.data);
  }

  onWorklistSelect(worklist) {
    if (worklist !== null && worklist.isNode) {
      this.data.worklist = worklist.id;
    }
    this.dataOutput.next(this.data);
  }

  reset() {
    this.data = {
      searchMode: SEARCHMODE_STANDARD,
    };
    this.searchStringEntry.clear();
    this.searchListEntry.clear();
    this.resetPressed.next();
    //this.dataOutput.next(this.data);
  }

  onAdvancedSearchChanged(data: any) {
    if (this.advancedSearch) {
      this.advancedData = data;
      this.data.fields = Object.assign(
        {},
        this.data.fields || {},
        this.advancedData
      );
    } else {
      this.data.fields = {};
    }

    this.dataOutput.next(this.data);
    if (!this.searchOnFieldsChanged) {
      return;
    }
    this.doSearch();
  }

  onExpandToggle($event: boolean) {
    this.advancedSearch = $event;
    this.onAdvancedSearchChanged(this.advancedData);
  }

  onAttributesChanged(attributes: Attribute[]) {
    this.attributesOutput.next(attributes);
    this.data.attributes = attributes;
    this.dataOutput.next(this.data);
  }

  private initToolboxEdits() {
    const filterer = filter(
      (data) => data && (data as any).length !== 0 && data[0].current
    );

    merge(
      this.appContext.userContext.subscribe({
        "@toolbox-active-context": "single",
      }),
      this.appContext.userContext.subscribe({
        "@toolbox-active-context": "sequential",
      })
    )
      .pipe(
        filterer,
        map((data) => data[0].current.identifier),
        takeUntil(this.unsubscribe)
      )
      .subscribe((number) => {
        this.data = {
          searchMode: "number",
        };
        this.onModeChange();
        this.data.productNo = number + "";
        this.searchStringEntry.value = this.data.productNo;
        this.resetPressed.next();
      });

    this.appContext.userContext
      .subscribe({ "@toolbox-active-context": "bulk" })
      .pipe(
        filterer,
        map((data) => data[0].current || []),
        takeUntil(this.unsubscribe)
      )
      .subscribe((data) => {
        if (this.searchmodeSelect) {
          this.data.searchMode = "list";
          this.reset();
          this.data.list = data.join("\n");
          this.searchListEntry.value = this.data.list;
          this.onModeChange();
          this.doSearch();
        } else {
          this.data.productNo = "";
          this.searchStringEntry.clear();
          this.bulkEdit.next(data);
        }
      });
  }
}
<nm-widgetframe
  [header]="configuration.configuration.header"
  [configuration]="configuration"
  [infoTitle]="configuration.configuration.infoTitle"
  [infoText]="configuration.configuration.infoText"
  [toolbarInvisible]="!withHeader"
  [infoPlacement]="'bottom'"
  [wikiLink]="configuration.configuration.wikiLink"
  [isCollapsible]="configuration.configuration.isCollapsible"
>
  <div slot="title" class="nm-widgetframe__title">
    {{ configuration.configuration.title | translate }}
  </div>

  <div slot="buttons" class="nm-widgetframe__buttons"></div>

  <div slot="content" class="nm-widgetframe__content">
    <ng-container *ngIf="searchmodeSelect">
      <mat-form-field>
        <mat-select
          [(value)]="data.searchMode"
          (selectionChange)="onModeChange()"
          [nmAutofocus]="true"
        >
          <mat-option
            *ngFor="let mode of searchmodes"
            [value]="mode.identifier"
            >{{ mode.label | translate }}</mat-option
          >
        </mat-select>
      </mat-form-field>
      <br />
    </ng-container>

    <ng-container [ngSwitch]="data.searchMode">
      <div *ngSwitchCase="'number'">
        <mat-form-field class="fixed-height">
          <input
            matInput
            [(ngModel)]="data.productNo"
            (ngModelChange)="searchStringChange()"
            [placeholder]="searchInputLabel | translate"
            (keydown.enter)="doSearch()"
          />
        </mat-form-field>
      </div>

      <div *ngSwitchCase="'worklist'">
        <nm-worklist-tree-selector
          (onSelection)="onWorklistSelect($event)"
          [local-storage-grid]="prefix + 'worklists-grid'"
          [local-storage-filter]="prefix + 'worklists-filter'"
          height="400px"
          [nodeMenuSelectors]="nodeMenuSelectors"
          [nodeIconsSelectors]="nodeIconsSelectors"
        >
        </nm-worklist-tree-selector>
      </div>

      <div *ngSwitchCase="'list'">
        <mat-form-field>
          <textarea
            matInput
            [(ngModel)]="data.list"
            style="width: 100%; min-height: 30px; height: 120px"
            [placeholder]="'searchlist.placeholder' | translate"
            (ngModelChange)="searchListStringChange()"
          >
          </textarea>
        </mat-form-field>
      </div>
    </ng-container>

    <nm-search-advanced
      [lookups]="configuration.configuration.lookups"
      [fields]="configuration.configuration.fields"
      [links]="configuration._links"
      [locale]="locale"
      [reloadLookups]="reloadLookups"
      (search)="onAdvancedSearchChanged($event)"
      (attributes)="onAttributesChanged($event)"
      (expandToggle)="onExpandToggle($event)"
      [reset]="resetPressed"
      [prefix]="configuration.configuration.localstoragePrefix"
      [attributeUrl]="configuration.configuration.attributeUrl"
      [selectFilterParams]="configuration.configuration.selectFilterParams"
      [dataInput]="dataOutput"
      [searchFavorites]="searchFavorites"
      [searchTemplatesUri]="searchTemplatesUri"
    >
    </nm-search-advanced>

    <div class="nm-RatingSearch__buttonGroup">
      <button mat-button type="button" (click)="reset()">
        {{ "button.reset" | translate }}
      </button>

      <button mat-raised-button color="primary" (click)="doSearch()">
        {{ "placeholder.search" | translate }}
      </button>
    </div>
  </div>
</nm-widgetframe>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""