Implement sync with parent state params for dashboard state component

This commit is contained in:
Igor Kulikov 2021-12-23 19:01:43 +02:00
parent ce3d929fec
commit 3ae20647aa
7 changed files with 47 additions and 11 deletions

View File

@ -150,6 +150,7 @@ export type StateControllerHolder = () => IStateController;
export interface IStateController {
dashboardCtrl: IDashboardController;
getStateParams(): StateParams;
stateChanged(): Observable<any>;
getStateParamsByStateId(stateId: string): StateParams;
openState(id: string, params?: StateParams, openRightLayout?: boolean): void;
updateState(id?: string, params?: StateParams, openRightLayout?: boolean): void;

View File

@ -14,23 +14,24 @@
/// limitations under the License.
///
import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { Dashboard } from '@shared/models/dashboard.models';
import { StateObject, StateParams } from '@core/api/widget-api.models';
import { updateEntityParams, WidgetContext } from '../../models/widget-component.models';
import { StateObject } from '@core/api/widget-api.models';
import { updateEntityParams, WidgetContext } from '@home/models/widget-component.models';
import { deepClone, objToBase64 } from '@core/utils';
import { IDashboardComponent } from '@home/models/dashboard-component.models';
import { EntityId } from '@shared/models/id/entity-id';
import { Subscription } from 'rxjs';
@Component({
selector: 'tb-dashboard-state',
templateUrl: './dashboard-state.component.html',
styleUrls: []
})
export class DashboardStateComponent extends PageComponent implements OnInit {
export class DashboardStateComponent extends PageComponent implements OnInit, OnDestroy {
@Input()
ctx: WidgetContext;
@ -38,6 +39,9 @@ export class DashboardStateComponent extends PageComponent implements OnInit {
@Input()
stateId: string;
@Input()
syncParentStateParams = false;
@Input()
entityParamName: string;
@ -50,12 +54,31 @@ export class DashboardStateComponent extends PageComponent implements OnInit {
parentDashboard: IDashboardComponent;
private stateSubscription: Subscription;
constructor(protected store: Store<AppState>) {
super(store);
}
ngOnInit(): void {
this.dashboard = deepClone(this.ctx.stateController.dashboardCtrl.dashboardCtx.getDashboard());
this.updateCurrentState();
this.parentDashboard = this.ctx.parentDashboard ?
this.ctx.parentDashboard : this.ctx.dashboard;
if (this.syncParentStateParams) {
this.stateSubscription = this.ctx.stateController.stateChanged().subscribe(() => {
this.updateCurrentState();
});
}
}
ngOnDestroy(): void {
if (this.stateSubscription) {
this.stateSubscription.unsubscribe();
}
}
private updateCurrentState(): void {
const stateObject: StateObject = {};
const params = deepClone(this.ctx.stateController.getStateParams());
updateEntityParams(params, this.entityParamName, this.entityId);
@ -64,7 +87,5 @@ export class DashboardStateComponent extends PageComponent implements OnInit {
stateObject.id = this.stateId;
}
this.currentState = objToBase64([stateObject]);
this.parentDashboard = this.ctx.parentDashboard ?
this.ctx.parentDashboard : this.ctx.dashboard;
}
}

View File

@ -54,7 +54,7 @@ export class DefaultStateControllerComponent extends StateControllerComponent im
super.ngOnDestroy();
}
protected init() {
public init() {
if (this.preservedState) {
this.stateObject = this.preservedState;
setTimeout(() => {

View File

@ -58,7 +58,7 @@ export class EntityStateControllerComponent extends StateControllerComponent imp
super.ngOnDestroy();
}
protected init() {
public init() {
if (this.preservedState) {
this.stateObject = this.preservedState;
this.selectedStateIndex = this.stateObject.length - 1;

View File

@ -17,7 +17,7 @@
import { IStateControllerComponent, StateControllerState } from '@home/components/dashboard-page/states/state-controller.models';
import { IDashboardController } from '../dashboard-page.models';
import { DashboardState } from '@app/shared/models/dashboard.models';
import { Subscription } from 'rxjs';
import { Observable, Subject, Subscription } from 'rxjs';
import { NgZone, OnDestroy, OnInit, Directive } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { StatesControllerService } from '@home/components/dashboard-page/states/states-controller.service';
@ -27,6 +27,7 @@ import { StateObject, StateParams } from '@app/core/api/widget-api.models';
@Directive()
export abstract class StateControllerComponent implements IStateControllerComponent, OnInit, OnDestroy {
private stateChangedSubject = new Subject();
stateObject: StateControllerState = [];
dashboardCtrl: IDashboardController;
preservedState: any;
@ -108,6 +109,7 @@ export abstract class StateControllerComponent implements IStateControllerCompon
const newState = this.decodeStateParam(paramMap.get('state'));
if (this.currentState !== newState) {
this.currentState = newState;
this.stateChangedSubject.next();
if (this.inited) {
this.onStateChanged();
}
@ -124,6 +126,7 @@ export abstract class StateControllerComponent implements IStateControllerCompon
subscription.unsubscribe();
});
this.rxSubscriptions.length = 0;
this.stateChangedSubject.complete();
}
protected updateStateParam(newState: string, replaceCurrentHistoryUrl = false) {
@ -142,6 +145,11 @@ export abstract class StateControllerComponent implements IStateControllerCompon
});
});
}
this.stateChangedSubject.next();
}
public stateChanged(): Observable<any> {
return this.stateChangedSubject.asObservable();
}
public openRightLayout(): void {
@ -159,6 +167,7 @@ export abstract class StateControllerComponent implements IStateControllerCompon
public reInit() {
this.preservedState = null;
this.currentState = this.decodeStateParam(this.route.snapshot.queryParamMap.get('state'));
this.stateChangedSubject.next();
this.init();
}
@ -166,7 +175,7 @@ export abstract class StateControllerComponent implements IStateControllerCompon
return stateURI !== null ? decodeURIComponent(stateURI) : null;
}
protected abstract init();
public abstract init();
protected abstract onMobileChanged();

View File

@ -30,4 +30,5 @@ export interface IStateControllerComponent extends IStateController {
dashboardId: string;
preservedState: any;
reInit(): void;
init(): void;
}

View File

@ -76,6 +76,7 @@ export class StatesComponentDirective implements OnInit, OnDestroy, OnChanges {
ngOnChanges(changes: SimpleChanges): void {
let reInitController = false;
let initController = false;
for (const propName of Object.keys(changes)) {
const change = changes[propName];
if (!change.firstChange && change.currentValue !== change.previousValue) {
@ -92,12 +93,15 @@ export class StatesComponentDirective implements OnInit, OnDestroy, OnChanges {
this.stateControllerComponent.state = this.state;
} else if (propName === 'currentState') {
this.stateControllerComponent.currentState = this.currentState;
initController = true;
} else if (propName === 'syncStateWithQueryParam') {
this.stateControllerComponent.syncStateWithQueryParam = this.syncStateWithQueryParam;
}
}
}
if (reInitController) {
if (initController) {
this.stateControllerComponent.init();
} else if (reInitController) {
this.stateControllerComponent.reInit();
}
}