nm-expansion-panel
src/app/shared/widgets/expansion-panel/expansion-panel.component.ts
changeDetection | ChangeDetectionStrategy.OnPush |
selector | nm-expansion-panel |
styleUrls | expansion-panel.component.scss |
templateUrl | ./expansion-panel.component.html |
Widget inputs |
Widget outputs |
Properties |
|
Methods |
constructor(localstorageService: LocalStorageService, _widgetframeService: WidgetframeService, currentLocaleService: CurrentLocaleService, cd: ChangeDetectorRef)
|
|||||||||||||||
Parameters :
|
Protected configureWidget | ||||||
configureWidget(configuration: WidgetConfig)
|
||||||
Decorators : WidgetConfigure
|
||||||
Parameters :
Returns :
void
|
getComponentSelector | ||||||
getComponentSelector(component: any)
|
||||||
Parameters :
Returns :
any
|
isComponentExpanded | ||||||
isComponentExpanded(component: any)
|
||||||
Parameters :
Returns :
any
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onPanelHeaderButtonClick |
onPanelHeaderButtonClick(event: Event, component: any)
|
Returns :
void
|
toggle | ||||
toggle(component: )
|
||||
Parameters :
Returns :
void
|
Private updateComponents | ||||||
updateComponents(data: any)
|
||||||
Parameters :
Returns :
void
|
updateLocalStorageEntry | ||||
updateLocalStorageEntry(configuration: )
|
||||
Parameters :
Returns :
void
|
Public components |
components:
|
Type : any
|
Public configuration |
configuration:
|
Type : WidgetConfig
|
Decorators : WidgetConfiguration
|
Public content |
content:
|
Type : Subject<any>
|
Default value : new Subject<any>()
|
Decorators : WidgetInput
|
Components sent directly from controller |
Public id |
id:
|
Type : string
|
Decorators : WidgetId
|
Public initiallyExpanded |
initiallyExpanded:
|
Type : boolean
|
Public isDisabled |
isDisabled:
|
Type : boolean
|
Enables or disables panels @default(false) |
Public lazyRendering |
lazyRendering:
|
Type : boolean
|
If lazyRendering is enabled, initialization of panels are deferred until they are opened; default is true |
Private localstorageEntry |
localstorageEntry:
|
Type : LocalStorageEntry
|
Public multiViewMode |
multiViewMode:
|
Type : boolean
|
If multiViewMode is enabled, more than one panel can be opened at the same time; default is true |
Private notificationKey |
notificationKey:
|
Type : string
|
Public panelStates |
panelStates:
|
Type : any
|
Default value : {}
|
Private unsubscribe |
unsubscribe:
|
Default value : NgUnsubscribe.create()
|
Public uri |
uri:
|
Type : Subject<string>
|
Default value : new Subject<string>()
|
Decorators : WidgetInput
|
Uri used to fetch data |
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
OnInit,
} from "@angular/core";
import { getOrDefault, WidgetConfig } from "../widget.configuration";
import {
WidgetComponent,
WidgetConfiguration,
WidgetConfigure,
WidgetId,
WidgetInput,
WidgetOutput,
} from "../widget.metadata";
import {
LocalStorageEntry,
LocalStorageService,
} from "../../components/local-storage/local-storage.service";
import {
DeletionMode,
Scope,
} from "../../components/local-storage/local-storage-constants";
import {
EMPTY,
Subject,
of as observableOf,
combineLatest as observableCombineLatest,
} from "rxjs";
import { catchError, mergeMap, switchMap, takeUntil } from "rxjs/operators";
import { NgUnsubscribe } from "../../ng-unsubscribe";
import { CurrentLocaleService } from "../../components/i18n/currentLocale.service";
import { WidgetframeService } from "../widgetframe/widgetframe.service";
@WidgetComponent("nm-expansion-panel")
@Component({
selector: "nm-expansion-panel",
templateUrl: "./expansion-panel.component.html",
styleUrls: ["./expansion-panel.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
/**
* "nm-expansion-panel" displays widgets inside mat-expansion panels. The title configured in each widget is shown in the expansion-panel-header.
* For layout reasons the widget should be configured as withBorder: false and withHeader: false
* Stores expanded state in locale storage, if "expansionStorageKey" is in json config.
*/
export class ExpansionPanelWidgetComponent implements OnInit {
@WidgetId()
public id: string;
@WidgetConfiguration()
public configuration: WidgetConfig;
/**
* Components sent directly from controller
*/
@WidgetInput()
public content: Subject<any> = new Subject<any>();
/**
* Uri used to fetch data
*/
@WidgetInput()
public uri: Subject<string> = new Subject<string>();
/**
* Emits the component which we clicked on its panel header button
*/
@WidgetOutput("firePanelHeaderButton")
private firePanelHeaderButton: Subject<any> = new Subject<any>();
private localstorageEntry: LocalStorageEntry;
public panelStates: any = {};
public components: any;
public initiallyExpanded: boolean;
/**
* Enables or disables panels @default(false)
*/
public isDisabled: boolean;
private notificationKey: string;
private unsubscribe = NgUnsubscribe.create();
/**
* If multiViewMode is enabled, more than one panel can be opened at the same time; default is true
*/
public multiViewMode: boolean;
/**
* If lazyRendering is enabled, initialization of panels are deferred until they are opened; default is true
*/
public lazyRendering: boolean;
constructor(
private localstorageService: LocalStorageService,
private _widgetframeService: WidgetframeService,
private currentLocaleService: CurrentLocaleService,
private cd: ChangeDetectorRef
) {}
@WidgetConfigure()
protected configureWidget(configuration: WidgetConfig) {
this.initiallyExpanded = getOrDefault(
this.configuration.configuration.isExpanded,
true
);
this.isDisabled = getOrDefault(
this.configuration.configuration.isDisabled,
false
);
this.notificationKey = getOrDefault(
this.configuration.configuration.notificationKey,
"imarket.api-call"
);
const configuredComponents = configuration?.configuration?.components;
if (configuredComponents) {
this.components = configuredComponents;
for (const component of configuredComponents) {
this.panelStates[component] = {};
this.panelStates[component].expanded = true;
}
}
this.multiViewMode = getOrDefault(
this.configuration.configuration.multiViewMode,
true
);
this.lazyRendering = getOrDefault(
this.configuration.configuration.lazyRendering,
true
);
this.updateLocalStorageEntry(configuration);
}
ngOnInit() {
this.content.pipe(takeUntil(this.unsubscribe)).subscribe((data) => {
if (data !== undefined) {
this.updateLocalStorageEntry(this.configuration);
this.updateComponents(data);
}
});
observableCombineLatest(
this.uri.asObservable(),
this.currentLocaleService.getCurrentLocale()
)
.pipe(
switchMap(([uri, locale]) => {
return observableOf(uri).pipe(
mergeMap((href) => this._widgetframeService.getData(href)),
catchError((error) => EMPTY)
);
}),
takeUntil(this.unsubscribe)
)
.subscribe((data) => {
if (data) {
this.updateLocalStorageEntry(this.configuration);
this.updateComponents(data);
}
});
}
private updateComponents(data: any) {
this.components = data;
for (const component of data) {
const selector = this.getComponentSelector(component);
this.panelStates[selector] = this.panelStates[selector]
? this.panelStates[selector]
: {};
this.panelStates[selector].expanded = this.isComponentExpanded(component);
}
this.cd.markForCheck();
}
updateLocalStorageEntry(configuration) {
if (configuration.configuration.expansionStorageKey) {
this.localstorageEntry = this.localstorageService.getLocalStorageEntry(
configuration.configuration.expansionStorageKey + "-expansion",
Scope.USER_AND_CLIENT,
DeletionMode.NEVER
);
if (this.localstorageEntry && this.localstorageEntry.exists()) {
this.panelStates = JSON.parse(this.localstorageEntry.value);
}
}
}
toggle(component) {
if (!this.localstorageEntry) {
return;
}
const selector = this.getComponentSelector(component);
if (this.panelStates[selector]) {
this.panelStates[selector].expanded = !this.panelStates[selector]
.expanded;
}
this.localstorageEntry.value = JSON.stringify(this.panelStates);
}
onPanelHeaderButtonClick(event: Event, component: any) {
event.stopPropagation();
this.firePanelHeaderButton.next(component);
return;
}
isComponentExpanded(component: any) {
const selector = this.getComponentSelector(component);
const expanded = this.panelStates[selector]
? this.panelStates[selector].expanded
: this.initiallyExpanded;
return expanded !== null && expanded !== undefined
? expanded
: this.initiallyExpanded;
}
getComponentSelector(component: any) {
return component.id ? component.id : component;
}
}
<mat-accordion
[multi]="multiViewMode"
*ngIf="components"
class="nm-expansionPanel mat-elevation-z0"
>
<mat-expansion-panel
*ngFor="let component of components; index as i"
class="mat-elevation-z0"
[expanded]="isComponentExpanded(component)"
[disabled]="isDisabled"
(afterCollapse)="toggle(component)"
(afterExpand)="toggle(component)"
>
<mat-expansion-panel-header>
<mat-panel-title class="nm-expansionPanel__title" color="primary">
{{
(component | widgetFor: configuration).configuration.title | translate
}}
</mat-panel-title>
<button
mat-icon-button
*ngIf="component.configuration?.panelHeaderBtn"
[disabled]="component.configuration.panelHeaderBtn.disabled"
(click)="onPanelHeaderButtonClick($event, component)"
disableRipple="true"
>
<mat-icon
[matTooltip]="
component.configuration.panelHeaderBtn.tooltip | translate
"
>{{ component.configuration.panelHeaderBtn.icon }}</mat-icon
>
</button>
</mat-expansion-panel-header>
<nm-container
*ngIf="!lazyRendering; else lazyRenderingTemplate"
[configuration]="component | widgetFor: configuration"
[parent]="id"
[id]="component"
>
</nm-container>
<ng-template #lazyRenderingTemplate>
<ng-template matExpansionPanelContent>
<nm-container
[configuration]="component | widgetFor: configuration"
[parent]="id"
[id]="component"
>
</nm-container>
</ng-template>
</ng-template>
</mat-expansion-panel>
</mat-accordion>