nm-search-app-search
src/app/shared/widgets/search-app-search-widget/search-app-search-widget.component.ts
providers |
EditAttributeService
|
selector | nm-search-app-search |
styleUrls | search-app-search-widget.component.scss |
templateUrl | ./search-app-search-widget.component.html |
constructor(widgetframeService: WidgetframeService, localstorageService: LocalStorageService, dialog: MatDialog, translateService: TranslateService, datetimeAdapter: DateTimeAdapter
|
||||||||||||||||||||||||||||||
Parameters :
|
Public attributeSupportsRange | ||||
attributeSupportsRange(attribute: )
|
||||
Parameters :
Returns :
boolean
|
Public computeNumberListMaxHeight |
computeNumberListMaxHeight()
|
Returns :
string
|
Public configure | ||||||
configure(configuration: WidgetConfig
|
||||||
Decorators : WidgetConfigure
|
||||||
Parameters :
Returns :
void
|
Public copyToClipboard | ||||
copyToClipboard(event: )
|
||||
Parameters :
Returns :
void
|
Public formcontrolNameFor | ||||||
formcontrolNameFor(field: FormWidgetField)
|
||||||
Parameters :
Returns :
any
|
getHeightModifier |
getHeightModifier()
|
Returns :
number
|
getLookups | ||||
getLookups(key: )
|
||||
Parameters :
Returns :
any[]
|
Public getTooltipValueForAttribute | ||||||
getTooltipValueForAttribute(attribute: Attribute)
|
||||||
Parameters :
Returns :
any
|
Public isFieldVisible | ||||||
isFieldVisible(field: FormWidgetField)
|
||||||
Parameters :
Returns :
any
|
Private loadLookups | ||||
loadLookups(locale: )
|
||||
Parameters :
Returns :
void
|
Public mergeForms |
mergeForms()
|
Returns :
any
|
onAdvancedSearchChanged | ||||||
onAdvancedSearchChanged(data: any)
|
||||||
Parameters :
Returns :
void
|
onAttributesChanged | ||||||
onAttributesChanged(attributes: Attribute[])
|
||||||
Parameters :
Returns :
void
|
onExpandToggle | ||||||
onExpandToggle($event: any)
|
||||||
Parameters :
Returns :
void
|
Public onInputEvent | ||||||
onInputEvent(event: FormEventPayload)
|
||||||
Parameters :
Returns :
void
|
onListValueChange | ||||||
onListValueChange(listValues: any)
|
||||||
Parameters :
Returns :
void
|
Public onSubmit |
onSubmit()
|
Returns :
void
|
rangeChange | |||||||||
rangeChange(event: , field: FormWidgetField)
|
|||||||||
Parameters :
Returns :
void
|
Private recoverChangedAttributes |
recoverChangedAttributes()
|
Returns :
void
|
Private recoverFormValue |
recoverFormValue()
|
Returns :
void
|
Private recoverFromData | |||||||||
recoverFromData(data: Attribute[], attributes: Attribute[])
|
|||||||||
Parameters :
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 :
Returns :
void
|
Private setListsearchValue | ||||
setListsearchValue(value: )
|
||||
Parameters :
Returns :
void
|
Public showLabel | ||||
showLabel(attribute: )
|
||||
Parameters :
Returns :
boolean
|
Public submit |
submit()
|
Returns :
void
|
toggleContentVisibility |
toggleContentVisibility()
|
Returns :
void
|
Public toggleMode | ||||
toggleMode($event: )
|
||||
Parameters :
Returns :
void
|
Private updateLookups | |||||||||
updateLookups(keys: string[], locale: )
|
|||||||||
Parameters :
Returns :
void
|
Public _editAttributeService |
_editAttributeService:
|
Type : EditAttributeService
|
Private _listsearch |
_listsearch:
|
Type : boolean
|
Private advancedFormData |
advancedFormData:
|
Type : any
|
Public attributeData |
attributeData:
|
Default value : new Subject<Attribute[]>()
|
Decorators : WidgetInput
|
Public attributes |
attributes:
|
Type : Attribute[]
|
Private attributesLocalstorageEntry |
attributesLocalstorageEntry:
|
Type : LocalStorageEntry
|
Public attributesOutput |
attributesOutput:
|
Default value : new ReplaySubject<any>(1)
|
Decorators : WidgetOutput
|
Public attributeTypesToAddMultiple |
attributeTypesToAddMultiple:
|
Type : string[]
|
Private basicData |
basicData:
|
Type : any
|
Public basicform |
basicform:
|
Public change |
change:
|
Default value : new BehaviorSubject<any>({})
|
Decorators : WidgetOutput
|
Public changedAttributes |
changedAttributes:
|
Type : []
|
Default value : []
|
Private changedAttributesLocalstorageEntry |
changedAttributesLocalstorageEntry:
|
Type : LocalStorageEntry
|
Public configuration |
configuration:
|
Type : WidgetConfig<FormWidgetConfiguration>
|
Decorators : WidgetConfiguration
|
Public contentVisible |
contentVisible:
|
Type : boolean
|
Default value : false
|
Public contentVisibleEntry |
contentVisibleEntry:
|
Type : LocalStorageEntry
|
Public copyNonMatchingParametersToClipboard |
copyNonMatchingParametersToClipboard:
|
Default value : new Subject()
|
Decorators : WidgetOutput
|
Public currentLocale |
currentLocale:
|
Private data |
data:
|
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:
|
Type : boolean
|
Public event |
event:
|
Default value : new Subject<FormEventPayload>()
|
Decorators : WidgetOutput
|
Private expanded |
expanded:
|
Type : boolean
|
Default value : true
|
exportButtonDisabled |
exportButtonDisabled:
|
Type : boolean
|
Default value : true
|
Public favoriteField |
favoriteField:
|
Type : FormWidgetField
|
Default value : {
identifier: "searchfavorites",
description: "table.head.searchfavorite",
type: "LOOKUP",
lookupSource: "searchfavorites",
eventField: true,
range: "never",
}
|
Public favoriteForm |
favoriteForm:
|
Public fields |
fields:
|
Type : FormWidgetField[]
|
Public fieldsVisible |
fieldsVisible:
|
Type : object
|
Default value : {}
|
Private fieldsVisibleEntry |
fieldsVisibleEntry:
|
Type : LocalStorageEntry
|
Public fieldsVisibleFavorite |
fieldsVisibleFavorite:
|
Private fieldsVisibleFavoriteEntry |
fieldsVisibleFavoriteEntry:
|
Type : LocalStorageEntry
|
Private forceEmit |
forceEmit:
|
Default value : new Subject<void>()
|
Public form |
form:
|
Private formValueEntry |
formValueEntry:
|
Type : LocalStorageEntry
|
Public formValues |
formValues:
|
Type : object
|
Default value : {}
|
Public frameHeight |
frameHeight:
|
Public hasSystemAttributes |
hasSystemAttributes:
|
Type : boolean
|
Default value : false
|
Public header |
header:
|
Public id |
id:
|
Type : string
|
Decorators : WidgetId
|
Public infoText |
infoText:
|
Public isCollapsible |
isCollapsible:
|
Type : boolean
|
Default value : false
|
Private isListsearchEntry |
isListsearchEntry:
|
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:
|
Type : FormWidgetField
|
Default value : {
identifier: "parameter",
description: "table.head.listsearchmodes",
type: "LOOKUP",
lookupSource: "listsearchmodes",
default: "PRODUCTNO",
range: "never",
}
|
Public listsearchValue |
listsearchValue:
|
Private listsearchValueEntry |
listsearchValueEntry:
|
Type : LocalStorageEntry
|
Public listvalue |
listvalue:
|
Default value : new Subject()
|
Decorators : WidgetInput
|
Public locale |
locale:
|
Default value : new BehaviorSubject(null)
|
Decorators : WidgetInput
|
Public lookups |
lookups:
|
Type : object
|
Default value : {}
|
Private nmSearchFooter_ref |
nmSearchFooter_ref:
|
Type : ElementRef
|
Decorators : ViewChild
|
Private numberList_ref |
numberList_ref:
|
Type : ElementRef
|
Decorators : ViewChild
|
Public rangeModes |
rangeModes:
|
Type : object
|
Default value : {}
|
Private rangeModesEntry |
rangeModesEntry:
|
Type : LocalStorageEntry
|
Public reloadLookups |
reloadLookups:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Public resentFavoritesChanged |
resentFavoritesChanged:
|
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:
|
Type : boolean
|
Default value : true
|
Private searchMode |
searchMode:
|
Public searchModeChanged |
searchModeChanged:
|
Default value : new Subject<boolean>()
|
Private searchModeEntry |
searchModeEntry:
|
Type : LocalStorageEntry
|
Public searchModeField |
searchModeField:
|
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:
|
listsearch | ||||
getlistsearch()
|
||||
setlistsearch(value: )
|
||||
Parameters :
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>