nm-content-overview
src/app/shared/widgets/apps/ipim-content-object/content-overview/overview.component.ts
Used in iPIM Buy. No Widgetframe.
Button of type mat-raised-button
selector | nm-content-overview |
styleUrls | overview.component.scss |
templateUrl | ./overview.component.html |
Widget inputs |
Widget outputs |
Properties |
|
Methods |
|
constructor(_widgetframeService: WidgetframeService, authHttp: HttpClient, _notificationService: NotificationsService, _localStorageService: LocalStorageService, _translateService: TranslateService, injector: Injector, router: Router, route: ActivatedRoute)
|
|||||||||||||||||||||||||||
Parameters :
|
Protected configureWidget | ||||||
configureWidget(configuration: WidgetConfig)
|
||||||
Decorators : WidgetConfigure
|
||||||
Parameters :
Returns :
void
|
confirmSave |
confirmSave()
|
Returns :
void
|
definitionChanged |
definitionChanged()
|
Returns :
void
|
Private getContentTypes | ||||||
getContentTypes(selectedWidgetLocale: string)
|
||||||
Parameters :
Returns :
void
|
Private mapToOverview |
mapToOverview(data: any, contentNo: any, widgetLocale: any)
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
Private openConfirmationDialog |
openConfirmationDialog(messageTitle: string, messageDescription: string)
|
Returns :
MatDialogRef<ConfirmationDialogComponent>
|
openLink | ||||||
openLink(contentNo: , event: )
|
||||||
Parameters :
Returns :
boolean
|
Private resetOverviewData |
resetOverviewData()
|
Returns :
void
|
resetValidFromDateTime | ||||
resetValidFromDateTime(event: )
|
||||
Parameters :
Returns :
void
|
resetValidUntilDateTime | ||||
resetValidUntilDateTime(event: )
|
||||
Parameters :
Returns :
void
|
Private saveDefinition |
saveDefinition()
|
Returns :
void
|
saveDisabled |
saveDisabled()
|
Returns :
boolean
|
validateDateRange |
validateDateRange()
|
Returns :
void
|
Public _id |
_id:
|
Decorators : WidgetId
|
Public assetHref |
assetHref:
|
Default value : new ReplaySubject<any>(1)
|
Public assets |
assets:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Private autoSearchLocalStorage |
autoSearchLocalStorage:
|
Type : LocalStorageEntry
|
Public configuration |
configuration:
|
Type : WidgetConfig
|
Decorators : WidgetConfiguration
|
Public contentLocale |
contentLocale:
|
Type : string
|
Public contentName |
contentName:
|
Type : string
|
Public contentNo |
contentNo:
|
Default value : new ReplaySubject<any>()
|
Decorators : WidgetInput
|
Private contentNoLocalStorage |
contentNoLocalStorage:
|
Type : LocalStorageEntry
|
Public contentType |
contentType:
|
Type : any
|
Public contentTypesLink |
contentTypesLink:
|
Type : string
|
Public contentValidFrom |
contentValidFrom:
|
Type : Date
|
Public contentValidUntil |
contentValidUntil:
|
Type : Date
|
Public dataChanged |
dataChanged:
|
Default value : false
|
Public dialog |
dialog:
|
Type : MatDialog
|
Public identifier |
identifier:
|
Type : string
|
Public infoText |
infoText:
|
Type : string
|
Public infoTitle |
infoTitle:
|
Type : string
|
Public isDateRangeValid |
isDateRangeValid:
|
Type : boolean
|
Default value : true
|
Public isDefinitionSaved |
isDefinitionSaved:
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Decorators : WidgetOutput
|
Private openRelation |
openRelation:
|
Type : Subject<any>
|
Default value : new ReplaySubject<any>(1)
|
Decorators : WidgetOutput
|
Private openRelationLocalStorage |
openRelationLocalStorage:
|
Type : LocalStorageEntry
|
Public overviewData |
overviewData:
|
Type : any
|
Default value : null
|
Public relationURL |
relationURL:
|
Type : string
|
Public reload |
reload:
|
Default value : new BehaviorSubject<any>(new Date())
|
Decorators : WidgetInput
|
Public resetChannel |
resetChannel:
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Public saveLink |
saveLink:
|
Type : string
|
Public selectedLocale |
selectedLocale:
|
Default value : new ReplaySubject<any>()
|
Decorators : WidgetInput
|
Public selectedUiLocale |
selectedUiLocale:
|
Type : BehaviorSubject<any>
|
Default value : new BehaviorSubject<any>(
null
)
|
Decorators : WidgetInput
|
Public title |
title:
|
Type : string
|
Public types |
types:
|
Type : any[]
|
Private unsubscribe |
unsubscribe:
|
Default value : NgUnsubscribe.create()
|
Public wikiLink |
wikiLink:
|
Type : string
|
import {
combineLatest as observableCombineLatest,
Subject,
ReplaySubject,
BehaviorSubject,
} from "rxjs";
import { map, takeUntil } from "rxjs/operators";
import { Component } from "@angular/core";
import { WidgetframeService } from "../../../widgetframe/widgetframe.service";
import { WidgetConfig } from "../../../widget.configuration";
import { NgUnsubscribe } from "../../../../ng-unsubscribe";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { MatDialog, MatDialogRef } from "@angular/material/dialog";
import { Injector } from "@angular/core";
import { ConfirmationDialogComponent } from "../../../../components/dialog";
import { NotificationsService } from "../../../../components/notifications/services/notifications.service";
import { TranslateService } from "@ngx-translate/core";
import {
WidgetComponent,
WidgetId,
WidgetConfiguration,
WidgetConfigure,
WidgetInput,
WidgetOutput,
} from "../../../widget.metadata";
import * as uriTemplates_ from "uri-templates";
import { Router, ActivatedRoute } from "@angular/router";
import {
LocalStorageEntry,
LocalStorageService,
} from "../../../../components/local-storage/local-storage.service";
import {
Scope,
DeletionMode,
} from "../../../../components/local-storage/local-storage-constants";
const uriTemplates = uriTemplates_;
declare var $: any;
/**
* Used in iPIM Buy.
* No Widgetframe.
*
* Button of type mat-raised-button
*/
@WidgetComponent("nm-content-overview")
@Component({
selector: "nm-content-overview",
templateUrl: "./overview.component.html",
styleUrls: ["./overview.component.scss"],
})
export class OverviewWidgetComponent {
public title: string;
public identifier: string;
public contentName: string;
public contentType: any;
public contentValidFrom: Date;
public contentValidUntil: Date;
public contentLocale: string;
public overviewData: any = null;
public infoText: string;
public infoTitle: string;
public wikiLink: string;
public relationURL: string;
public contentTypesLink: string;
public dataChanged = false;
public types: any[];
public assetHref = new ReplaySubject<any>(1);
public isDateRangeValid: boolean = true;
public saveLink: string;
private autoSearchLocalStorage: LocalStorageEntry;
private contentNoLocalStorage: LocalStorageEntry;
private openRelationLocalStorage: LocalStorageEntry;
public dialog: MatDialog;
@WidgetId()
public _id;
@WidgetConfiguration()
public configuration: WidgetConfig;
@WidgetInput()
public contentNo = new ReplaySubject<any>();
@WidgetInput()
public assets = new Subject<any>();
@WidgetInput()
public selectedLocale = new ReplaySubject<any>();
@WidgetInput()
public selectedUiLocale: BehaviorSubject<any> = new BehaviorSubject<any>(
null
);
@WidgetInput("reset")
public resetChannel = new Subject<any>();
@WidgetOutput("relation")
private openRelation: Subject<any> = new ReplaySubject<any>(1);
@WidgetInput()
public reload = new BehaviorSubject<any>(new Date());
@WidgetOutput()
public isDefinitionSaved: Subject<any> = new Subject<any>();
private unsubscribe = NgUnsubscribe.create();
constructor(
private _widgetframeService: WidgetframeService,
private authHttp: HttpClient,
private _notificationService: NotificationsService,
private _localStorageService: LocalStorageService,
private _translateService: TranslateService,
injector: Injector,
private router: Router,
private route: ActivatedRoute
) {
this.dialog = injector.get(MatDialog);
}
@WidgetConfigure()
protected configureWidget(configuration: WidgetConfig) {
this.title = configuration.configuration["title"];
this.infoText = configuration.configuration["infoText"];
this.infoTitle = configuration.configuration["infoTitle"];
this.wikiLink = this.configuration.configuration["wikiLink"];
this.relationURL = this.configuration.configuration["relationURL"];
this.contentTypesLink = configuration._links["contentTypes"]["href"];
this.saveLink = configuration.configuration["update-definition"];
let overviewHref = configuration._links["overview"]["href"];
let headerTemplate = uriTemplates(overviewHref);
observableCombineLatest(
this.contentNo.asObservable(),
this.selectedLocale.asObservable(),
this.reload.asObservable(),
(selectedContent, selectedLocale) => {
let params = {};
params["content"] = selectedContent[0];
params["locale"] = selectedLocale;
return params;
}
).subscribe((params) => {
if (!this.saveDisabled()) {
this.confirmSave();
} else if (params["content"] && params["locale"]) {
if (this.dataChanged) {
this._notificationService.alert(
this._translateService.instant(
"app.iPimContentMGT.frontend.alert.discard-changes.title"
),
this._translateService.instant(
"app.iPimContentMGT.frontend.alert.discard-changes.message"
)
);
this.dataChanged = false;
}
} else if (this.dataChanged) {
this._notificationService.alert(
this._translateService.instant(
"app.iPimContentMGT.frontend.alert.discard-changes.title"
),
this._translateService.instant(
"app.iPimContentMGT.frontend.alert.discard-changes.message"
)
);
this.dataChanged = false;
}
if (params == null || params["content"] == null) {
this.resetOverviewData();
return;
}
if (params["locale"] == null) {
return;
}
if (this.saveDisabled()) {
let contentNo = params["content"]["identifier"];
let widgetLocale = params["locale"];
this.getContentTypes(widgetLocale);
let assetHref1 = uriTemplates(
configuration._links["assets"]["href"]
).fill({ content: contentNo, "data-locale": widgetLocale });
this.assetHref.next(assetHref1);
let href = headerTemplate.fill({
content: contentNo,
"data-locale": widgetLocale,
});
this._widgetframeService.getData(href).subscribe(
(data) => {
this.mapToOverview(data, contentNo, widgetLocale);
},
(error) => {
this.overviewData = null;
}
);
}
});
this.resetChannel
.asObservable()
.pipe(takeUntil(this.unsubscribe))
.subscribe((reset) => {
this.dataChanged = false;
this.getContentTypes(this.contentLocale);
this.resetOverviewData();
this.contentNo.next([]);
});
}
openLink(contentNo, event) {
event.stopPropagation();
this.autoSearchLocalStorage = this._localStorageService.getLocalStorageEntry(
"autoSearch",
Scope.GLOBAL,
DeletionMode.LOGIN
);
this.contentNoLocalStorage = this._localStorageService.getLocalStorageEntry(
"content-searchInput",
Scope.GLOBAL,
DeletionMode.LOGIN
);
this.openRelationLocalStorage = this._localStorageService.getLocalStorageEntry(
"content-openRelation",
Scope.GLOBAL,
DeletionMode.LOGIN
);
this.autoSearchLocalStorage.value = "true";
this.contentNoLocalStorage.value = contentNo;
this.openRelationLocalStorage.value = "true";
this.router.navigate([this.relationURL], { relativeTo: this.route });
this.openRelation.next(contentNo);
return false;
}
private getContentTypes(selectedWidgetLocale: string): void {
if (!selectedWidgetLocale) {
return;
}
let template = uriTemplates(this.contentTypesLink);
let uriParams = {};
uriParams["locale"] = selectedWidgetLocale;
this.contentLocale = selectedWidgetLocale;
this.types = [];
this.authHttp
.get(template.fill(uriParams), {})
.pipe(map((res) => <any>res))
.subscribe((data: any) => {
if (data && data._embedded !== undefined) {
for (const type of data._embedded["content-type"]) {
this.types = this.types.concat(type);
}
}
});
}
resetValidFromDateTime(event) {
event.stopPropagation();
this.contentValidFrom = null;
this.dataChanged = true;
this.validateDateRange();
}
resetValidUntilDateTime(event) {
event.stopPropagation();
this.contentValidUntil = null;
this.dataChanged = true;
this.validateDateRange();
}
validateDateRange() {
if (this.contentValidUntil) {
this.contentValidUntil.setSeconds(0, 0);
}
if (this.contentValidFrom) {
this.contentValidFrom.setSeconds(0, 0);
}
if (this.contentValidUntil && this.contentValidFrom) {
this.isDateRangeValid = this.contentValidUntil > this.contentValidFrom;
} else {
this.isDateRangeValid = true;
}
}
private mapToOverview(data: any, contentNo: any, widgetLocale: any) {
console.log("data", data);
this.overviewData = data;
this.identifier = contentNo;
this.contentName = this.overviewData.description;
this.contentType = this.overviewData.type;
if (this.overviewData.validFrom) {
const date = new Date(this.overviewData.validFrom);
date.setHours(
date.getHours(),
date.getMinutes() - date.getTimezoneOffset(),
0,
0
);
this.contentValidFrom = date;
} else {
this.contentValidFrom = null;
}
if (this.overviewData.validUntil) {
const date = new Date(this.overviewData.validUntil);
date.setHours(
date.getHours(),
date.getMinutes() - date.getTimezoneOffset(),
0,
0
);
this.contentValidUntil = date;
} else {
this.contentValidUntil = null;
}
this.validateDateRange();
}
private resetOverviewData() {
this.overviewData = null;
this.contentName = null;
this.contentType = null;
this.contentValidFrom = null;
this.contentValidUntil = null;
this.identifier = "";
}
definitionChanged(): void {
this.dataChanged = true;
}
saveDisabled(): boolean {
return (
!this.dataChanged ||
this.contentName.length == 0 ||
!this.isDateRangeValid
);
}
confirmSave(): void {
let dialogRef = this.openConfirmationDialog(
"app.iPimContentMGT.frontend.content.save",
"app.iPimContentMGT.frontend.content.save.message"
);
dialogRef.afterClosed().subscribe((confirmed) => {
if (confirmed) {
this.saveDefinition();
this.dataChanged = false;
} else {
this.dataChanged = false;
this.reload.next("reload");
}
});
}
private openConfirmationDialog(
messageTitle: string,
messageDescription: string
): MatDialogRef<ConfirmationDialogComponent> {
let dialogRef = this.dialog.open(ConfirmationDialogComponent);
dialogRef.componentInstance["title"] = this._translateService.instant(
messageTitle
);
dialogRef.componentInstance["message"] = this._translateService.instant(
messageDescription
);
dialogRef.componentInstance[
"buttonAcceptTitle"
] = this._translateService.instant("button.accept");
dialogRef.componentInstance[
"buttonCancelTitle"
] = this._translateService.instant("button.cancel");
return dialogRef;
}
private saveDefinition(): void {
let template = uriTemplates(this.saveLink);
let uriParams = {};
uriParams["content"] = this.identifier;
uriParams["ui-locale"] = this.selectedUiLocale.value;
let content = JSON.stringify({
locale: this.contentLocale,
description: this.contentName,
type: this.contentType,
validFrom: this.contentValidFrom,
validUntil: this.contentValidUntil,
});
let headers = new HttpHeaders();
headers.append("Content-Type", "application/json");
headers.append("Accept", "application/json");
this.authHttp
.put(template.fill(uriParams), content, { headers: headers })
.pipe(map((res) => <any>res))
.subscribe(
(response) => {
if (response.contentNo && response.contentNo !== "") {
this._notificationService.success(
response.title,
response.messages
);
this.isDefinitionSaved.next(true);
} else {
this._notificationService.error(response.title, response.messages);
}
this.reload.next("reload");
this.dataChanged = false;
},
(err) => {
let errorResponse = err.error;
this._notificationService.error(
errorResponse.error,
errorResponse.message
);
this.dataChanged = false;
this.isDefinitionSaved.next(true);
}
);
}
ngOnInit() {}
}
<nm-widgetframe
[header]="configuration.configuration['header']"
[configuration]="configuration"
[infoText]="infoText"
[infoTitle]="infoTitle"
[wikiLink]="wikiLink"
[infoPlacement]="'left'"
widgetId="{{ _id }}"
>
<div slot="title" class="nm-widgetframe__title">
{{ title | translate
}}<span *ngIf="contentName && overviewData"
>: {{ contentName }} [{{ identifier }}]</span
>
</div>
<div slot="content" class="nm-widgetframe__content">
<nm-gallery
[href]="assetHref"
[assets]="assets"
[width]="'100%'"
[height]="'400px'"
*ngIf="overviewData !== null"
></nm-gallery>
<div class="info" *ngIf="overviewData !== null">
<div class="definition-row">
<mat-form-field class="full-width definition-input">
<input
matInput
type="text"
[(ngModel)]="contentName"
(ngModelChange)="definitionChanged()"
[placeholder]="
'app.iPimContentMGT.frontend.content-definition.name' | translate
"
/>
</mat-form-field>
</div>
<div class="definition-row">
<div class="nm-select">
<mat-form-field class="full-width definition-input">
<mat-select
[(ngModel)]="contentType"
style="width: 100%"
required
(ngModelChange)="definitionChanged()"
[placeholder]="
'app.iPimContentMGT.frontend.content-definition.type'
| translate
"
>
<mat-option *ngFor="let type of types" [value]="type.identifier">
{{ type.description }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="definition-row">
<div class="full-width">
<mat-form-field
class="full-width definition-input"
(click)="datetimepickervalidfrom.open()"
[ngClass]="{ 'nm-date-time-input': true }"
>
<input
matInput
[(ngModel)]="contentValidFrom"
(ngModelChange)="definitionChanged()"
[owlDateTime]="datetimepickervalidfrom"
(dateTimeInput)="validateDateRange()"
[placeholder]="
'app.iPimContentMGT.frontend.overview.validfrom' | translate
"
/>
<button
mat-icon-button
color="primary"
matSuffix
class="remove-action"
*ngIf="contentValidFrom"
(click)="resetValidFromDateTime($event)"
>
<mat-icon class="fade-in">close</mat-icon>
</button>
<button
mat-button
matSuffix
color="primary"
mat-icon-button
aria-label="date_range"
[owlDateTimeTrigger]="datetimepickervalidfrom"
>
<mat-icon>event</mat-icon>
</button>
</mat-form-field>
<owl-date-time #datetimepickervalidfrom></owl-date-time>
</div>
</div>
<div class="definition-row">
<div class="full-width definition-input">
<mat-form-field
class="full-width definition-input"
(click)="datetimepickervaliduntil.open()"
[ngClass]="{ 'nm-date-time-input': true }"
>
<input
matInput
[(ngModel)]="contentValidUntil"
(ngModelChange)="definitionChanged()"
[owlDateTime]="datetimepickervaliduntil"
(dateTimeInput)="validateDateRange()"
[placeholder]="
'app.iPimContentMGT.frontend.overview.validuntil' | translate
"
/>
<button
mat-icon-button
color="primary"
matSuffix
class="remove-action"
*ngIf="contentValidUntil"
(click)="resetValidUntilDateTime($event)"
>
<mat-icon class="fade-in">close</mat-icon>
</button>
<button
mat-button
matSuffix
color="primary"
mat-icon-button
aria-label="date_range"
[owlDateTimeTrigger]="datetimepickervaliduntil"
>
<mat-icon>event</mat-icon>
</button>
</mat-form-field>
<owl-date-time #datetimepickervaliduntil></owl-date-time>
</div>
<mat-error class="dateRangeError" *ngIf="!isDateRangeValid">{{
"app.iPimContentMGT.frontend.error.date-range-invalid" | translate
}}</mat-error>
</div>
<div
class="main-text"
*ngIf="overviewData?.mainDescription !== null"
style="-webkit-box-orient: vertical !important"
[innerHTML]="overviewData.mainDescription | sanitizeHtml"
></div>
<div
style="margin-top: 25px; margin-bottom: 15px"
*ngIf="overviewData?.relations.length > 0"
>
<mat-label style="color: #757575">{{
"app.iPimContentMGT.frontend.content-relations.title" | translate
}}</mat-label>
<br />
<a
*ngFor="let relation of overviewData?.relations; let last = last"
(click)="openLink(relation, $event)"
>
{{ relation }}
<br *ngIf="!last" />
</a>
</div>
<footer>
<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
<button
id="definition-save-button"
mat-raised-button
type="button"
color="primary"
(click)="confirmSave()"
[disabled]="saveDisabled()"
>
{{ "button.save" | translate }}
</button>
</div>
</footer>
</div>
</div>
</nm-widgetframe>