@WidgetComponent

nm-search-app-search

File

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

Metadata

providers EditAttributeService
selector nm-search-app-search
styleUrls search-app-search-widget.component.scss
templateUrl ./search-app-search-widget.component.html

Index

Widget inputs
Widget outputs
Properties
Methods

Constructor

constructor(widgetframeService: WidgetframeService, localstorageService: LocalStorageService, dialog: MatDialog, translateService: TranslateService, datetimeAdapter: DateTimeAdapter, appStore: AppdataStore, _editAttributeService: EditAttributeService, scrollService: ScrollService, cdr: ChangeDetectorRef)
Parameters :
Name Type Optional
widgetframeService WidgetframeService no
localstorageService LocalStorageService no
dialog MatDialog no
translateService TranslateService no
datetimeAdapter DateTimeAdapter<any> no
appStore AppdataStore no
_editAttributeService EditAttributeService no
scrollService ScrollService no
cdr ChangeDetectorRef no

Methods

Public attributeSupportsRange
attributeSupportsRange(attribute: )
Parameters :
Name Optional
attribute no
Returns : boolean
Public computeNumberListMaxHeight
computeNumberListMaxHeight()
Returns : string
Public configure
configure(configuration: WidgetConfig)
Decorators : WidgetConfigure
Parameters :
Name Type Optional
configuration WidgetConfig<FormWidgetConfiguration> no
Returns : void
Public copyToClipboard
copyToClipboard(event: )
Parameters :
Name Optional
event no
Returns : void
Public formcontrolNameFor
formcontrolNameFor(field: FormWidgetField)
Parameters :
Name Type Optional
field FormWidgetField no
Returns : any
getHeightModifier
getHeightModifier()
Returns : number
getLookups
getLookups(key: )
Parameters :
Name Optional
key no
Returns : any[]
Public getTooltipValueForAttribute
getTooltipValueForAttribute(attribute: Attribute)
Parameters :
Name Type Optional
attribute Attribute no
Returns : any
Public isFieldVisible
isFieldVisible(field: FormWidgetField)
Parameters :
Name Type Optional
field FormWidgetField no
Returns : any
Private loadLookups
loadLookups(locale: )
Parameters :
Name Optional
locale no
Returns : void
Public mergeForms
mergeForms()
Returns : any
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: any)
Parameters :
Name Type Optional
$event any no
Returns : void
Public onInputEvent
onInputEvent(event: FormEventPayload)
Parameters :
Name Type Optional
event FormEventPayload no
Returns : void
onListValueChange
onListValueChange(listValues: any)
Parameters :
Name Type Optional
listValues any no
Returns : void
Public onSubmit
onSubmit()
Returns : void
rangeChange
rangeChange(event: , field: FormWidgetField)
Parameters :
Name Type Optional
event no
field FormWidgetField no
Returns : void
Private recoverChangedAttributes
recoverChangedAttributes()
Returns : void
Private recoverFormValue
recoverFormValue()
Returns : void
Private recoverFromData
recoverFromData(data: Attribute[], attributes: Attribute[])
Parameters :
Name Type Optional
data Attribute[] no
attributes Attribute[] no
Returns : void
Public resetClick
resetClick()
Returns : void
Public resetFavoritesSelect
resetFavoritesSelect()
Returns : void
Private resetSearchModeField
resetSearchModeField()
Returns : void
Public save
save()
Returns : void
Private setFormValue
setFormValue(value: )
Parameters :
Name Optional
value no
Returns : void
Private setListsearchValue
setListsearchValue(value: )
Parameters :
Name Optional
value no
Returns : void
Public showLabel
showLabel(attribute: )
Parameters :
Name Optional
attribute no
Returns : boolean
Public submit
submit()
Returns : void
toggleContentVisibility
toggleContentVisibility()
Returns : void
Public toggleMode
toggleMode($event: )
Parameters :
Name Optional
$event no
Returns : void
Private updateLookups
updateLookups(keys: string[], locale: )
Parameters :
Name Type Optional
keys string[] no
locale no
Returns : void

Properties

Public _editAttributeService
_editAttributeService: EditAttributeService
Type : EditAttributeService
Private _listsearch
_listsearch: boolean
Type : boolean
Private advancedFormData
advancedFormData: any
Type : any
Public attributeData
attributeData:
Default value : new Subject<Attribute[]>()
Decorators : WidgetInput
Public attributes
attributes: Attribute[]
Type : Attribute[]
Private attributesLocalstorageEntry
attributesLocalstorageEntry: LocalStorageEntry
Type : LocalStorageEntry
Public attributesOutput
attributesOutput:
Default value : new ReplaySubject<any>(1)
Decorators : WidgetOutput
Public attributeTypesToAddMultiple
attributeTypesToAddMultiple: string[]
Type : string[]
Private basicData
basicData: any
Type : any
Public basicform
basicform:
Public change
change:
Default value : new BehaviorSubject<any>({})
Decorators : WidgetOutput
Public changedAttributes
changedAttributes: []
Type : []
Default value : []
Private changedAttributesLocalstorageEntry
changedAttributesLocalstorageEntry: LocalStorageEntry
Type : LocalStorageEntry
Public configuration
configuration: WidgetConfig<FormWidgetConfiguration>
Type : WidgetConfig<FormWidgetConfiguration>
Decorators : WidgetConfiguration
Public contentVisible
contentVisible: boolean
Type : boolean
Default value : false
Public contentVisibleEntry
contentVisibleEntry: LocalStorageEntry
Type : LocalStorageEntry
Public copyNonMatchingParametersToClipboard
copyNonMatchingParametersToClipboard:
Default value : new Subject()
Decorators : WidgetOutput
Public currentLocale
currentLocale:
Private data
data: any
Type : any
Default value : {}
Public dataOutput
dataOutput:
Default value : new Subject()
Decorators : WidgetOutput
Public disableCopyNonMatchingParametersToClipboard
disableCopyNonMatchingParametersToClipboard:
Default value : new Subject<boolean>()
Decorators : WidgetInput
Public doSave
doSave:
Default value : new Subject()
Decorators : WidgetOutput
Public doSubmit
doSubmit:
Default value : new Subject()
Decorators : WidgetOutput
Public enableRoleBasedSearchTemplates
enableRoleBasedSearchTemplates: boolean
Type : boolean
Public event
event:
Default value : new Subject<FormEventPayload>()
Decorators : WidgetOutput
Private expanded
expanded: boolean
Type : boolean
Default value : true
exportButtonDisabled
exportButtonDisabled: boolean
Type : boolean
Default value : true
Public favoriteField
favoriteField: FormWidgetField
Type : FormWidgetField
Default value : { identifier: "searchfavorites", description: "table.head.searchfavorite", type: "LOOKUP", lookupSource: "searchfavorites", eventField: true, range: "never", }
Public favoriteForm
favoriteForm:
Public fields
fields: FormWidgetField[]
Type : FormWidgetField[]
Public fieldsVisible
fieldsVisible: object
Type : object
Default value : {}
Private fieldsVisibleEntry
fieldsVisibleEntry: LocalStorageEntry
Type : LocalStorageEntry
Public fieldsVisibleFavorite
fieldsVisibleFavorite:
Private fieldsVisibleFavoriteEntry
fieldsVisibleFavoriteEntry: LocalStorageEntry
Type : LocalStorageEntry
Private forceEmit
forceEmit:
Default value : new Subject<void>()
Public form
form:
Private formValueEntry
formValueEntry: LocalStorageEntry
Type : LocalStorageEntry
Public formValues
formValues: object
Type : object
Default value : {}
Public frameHeight
frameHeight:
Public hasSystemAttributes
hasSystemAttributes: boolean
Type : boolean
Default value : false
Public header
header:
Public id
id: string
Type : string
Decorators : WidgetId
Public infoText
infoText:
Public isCollapsible
isCollapsible: boolean
Type : boolean
Default value : false
Private isListsearchEntry
isListsearchEntry: LocalStorageEntry
Type : LocalStorageEntry
Public isSearchmodeList
isSearchmodeList:
Default value : new ReplaySubject<boolean>(1)
Decorators : WidgetOutput
Public listchange
listchange:
Default value : new ReplaySubject<any>(1)
Decorators : WidgetOutput
Public listHeight
listHeight:
Public listSearchForm
listSearchForm:
Public listsearchmodeField
listsearchmodeField: FormWidgetField
Type : FormWidgetField
Default value : { identifier: "parameter", description: "table.head.listsearchmodes", type: "LOOKUP", lookupSource: "listsearchmodes", default: "PRODUCTNO", range: "never", }
Public listsearchValue
listsearchValue:
Private listsearchValueEntry
listsearchValueEntry: LocalStorageEntry
Type : LocalStorageEntry
Public listvalue
listvalue:
Default value : new Subject()
Decorators : WidgetInput
Public locale
locale:
Default value : new BehaviorSubject(null)
Decorators : WidgetInput
Public lookups
lookups: object
Type : object
Default value : {}
Private nmSearchFooter_ref
nmSearchFooter_ref: ElementRef
Type : ElementRef
Decorators : ViewChild
Private numberList_ref
numberList_ref: ElementRef
Type : ElementRef
Decorators : ViewChild
Public rangeModes
rangeModes: object
Type : object
Default value : {}
Private rangeModesEntry
rangeModesEntry: LocalStorageEntry
Type : LocalStorageEntry
Public reloadLookups
reloadLookups:
Default value : new Subject<any>()
Decorators : WidgetInput
Public resentFavoritesChanged
resentFavoritesChanged: boolean
Type : boolean
Default value : false
Public reset
reset:
Default value : new Subject()
Decorators : WidgetInput
Public resetOutput
resetOutput:
Default value : new Subject()
Decorators : WidgetOutput
Public searchFavorites
searchFavorites: boolean
Type : boolean
Default value : true
Private searchMode
searchMode:
Public searchModeChanged
searchModeChanged:
Default value : new Subject<boolean>()
Private searchModeEntry
searchModeEntry: LocalStorageEntry
Type : LocalStorageEntry
Public searchModeField
searchModeField: FormWidgetField
Type : FormWidgetField
Default value : { identifier: "searchMode", description: "table.head.searchmodes", type: "MENU", defaultVisible: false, lookupSource: "standardsearchmodes", default: "SEARCH_MODE_STANDARD", range: "never", }
Public searchModeForm
searchModeForm:
Public searchmodeSelect
searchmodeSelect:
Default value : true
Public title
title:
Private unsubscribe
unsubscribe:
Default value : NgUnsubscribe.create()
Public value
value:
Default value : new Subject()
Decorators : WidgetInput
Public wikiLink
wikiLink:

Accessors

listsearch
getlistsearch()
setlistsearch(value: )
Parameters :
Name Optional
value no
Returns : void
import {
  WidgetComponent,
  WidgetConfiguration,
  WidgetConfigure,
  WidgetId,
  WidgetInput,
  WidgetOutput,
} from "../widget.metadata";
import {
  ChangeDetectorRef,
  Component,
  ElementRef,
  ViewChild,
} from "@angular/core";
import {
  getOrDefault,
  throwIfUndefined,
  WidgetConfig,
} from "../widget.configuration";
import { FormControl, FormGroup } from "@angular/forms";
import { WidgetframeService } from "../widgetframe/widgetframe.service";
import { NgUnsubscribe } from "../../ng-unsubscribe";
import { debounceTime, takeUntil } from "rxjs/operators";
import { BehaviorSubject, combineLatest, ReplaySubject, Subject } from "rxjs";
import {
  LocalStorageEntry,
  LocalStorageService,
} from "../../components/local-storage/local-storage.service";
import {
  DeletionMode,
  Scope,
} from "../../components/local-storage/local-storage-constants";
import {
  deepCopy,
  notNullOrEmpty,
  UtilService,
} from "../../components/util/util.service";
import { MatDialog } from "@angular/material/dialog";

import { DateTimeAdapter } from "ng-pick-datetime";

import { TranslateService } from "@ngx-translate/core";
import { EditAttributeService } from "../../components/edit-attribute/edit-attribute.service";
import { Attribute } from "../../components/edit-attribute/attribute";
import { AppdataStore } from "../../components/appdata/appdata.store";
import { ScrollService } from "../../components/scroll/scroll.service";
import { FormWidgetField } from "../search/advanced/search-advanced.component";

const DEFAULT_FRAME_HEIGHT_PX: number = 559;
const EMPTY_ADVANCED_SEARCH_HEIGHT_PX: number = 140;

export class FormLookup {
  label: string;
  collectionName: string;
  valueField: string;
  keepOriginal: boolean;
}

export class FormEventPayload {
  field: string;
  payload: any;
}

export class FormWidgetConfiguration {
  editVisibleFields: boolean;
  attributeUrl: string;
  fields: FormWidgetField[];
  lookups: { [key: string]: FormLookup };
  infoText: string;
  infoWidth: string;
  infoHeight: string;
  listSearchInfoText: string;
  listSearchTitle: string;
  header: string;
  isCollapsible: boolean;
  title: string;
  wikiLink: string;
  children: any;
  frameHeight: any;
  listHeight: any;
  attributeTypesToAddMultiple: string[];
  selectFilterParams: any;
  localstoragePrefix: string;
  enableRoleBasedSearchTemplates: boolean;
}

@WidgetComponent("nm-search-app-search")
@Component({
  selector: "nm-search-app-search",
  templateUrl: "./search-app-search-widget.component.html",
  styleUrls: ["./search-app-search-widget.component.scss"],
  providers: [EditAttributeService],
})
export class SearchAppSearchWidgetComponent {
  public basicform;

  public form;
  public favoriteForm;
  public listSearchForm;
  public listsearchValue;
  public searchModeForm;

  public favoriteField: FormWidgetField = {
    identifier: "searchfavorites",
    description: "table.head.searchfavorite",
    type: "LOOKUP",
    lookupSource: "searchfavorites",
    eventField: true,
    range: "never",
  };

  public listsearchmodeField: FormWidgetField = {
    identifier: "parameter",
    description: "table.head.listsearchmodes",
    type: "LOOKUP",
    lookupSource: "listsearchmodes",
    default: "PRODUCTNO",
    range: "never",
  };

  public searchModeField: FormWidgetField = {
    identifier: "searchMode",
    description: "table.head.searchmodes",
    type: "MENU",
    defaultVisible: false,
    lookupSource: "standardsearchmodes",
    default: "SEARCH_MODE_STANDARD",
    range: "never",
  };

  public fields: FormWidgetField[];
  public header;
  public infoText;
  public title;
  public wikiLink;
  public isCollapsible: boolean = false;
  public contentVisible: boolean = false;
  public resentFavoritesChanged: boolean = false;

  public currentLocale;

  public rangeModes = {};
  public fieldsVisible = {};
  public fieldsVisibleFavorite;

  public lookups = {};
  public formValues = {};
  private unsubscribe = NgUnsubscribe.create();

  private isListsearchEntry: LocalStorageEntry;
  private listsearchValueEntry: LocalStorageEntry;
  private formValueEntry: LocalStorageEntry;
  private rangeModesEntry: LocalStorageEntry;
  private fieldsVisibleEntry: LocalStorageEntry;
  private fieldsVisibleFavoriteEntry: LocalStorageEntry;
  private attributesLocalstorageEntry: LocalStorageEntry;
  private changedAttributesLocalstorageEntry: LocalStorageEntry;
  public contentVisibleEntry: LocalStorageEntry;
  public hasSystemAttributes: boolean = false;
  private _listsearch: boolean;
  public attributes: Attribute[];
  public changedAttributes = [];
  public frameHeight;
  public listHeight;

  private forceEmit = new Subject<void>();
  public searchModeChanged = new Subject<boolean>();
  public attributeTypesToAddMultiple: string[];
  public enableRoleBasedSearchTemplates: boolean;

  public searchmodeSelect = true;
  public searchFavorites: boolean = true;
  private basicData: any;
  private advancedFormData: any;
  private data: any = {};
  private expanded: boolean = true;

  private searchMode;
  private searchModeEntry: LocalStorageEntry;

  exportButtonDisabled: boolean = true;

  constructor(
    private widgetframeService: WidgetframeService,
    private localstorageService: LocalStorageService,
    private dialog: MatDialog,
    private translateService: TranslateService,
    private datetimeAdapter: DateTimeAdapter<any>,
    private appStore: AppdataStore,
    public _editAttributeService: EditAttributeService,
    private scrollService: ScrollService,
    private cdr: ChangeDetectorRef
  ) {}

  @WidgetId()
  public id: string;

  @WidgetConfiguration()
  public configuration: WidgetConfig<FormWidgetConfiguration>;

  @WidgetInput()
  public locale = new BehaviorSubject(null);

  @WidgetOutput()
  public change = new BehaviorSubject<any>({});

  @WidgetOutput()
  public listchange = new ReplaySubject<any>(1);

  @WidgetInput()
  public reset = new Subject();

  @WidgetOutput()
  public resetOutput = new Subject();

  @WidgetOutput("submit")
  public doSubmit = new Subject();

  @WidgetOutput()
  public copyNonMatchingParametersToClipboard = new Subject();

  @WidgetInput()
  public value = new Subject();

  @WidgetInput()
  public listvalue = new Subject();

  @WidgetInput("attributeData")
  public attributeData = new Subject<Attribute[]>();

  @WidgetInput()
  public reloadLookups = new Subject<any>();

  @WidgetOutput("save")
  public doSave = new Subject();

  @WidgetOutput("attributes")
  public attributesOutput = new ReplaySubject<any>(1);

  @WidgetOutput()
  public isSearchmodeList = new ReplaySubject<boolean>(1);

  @WidgetOutput()
  public event = new Subject<FormEventPayload>();

  @WidgetInput()
  public disableCopyNonMatchingParametersToClipboard = new Subject<boolean>();

  @WidgetOutput("data")
  public dataOutput = new Subject();

  @ViewChild("searchNumberList")
  private numberList_ref: ElementRef;

  @ViewChild("nmSearchFooter")
  private nmSearchFooter_ref: ElementRef;

  get listsearch() {
    return this._listsearch;
  }

  set listsearch(value) {
    this._listsearch = value;
    this.isSearchmodeList.next(value);
  }

  @WidgetConfigure()
  public configure(configuration: WidgetConfig<FormWidgetConfiguration>) {
    this.enableRoleBasedSearchTemplates = this.configuration.configuration.enableRoleBasedSearchTemplates;

    this.attributesOutput.next([]);

    this.frameHeight = getOrDefault(
      this.configuration.configuration.frameHeight,
      DEFAULT_FRAME_HEIGHT_PX
    );
    if (this.configuration.configuration.listHeight) {
      this.listHeight =
        String(this.configuration.configuration.listHeight) + "px";
    } else {
      this.listHeight =
        String(
          (window.innerHeight ||
            document.documentElement.clientHeight ||
            document.body.clientHeight) -
            this.frameHeight +
            this.getHeightModifier()
        ) + "px";
    }

    this.attributeTypesToAddMultiple = getOrDefault(
      this.configuration.configuration.attributeTypesToAddMultiple,
      ["LOCALIZED_STRING", "TEXT_TYPE"]
    );

    this.scrollService
      .getChangeViewPortSize()
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((newViewPortHeight) => {
        if (!this.configuration.configuration.listHeight) {
          this.listHeight =
            String(
              newViewPortHeight - this.frameHeight + this.getHeightModifier()
            ) + "px";
        }
      });

    this.attributesLocalstorageEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-search-atributes",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.changedAttributesLocalstorageEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "search-changed-attributes",
      Scope.GLOBAL,
      DeletionMode.LOGIN
    );
    if (this.attributesLocalstorageEntry.exists()) {
      this.attributes = JSON.parse(this.attributesLocalstorageEntry.value);
      this.recoverChangedAttributes();
    }

    this.searchModeEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-search-mode",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    if (this.searchModeEntry.exists()) {
      this.searchMode = JSON.parse(this.searchModeEntry.value);
    }
    const searchModeControls = {};
    searchModeControls[this.searchModeField.identifier] = new FormControl(
      this.searchMode ? this.searchMode : this.searchModeField.default
    );
    this.searchModeForm = new FormGroup(searchModeControls);

    this.listSearchForm = new FormGroup({
      parameter: new FormControl("PRODUCTNO"),
      list: new FormControl(""),
    });
    combineLatest([
      this.listSearchForm.valueChanges,
      this.searchModeForm.valueChanges,
    ])
      .pipe(takeUntil(this.unsubscribe))
      .subscribe(([data, searchModeData]: any) => {
        this.listsearchValueEntry.value = JSON.stringify(data);
        Object.assign(data, searchModeData);
        this.listchange.next(data);
        this.data.listvalue = data;
        this.dataOutput.next(this.data);
      });

    this.searchModeForm.valueChanges
      .asObservable()
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((searchModeData) => {
        if (searchModeData?.searchMode) {
          this.searchModeEntry.value = JSON.stringify(
            searchModeData.searchMode
          );
        }
      });

    this.fields = configuration.configuration.fields.filter(
      (item) => item.basic
    );

    this.formValueEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-form",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.rangeModesEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-range-modes",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.fieldsVisibleEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-fields-visible",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.fieldsVisibleFavoriteEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-fields-visible-favorite",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.isListsearchEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-islistsearch",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    this.listsearchValueEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-listsearch",
      Scope.GLOBAL,
      DeletionMode.RESET
    );
    if (this.rangeModesEntry.exists()) {
      this.rangeModes = JSON.parse(this.rangeModesEntry.value);
    }
    this.isCollapsible = getOrDefault(
      this.configuration.configuration.isCollapsible,
      false
    );
    this.contentVisibleEntry = this.localstorageService.getLocalStorageEntry(
      this.id + "-contentVisible",
      Scope.GLOBAL,
      DeletionMode.RESET
    );

    if (this.contentVisibleEntry.exists()) {
      this.contentVisible = this.contentVisibleEntry.value === "true";
    }

    this.header = getOrDefault(
      this.configuration.configuration.header,
      "primary"
    );
    if (this.isListsearchEntry.exists()) {
      this.listsearch = this.isListsearchEntry.value === "true";
    } else {
      this.listsearch = false;
    }
    if (this.listsearchValueEntry.exists()) {
      this.listSearchForm.patchValue(
        JSON.parse(this.listsearchValueEntry.value)
      );
    }

    this.infoText = configuration.configuration.infoText;
    this.title = throwIfUndefined(this.configuration.configuration.title);
    this.wikiLink = this.configuration.configuration.wikiLink;
    this.locale
      .asObservable()
      .pipe(takeUntil(this.unsubscribe), debounceTime(1))
      .subscribe((locale) => this.loadLookups(locale));
    let controls = {};

    this.fields.forEach((field) => {
      if (field.allowRange) {
        controls[field.identifier + "From"] = new FormControl("");
        controls[field.identifier + "Until"] = new FormControl("");
      } else {
        controls[field.identifier] = new FormControl(field.default);
      }
    });

    this.reloadLookups
      .asObservable()
      .pipe(takeUntil(this.unsubscribe), debounceTime(1))
      .subscribe((lookups) => {
        this.updateLookups(lookups, this.locale.getValue());
      });

    this.favoriteForm = new FormGroup({
      searchfavorites: new FormControl(""),
    });

    this.form = new FormGroup(controls);

    this.favoriteForm.valueChanges
      .asObservable()
      .pipe(takeUntil(this.unsubscribe))
      .subscribe(() => {
        this.resentFavoritesChanged = true;
      });

    combineLatest([
      this.form.valueChanges,
      this.searchModeForm.valueChanges,
      this.forceEmit.asObservable(),
    ])
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((values) => {
        this.resetFavoritesSelect();
        this.resentFavoritesChanged = false;
        let data = values[0];
        const searchModeData = values[1];
        this.formValueEntry.value = JSON.stringify(data);
        this.formValues = data;
        this.hasSystemAttributes = false;
        data = deepCopy(data);

        this.fields.forEach((field) => {
          if (this.formValues[field.identifier] && field.type === "lookup") {
            let lookups = this.lookups[this.currentLocale][field.lookupSource];
            for (const lookup of lookups) {
              if (this.formValues[field.identifier] === lookup.value) {
                this.formValues[field.identifier] = lookup.label;
              }
            }
          }

          if (!this.isFieldVisible(field)) {
            delete data[field.identifier];
            delete data[field.identifier + "Until"];
            delete data[field.identifier + "From"];
          }
          // If we are not in range mode dont send the range until field
          if (field.allowRange) {
            if (!this.rangeModes[field.identifier]) {
              delete data[field.identifier + "Until"];
            }
          }

          if (
            this.isFieldVisible(field) &&
            field.identifier.indexOf("articleNo") === -1 &&
            field.identifier !== "description" &&
            field.identifier !== "searchModes"
          ) {
            if (data[field.identifier]) {
              this.hasSystemAttributes = true;
            } else if (field.allowRange) {
              if (
                data[field.identifier] + "From" ||
                data[field.identifier] + "From"
              ) {
                this.hasSystemAttributes = true;
              }
            }
          }
        });
        Object.assign(data, searchModeData);
        this.basicData = data;
        this.change.next(this.mergeForms());
      });
    this.forceEmit.next();

    this.searchModeForm.updateValueAndValidity({
      onlySelf: false,
      emitEvent: true,
    });

    this.listvalue.pipe(takeUntil(this.unsubscribe)).subscribe((data) => {
      this.listsearch = true;
      this.isListsearchEntry.value = "true";
      this.listSearchForm.patchValue(data);
      this.listsearchValueEntry.value = JSON.stringify(data);
    });

    this.value.pipe(takeUntil(this.unsubscribe)).subscribe((data) => {
      this.resentFavoritesChanged = true;
      this.setFormValue(data);
      this.formValueEntry.value = JSON.stringify(data);
      this.formValues = data;
      this.listsearch = false;
      this.isListsearchEntry.value = "false";

      this.fieldsVisible = {};
      this.fields.forEach((field) => {
        if (field.allowRange) {
          // We can not use a if(data[field.identifier]) check here, since 0 will validate to false!
          if (
            notNullOrEmpty(data[field.identifier + "From"]) ||
            notNullOrEmpty(data[field.identifier + "Until"])
          ) {
            this.fieldsVisible[field.identifier] = true;
            if (notNullOrEmpty(data[field.identifier + "Until"])) {
              this.rangeModes[field.identifier] = true;
            } else {
              this.rangeModes[field.identifier] = false;
            }
          } else {
            this.fieldsVisible[field.identifier] = false;

            if (field.basic) {
              this.fieldsVisible[field.identifier] = true;
            }
          }
        } else {
          if (notNullOrEmpty(data[field.identifier]) || field.basic) {
            this.fieldsVisible[field.identifier] = true;
          } else {
            this.fieldsVisible[field.identifier] = false;
          }
        }
      });
      this.fieldsVisibleEntry.value = JSON.stringify(this.fieldsVisible);
    });
    if (this.fieldsVisibleEntry.exists()) {
      this.fieldsVisible = JSON.parse(this.fieldsVisibleEntry.value);
    } else {
      this.fields.forEach((field) => {
        if (field.defaultVisible === false) {
          this.fieldsVisible[field.identifier] = false;
        } else {
          this.fieldsVisible[field.identifier] = true;
        }
      });
    }
    if (this.fieldsVisibleFavoriteEntry.exists()) {
      this.fieldsVisibleFavorite = JSON.parse(
        this.fieldsVisibleFavoriteEntry.value
      );
    }
    this.recoverFormValue();

    this.reset.pipe(takeUntil(this.unsubscribe)).subscribe(() => {
      this.formValueEntry.value = "{}";
      const formValue = {};
      this.fields.forEach((field) => {
        if (field.default) {
          formValue[field.identifier] = field.default;
        } else {
          if (notNullOrEmpty(field.identifier + "From")) {
            formValue[field.identifier + "From"] = null;
          }
          if (notNullOrEmpty(field.identifier + "Until")) {
            formValue[field.identifier + "Until"] = null;
          }
          formValue[field.identifier] = null;
        }
        this.setFormValue(formValue);
      });
      this.setListsearchValue("");

      this.changedAttributesLocalstorageEntry.clear();
      this.changedAttributes = [];

      this.onAdvancedSearchChanged({});
      this.onAttributesChanged([]);
      this.forceEmit.next();

      this.resetSearchModeField();
    });

    this.disableCopyNonMatchingParametersToClipboard
      .pipe(takeUntil(this.unsubscribe))
      .subscribe((disable) => (this.exportButtonDisabled = disable));
  }

  private resetSearchModeField() {
    this.searchModeEntry.value = null;
    this.searchModeForm.controls.searchMode.setValue("SEARCH_MODE_STANDARD");
  }

  private recoverChangedAttributes() {
    if (this.changedAttributesLocalstorageEntry.exists()) {
      this.changedAttributes = JSON.parse(
        this.changedAttributesLocalstorageEntry.value
      );
      for (const changedAttribute of this.changedAttributes) {
        let dublicate = this.attributes.filter(
          (item) => item.identifer == changedAttribute.identifer
        );
        if (dublicate.length === 1) {
          dublicate[0].source = changedAttribute.source;
          dublicate[0].modifier = changedAttribute.modifier;
          if (changedAttribute.from) {
            dublicate[0].from = changedAttribute.from;
            dublicate[0].to = changedAttribute.to;
            dublicate[0].displayRange = changedAttribute.displayRange;
          }
        }
      }
    }
    this.attributesOutput.next(this.changedAttributes);
  }

  private recoverFormValue() {
    if (this.formValueEntry.exists()) {
      this.setFormValue(JSON.parse(this.formValueEntry.value));
    }
  }

  private setFormValue(value) {
    this.form.patchValue(value);
  }

  private loadLookups(locale) {
    this.datetimeAdapter.setLocale(locale);
    this.currentLocale = locale;
    if (this.configuration.configuration.lookups) {
      if (this.lookups[locale]) {
        return;
      }
      const lookups = {};
      Object.keys(this.configuration.configuration.lookups).forEach((key) => {
        const lookup = this.configuration.configuration.lookups[key];
        lookups[key] = [];
        const link = this.configuration._links[key] as any;
        if (!link) {
          console.error(`Link for lookup ${key} is not configured`);
          return;
        }
        link.href = UtilService.setUrlParam(
          link.href,
          "locale",
          this.currentLocale
        );
        this.widgetframeService.getData(link.href).subscribe((data) => {
          if (!data["_embedded"][lookup.collectionName]) {
            console.error(
              `Cant find data under the collectionname ${lookup.collectionName}, is it configured correctly? ${link.href}`
            );
          }
          data = data["_embedded"][lookup.collectionName];

          if (lookup.keepOriginal === true) {
            lookups[key] = data;
            return;
          }

          data.forEach((value) => {
            const label = value[lookup.label];
            if (lookup.valueField) {
              value = value[lookup.valueField];
            }
            lookups[key].push({ value, label });
          });
          if (locale) {
            this.lookups = Object.assign({ [locale]: lookups }, this.lookups);
            this.cdr.markForCheck();
          }
        });
      });
    }
  }

  private updateLookups(keys: string[], locale) {
    this.datetimeAdapter.setLocale(locale);
    this.currentLocale = locale;
    if (this.configuration.configuration.lookups) {
      keys.forEach((key) => {
        const lookup = this.configuration.configuration.lookups[key];
        const link = this.configuration._links[key] as any;
        if (!link) {
          console.error(`Link for lookup ${key} is not configured`);
          return;
        }
        link.href = UtilService.setUrlParam(
          link.href,
          "locale",
          this.currentLocale
        );
        this.widgetframeService.getData(link.href).subscribe((data) => {
          if (!data["_embedded"][lookup.collectionName]) {
            console.error(
              `Cant find data under the collectionname ${lookup.collectionName}, is it configured correctly? ${link.href}`
            );
          }
          data = data["_embedded"][lookup.collectionName];
          this.lookups[locale][key] = [];
          data.forEach((value) => {
            const label = value[lookup.label];
            if (lookup.valueField) {
              value = value[lookup.valueField];
            }
            this.lookups[locale][key].push({ value, label });
          });
        });
      });
    }
  }

  getLookups(key): any[] {
    if (!this.currentLocale) {
      return [];
    }
    return this.lookups[this.currentLocale][key];
  }

  toggleContentVisibility() {
    this.contentVisible = !this.contentVisible;
    this.contentVisibleEntry.value = this.contentVisible.toString();
  }

  public onSubmit() {
    console.debug(this.form.value);
  }

  rangeChange(event, field: FormWidgetField) {
    this.rangeModes[field.identifier] = event.checked;
    this.forceEmit.next();
    this.rangeModesEntry.value = JSON.stringify(this.rangeModes);
  }

  public isFieldVisible(field: FormWidgetField) {
    if (field.basic) {
      return true;
    }
    const value = this.fieldsVisible[field.identifier];
    if (value === undefined) {
      return true;
    }
    return value;
  }

  public toggleMode($event) {
    this.listsearch = $event.checked;
    this.searchModeChanged.next(this.listsearch);
    this.isListsearchEntry.value = $event.checked;
    if (this.listsearch) {
      this.listchange.next(this.listSearchForm.value);
    } else {
      this.forceEmit.next();
    }
  }

  public submit() {
    this.doSubmit.next(this.listsearch);
  }

  public save() {
    this.doSave.next();
  }

  public resetClick() {
    this.resetOutput.next();
    this.reset.next();
  }

  private setListsearchValue(value) {
    this.listSearchForm.patchValue({ list: value });
    this.listsearchValueEntry.value = JSON.stringify(this.listSearchForm.value);
  }

  public formcontrolNameFor(field: FormWidgetField) {
    if (field.allowRange) {
      return field.identifier + "From";
    }
    return field.identifier;
  }

  public onInputEvent(event: FormEventPayload) {
    this.event.next(event);
  }

  public resetFavoritesSelect() {
    if (!this.resentFavoritesChanged) {
      this.favoriteForm.patchValue({ searchfavorites: null });
    }
  }

  public showLabel(attribute) {
    return attribute.type == "BOOLEAN";
  }

  public attributeSupportsRange(attribute) {
    return !(
      attribute.type == "BOOLEAN" ||
      attribute.type == "LOOKUP" ||
      attribute.type == "MULTI_LOOKUP" ||
      attribute.type == "STRING" ||
      attribute.type == "LOCALIZED_STRING"
    );
  }

  public mergeForms() {
    if (this.expanded && this.advancedFormData) {
      const data = Object.assign({}, this.advancedFormData, this.basicData);
      return data;
    }

    return this.basicData;
  }

  public computeNumberListMaxHeight(): string {
    if (this.listsearch) {
      let topList = this.numberList_ref?.nativeElement?.getBoundingClientRect()
        .top;
      let topFooter = this.nmSearchFooter_ref?.nativeElement?.getBoundingClientRect()
        .top;
      let maxHeight = topFooter - topList - EMPTY_ADVANCED_SEARCH_HEIGHT_PX;
      return maxHeight + "px";
    }
    return "0";
  }

  private recoverFromData(data: Attribute[], attributes: Attribute[]) {
    this.attributes = [];
    this.changedAttributes = [];
    data.forEach((entry) => {
      const attribute: Attribute = deepCopy(
        attributes.find((attribute) => attribute.id === entry.id)
      );
      attribute.source = entry.source;

      if (entry.from) {
        attribute.from = entry.from;
        attribute.displayRange = true;
      } else {
        attribute.from = {
          identifier: attribute.identifier,
          source: [],
          type: attribute.type,
        };
      }
      if (entry.to) {
        attribute.to = entry.to;
        attribute.displayRange = true;
      } else {
        attribute.to = {
          identifier: attribute.identifier,
          source: [],
          type: attribute.type,
        };
      }
      this.attributes.push(attribute);
      this.changedAttributes.push(attribute);
    });
    this.attributesOutput.next(this.changedAttributes);
    this.attributesLocalstorageEntry.value = JSON.stringify(this.attributes);
    this.changedAttributesLocalstorageEntry.value = JSON.stringify(
      this.changedAttributes
    );
  }

  public getTooltipValueForAttribute(attribute: Attribute) {
    return attribute.source
      .map((entry) =>
        entry.description && entry.description.length > 1
          ? entry.description
          : entry.value
      )
      .join(" | ");
    // return attribute.source[0].description && attribute.source[0].description.length > 1) ? attribute.source[0].description : attribute.source[0].value
  }

  onAdvancedSearchChanged(data: any) {
    this.advancedFormData = data;
    let merged = this.mergeForms();
    this.change.next(merged);
    this.data.fields = merged;
    this.dataOutput.next(this.data);
  }

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

  getHeightModifier() {
    let fontSize = this.scrollService.getFontSize().value;
    let modifier: number = 0;
    switch (fontSize) {
      case "small": {
        modifier = +14;
        break;
      }
      case "medium": {
        modifier = 0;
        break;
      }
      case "large":
      default: {
        modifier = -32;
        break;
      }
    }
    return modifier;
  }

  onListValueChange(listValues: any) {
    if (listValues) {
      this.listsearch = true;
      this.listvalue.next(listValues);
    } else {
      this.listsearch = false;
    }
  }

  onExpandToggle($event: any) {
    this.expanded = $event;
    this.onAdvancedSearchChanged(this.advancedFormData);
    // hide/unhide attributes for next search
    if (this.expanded) {
      this.attributesOutput.next(this.data.attributes);
    } else {
      this.attributesOutput.next([]);
    }
  }

  public copyToClipboard(event) {
    this.copyNonMatchingParametersToClipboard.next(this.listsearch);
  }
}
<nm-widgetframe
  [header]="header"
  [configuration]="configuration"
  [infoTitle]="title"
  [infoText]="
    listsearch ? configuration.configuration.listSearchInfoText : infoText
  "
  [infoWidth]="configuration.configuration.infoWidth"
  [infoHeight]="configuration.configuration.infoHeight"
  [widgetId]="id"
  [infoPlacement]="'bottom'"
  [wikiLink]="wikiLink"
  [isCollapsible]="isCollapsible"
>
  <div slot="title" class="nm-widgetframe__title">
    {{
      (listsearch ? configuration.configuration.listSearchTitle : title)
        | translate
    }}
  </div>

  <div slot="buttons" class="nm-widgetframe__buttons">
    <mat-slide-toggle
      matTooltip="{{ 'infotext.switchsearchmode' | translate }}"
      matTooltipShowDelay="500"
      [(ngModel)]="listsearch"
      (change)="toggleMode($event)"
    >
    </mat-slide-toggle>
  </div>

  <div slot="content" class="nm-widgetframe__content basic-search">
    <div>
      <form
        [class.hidden]="listsearch"
        [formGroup]="form"
        (ngSubmit)="onSubmit()"
        autocomplete="off"
      >
        <div>
          <div *ngFor="let field of fields" class="form-row">
            <ng-container *ngIf="field.basic">
              <div class="form-input">
                <ng-container
                  *ngIf="rangeModes[field.identifier]; else noRange"
                >
                  <div class="range-left">
                    <nm-form-widget-input
                      [field]="field"
                      [lookups]="lookups"
                      (event)="onInputEvent($event)"
                      (enterPressed)="submit()"
                      [locale]="currentLocale"
                      [placeholder]="
                        ('from' | translate) +
                        ' ' +
                        (field.description | translate)
                      "
                      [formControlName]="field.identifier + 'From'"
                      [autofocus]="field.autofocus"
                    ></nm-form-widget-input>
                  </div>
                  <div class="range-right">
                    <nm-form-widget-input
                      [field]="field"
                      [lookups]="lookups"
                      (event)="onInputEvent($event)"
                      (enterPressed)="submit()"
                      [locale]="currentLocale"
                      [placeholder]="
                        ('to' | translate) +
                        ' ' +
                        (field.description | translate)
                      "
                      [formControlName]="field.identifier + 'Until'"
                      [autofocus]="field.autofocus"
                    ></nm-form-widget-input>
                  </div>
                </ng-container>
                <ng-template #noRange>
                  <nm-form-widget-input
                    [field]="field"
                    (event)="onInputEvent($event)"
                    (enterPressed)="submit()"
                    [lookups]="lookups"
                    [placeholder]="field.description | translate"
                    [locale]="currentLocale"
                    [formControlName]="formcontrolNameFor(field)"
                    [autofocus]="field.autofocus"
                  ></nm-form-widget-input>
                </ng-template>
              </div>
              <div class="range-switch" *ngIf="field.allowRange">
                <mat-slide-toggle
                  [checked]="rangeModes[field.identifier]"
                  (change)="rangeChange($event, field)"
                ></mat-slide-toggle>
              </div>
            </ng-container>
          </div>
        </div>
      </form>
    </div>

    <div [class.hidden]="!listsearch">
      <form [formGroup]="listSearchForm" autocomplete="off">
        <nm-form-widget-input
          [field]="listsearchmodeField"
          [lookups]="lookups"
          [placeholder]="listsearchmodeField.description | translate"
          [locale]="currentLocale"
          [formControlName]="formcontrolNameFor(listsearchmodeField)"
        ></nm-form-widget-input>
        <mat-form-field>
          <textarea
            matInput
            #searchNumberList
            id="searchNumberList"
            formControlName="list"
            [placeholder]="'searchlist.placeholder' | translate"
            [ngStyle]="{ 'max-height': computeNumberListMaxHeight() }"
          >
          </textarea>
        </mat-form-field>
      </form>

      <nm-button
        [disabled]="exportButtonDisabled"
        (fireEvent)="copyToClipboard($event)"
        class="nm-search__footerButton"
        [buttonType]="'mat-icon-button'"
        [pTooltip]="'ipim.web.search.errors.export.tooltip' | translate"
        [icon]="'article'"
      >
      </nm-button>
    </div>

    <div class="spacer"></div>
    <nm-search-advanced
      [lookups]="configuration.configuration.lookups"
      [fields]="configuration.configuration.fields"
      [links]="configuration._links"
      [locale]="locale"
      (search)="onAdvancedSearchChanged($event)"
      (attributes)="onAttributesChanged($event)"
      (expandToggle)="onExpandToggle($event)"
      [reset]="resetOutput"
      [prefix]="configuration.configuration.localstoragePrefix"
      [attributeUrl]="configuration.configuration.attributeUrl"
      [selectFilterParams]="configuration.configuration.selectFilterParams"
      [dataInput]="dataOutput"
      [searchFavorites]="searchFavorites"
      [attributeTypesToAddMultiple]="attributeTypesToAddMultiple"
      [dialogWithActionMenu]="true"
      [listsearch]="listsearch"
      [searchModeChanged]="searchModeChanged"
      [listHeight]="listHeight"
      (listvalueOutput)="onListValueChange($event)"
      (templateOutput)="value.next($event)"
      [enableRoleBasedSearchTemplates]="enableRoleBasedSearchTemplates"
    >
    </nm-search-advanced>

    <div style="clear: both"><br /></div>
    <div #nmSearchFooter class="nm-search__footer">
      <form
        [formGroup]="searchModeForm"
        class="nm-search__searchModeInput"
        autocomplete="off"
      >
        <div class="form-input">
          <nm-form-widget-input
            [field]="searchModeField"
            (event)="onInputEvent($event)"
            [lookups]="lookups"
            [placeholder]="searchModeField.description | translate"
            [locale]="currentLocale"
            [formControlName]="formcontrolNameFor(searchModeField)"
          ></nm-form-widget-input>
        </div>
      </form>

      <div style="flex-grow: 1"></div>

      <button
        mat-raised-button
        color="primary"
        class="nm-search__footerButton"
        (click)="submit()"
      >
        {{ "placeholder.search" | translate }}
      </button>

      <button
        mat-button
        type="button"
        class="nm-search__footerButton"
        style="margin-right: 16px"
        (click)="resetClick()"
      >
        {{ "button.reset" | translate }}
      </button>
    </div>
  </div>
</nm-widgetframe>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""