nm-rating-search
src/app/shared/widgets/search/rating-search-widget.component.ts
selector | nm-rating-search |
styleUrls | rating-search-widget.component.scss |
templateUrl | ./rating-search-widget.component.html |
Widget inputs |
Widget outputs |
Properties |
|
Methods |
constructor(translateService: TranslateService, appDataStore: AppdataStore, localstorageService: LocalStorageService, widgetframeService: WidgetframeService, appContext: AppContext, cd: ChangeDetectorRef)
|
|||||||||||||||||||||
Parameters :
|
Public configureWidget | ||||||
configureWidget(config: WidgetConfig
|
||||||
Decorators : WidgetConfigure
|
||||||
Parameters :
Returns :
void
|
doSearch |
doSearch()
|
Returns :
void
|
Private initToolboxEdits |
initToolboxEdits()
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
onAdvancedSearchChanged | ||||||
onAdvancedSearchChanged(data: any)
|
||||||
Parameters :
Returns :
void
|
onAttributesChanged | ||||||
onAttributesChanged(attributes: Attribute[])
|
||||||
Parameters :
Returns :
void
|
onExpandToggle | ||||||
onExpandToggle($event: boolean)
|
||||||
Parameters :
Returns :
void
|
onModeChange |
onModeChange()
|
Returns :
void
|
onWorklistSelect | ||||
onWorklistSelect(worklist: )
|
||||
Parameters :
Returns :
void
|
reset |
reset()
|
Returns :
void
|
searchListStringChange |
searchListStringChange()
|
Returns :
void
|
searchStringChange |
searchStringChange()
|
Returns :
void
|
Private advancedData |
advancedData:
|
Type : any
|
Public advancedSearch |
advancedSearch:
|
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:
|
Type : WidgetConfig<RatingSearchConfiguration>
|
Decorators : WidgetConfiguration
|
Public data |
data:
|
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:
|
Type : Selectors
|
Public nodeMenuSelectors |
nodeMenuSelectors:
|
Type : Selectors
|
Public prefix |
prefix:
|
Type : string
|
Public reloadLookups |
reloadLookups:
|
Default value : new ReplaySubject<string[]>()
|
Decorators : WidgetInput
|
Public resetPressed |
resetPressed:
|
Default value : new Subject()
|
Decorators : WidgetOutput
|
Public searchFavorites |
searchFavorites:
|
Type : boolean
|
Default value : false
|
Public searchingDataOutput |
searchingDataOutput:
|
Default value : new Subject()
|
Decorators : WidgetOutput
|
Public searchInputLabel |
searchInputLabel:
|
Type : string
|
Private searchListEntry |
searchListEntry:
|
Type : LocalStorageEntry
|
Private searchModeEntry |
searchModeEntry:
|
Type : LocalStorageEntry
|
Public searchmodeSelect |
searchmodeSelect:
|
Default value : true
|
searchOnFieldsChanged |
searchOnFieldsChanged:
|
Type : any
|
Private searchStringEntry |
searchStringEntry:
|
Type : LocalStorageEntry
|
Public searchTemplatesUri |
searchTemplatesUri:
|
Type : string
|
Public staticFolders |
staticFolders:
|
Type : any[]
|
Public termOutput |
termOutput:
|
Default value : new ReplaySubject(1)
|
Decorators : WidgetOutput
|
Private unsubscribe |
unsubscribe:
|
Default value : NgUnsubscribe.create()
|
Public withHeader |
withHeader:
|
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>