UI: Add support select widget bundle when save as widget
This commit is contained in:
parent
deb8cf3a22
commit
60fa8f5f80
@ -110,6 +110,7 @@
|
|||||||
<span class="tb-details-subtitle">{{ 'widgets-bundle.current' | translate }}</span>
|
<span class="tb-details-subtitle">{{ 'widgets-bundle.current' | translate }}</span>
|
||||||
<tb-widgets-bundle-select fxFlexOffset="5"
|
<tb-widgets-bundle-select fxFlexOffset="5"
|
||||||
fxFlex
|
fxFlex
|
||||||
|
required
|
||||||
[selectFirstBundle]="false"
|
[selectFirstBundle]="false"
|
||||||
[selectBundleAlias]="selectedWidgetsBundleAlias"
|
[selectBundleAlias]="selectedWidgetsBundleAlias"
|
||||||
[ngModel]="null"
|
[ngModel]="null"
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<form [formGroup]="saveWidgetTypeAsFormGroup" (ngSubmit)="saveAs()">
|
<form [formGroup]="saveWidgetTypeAsFormGroup" (ngSubmit)="saveAs()" style="width: 360px">
|
||||||
<mat-toolbar color="primary">
|
<mat-toolbar color="primary">
|
||||||
<h2 translate>widget.save-widget-type-as</h2>
|
<h2 translate>widget.save-widget-type-as</h2>
|
||||||
<span fxFlex></span>
|
<span fxFlex></span>
|
||||||
@ -29,7 +29,6 @@
|
|||||||
</mat-progress-bar>
|
</mat-progress-bar>
|
||||||
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
|
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<fieldset>
|
|
||||||
<span translate>widget.save-widget-type-as-text</span>
|
<span translate>widget.save-widget-type-as-text</span>
|
||||||
<mat-form-field class="mat-block">
|
<mat-form-field class="mat-block">
|
||||||
<mat-label translate>widget.title</mat-label>
|
<mat-label translate>widget.title</mat-label>
|
||||||
@ -38,7 +37,11 @@
|
|||||||
{{ 'widget.title-required' | translate }}
|
{{ 'widget.title-required' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</fieldset>
|
<tb-widgets-bundle-select
|
||||||
|
formControlName="widgetsBundle"
|
||||||
|
allowEmptyBundle
|
||||||
|
bundlesScope="{{bundlesScope}}">
|
||||||
|
</tb-widgets-bundle-select>
|
||||||
</div>
|
</div>
|
||||||
<div mat-dialog-actions fxLayoutAlign="end center">
|
<div mat-dialog-actions fxLayoutAlign="end center">
|
||||||
<button mat-button color="primary"
|
<button mat-button color="primary"
|
||||||
|
|||||||
@ -18,12 +18,15 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import { MatDialogRef } from '@angular/material/dialog';
|
import { MatDialogRef } from '@angular/material/dialog';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppState } from '@core/core.state';
|
import { AppState } from '@core/core.state';
|
||||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { DialogComponent } from '@shared/components/dialog.component';
|
import { DialogComponent } from '@shared/components/dialog.component';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { getCurrentAuthUser } from '@core/auth/auth.selectors';
|
||||||
|
import { Authority } from '@shared/models/authority.enum';
|
||||||
|
|
||||||
export interface SaveWidgetTypeAsDialogResult {
|
export interface SaveWidgetTypeAsDialogResult {
|
||||||
widgetName: string;
|
widgetName: string;
|
||||||
|
widgetBundleId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -34,18 +37,27 @@ export interface SaveWidgetTypeAsDialogResult {
|
|||||||
export class SaveWidgetTypeAsDialogComponent extends
|
export class SaveWidgetTypeAsDialogComponent extends
|
||||||
DialogComponent<SaveWidgetTypeAsDialogComponent, SaveWidgetTypeAsDialogResult> implements OnInit {
|
DialogComponent<SaveWidgetTypeAsDialogComponent, SaveWidgetTypeAsDialogResult> implements OnInit {
|
||||||
|
|
||||||
saveWidgetTypeAsFormGroup: UntypedFormGroup;
|
saveWidgetTypeAsFormGroup: FormGroup;
|
||||||
|
bundlesScope: string;
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
public dialogRef: MatDialogRef<SaveWidgetTypeAsDialogComponent, SaveWidgetTypeAsDialogResult>,
|
public dialogRef: MatDialogRef<SaveWidgetTypeAsDialogComponent, SaveWidgetTypeAsDialogResult>,
|
||||||
public fb: UntypedFormBuilder) {
|
public fb: FormBuilder) {
|
||||||
super(store, router, dialogRef);
|
super(store, router, dialogRef);
|
||||||
|
|
||||||
|
const authUser = getCurrentAuthUser(store);
|
||||||
|
if (authUser.authority === Authority.TENANT_ADMIN) {
|
||||||
|
this.bundlesScope = 'tenant';
|
||||||
|
} else {
|
||||||
|
this.bundlesScope = 'system';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.saveWidgetTypeAsFormGroup = this.fb.group({
|
this.saveWidgetTypeAsFormGroup = this.fb.group({
|
||||||
title: [null, [Validators.required]]
|
title: [null, [Validators.required]],
|
||||||
|
widgetsBundle: [null]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +67,10 @@ export class SaveWidgetTypeAsDialogComponent extends
|
|||||||
|
|
||||||
saveAs(): void {
|
saveAs(): void {
|
||||||
const widgetName: string = this.saveWidgetTypeAsFormGroup.get('title').value;
|
const widgetName: string = this.saveWidgetTypeAsFormGroup.get('title').value;
|
||||||
|
const widgetBundleId: string = this.saveWidgetTypeAsFormGroup.get('widgetsBundle').value?.id?.id;
|
||||||
const result: SaveWidgetTypeAsDialogResult = {
|
const result: SaveWidgetTypeAsDialogResult = {
|
||||||
widgetName
|
widgetName,
|
||||||
|
widgetBundleId
|
||||||
};
|
};
|
||||||
this.dialogRef.close(result);
|
this.dialogRef.close(result);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -588,11 +588,25 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
|
|||||||
config.title = this.widget.widgetName;
|
config.title = this.widget.widgetName;
|
||||||
this.widget.defaultConfig = JSON.stringify(config);
|
this.widget.defaultConfig = JSON.stringify(config);
|
||||||
this.isDirty = false;
|
this.isDirty = false;
|
||||||
this.widgetService.saveWidgetTypeDetails(this.widget, undefined, undefined).subscribe(
|
this.widgetService.saveWidgetTypeDetails(this.widget, undefined, undefined).pipe(
|
||||||
|
mergeMap((widget) => {
|
||||||
|
if (saveWidgetAsData.widgetBundleId) {
|
||||||
|
return this.widgetService.addWidgetFqnToWidgetBundle(saveWidgetAsData.widgetBundleId, widget.fqn).pipe(
|
||||||
|
map(() => widget)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return of(widget);
|
||||||
|
})
|
||||||
|
).subscribe(
|
||||||
{
|
{
|
||||||
next: (widgetTypeDetails) => {
|
next: (widgetTypeDetails) => {
|
||||||
this.saveWidgetAsPending = false;
|
this.saveWidgetAsPending = false;
|
||||||
this.router.navigate(['..', widgetTypeDetails.id.id], {relativeTo: this.route});
|
if (saveWidgetAsData.widgetBundleId) {
|
||||||
|
this.router.navigate(['resources', 'widgets-library', 'widgets-bundles',
|
||||||
|
saveWidgetAsData.widgetBundleId, widgetTypeDetails.id.id]);
|
||||||
|
} else {
|
||||||
|
this.router.navigate(['resources', 'widgets-library', 'widget-types', widgetTypeDetails.id.id]);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
error: () => {
|
error: () => {
|
||||||
this.saveWidgetAsPending = false;
|
this.saveWidgetAsPending = false;
|
||||||
|
|||||||
@ -19,9 +19,9 @@
|
|||||||
<mat-select [required]="required"
|
<mat-select [required]="required"
|
||||||
[disabled]="disabled"
|
[disabled]="disabled"
|
||||||
[(ngModel)]="widgetsBundle"
|
[(ngModel)]="widgetsBundle"
|
||||||
matInput
|
|
||||||
panelClass="tb-widgets-bundle-select"
|
panelClass="tb-widgets-bundle-select"
|
||||||
placeholder="{{ 'widget.select-widgets-bundle' | translate }}"
|
placeholder="{{ 'widget.select-widgets-bundle' | translate }}"
|
||||||
|
(blur)="onTouched()"
|
||||||
(ngModelChange)="widgetsBundleChanged()">
|
(ngModelChange)="widgetsBundleChanged()">
|
||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
<div class="tb-bundle-item">
|
<div class="tb-bundle-item">
|
||||||
@ -29,6 +29,9 @@
|
|||||||
<span translate class="tb-bundle-system" *ngIf="isSystem(widgetsBundle)">widgets-bundle.system</span>
|
<span translate class="tb-bundle-system" *ngIf="isSystem(widgetsBundle)">widgets-bundle.system</span>
|
||||||
</div>
|
</div>
|
||||||
</mat-select-trigger>
|
</mat-select-trigger>
|
||||||
|
<mat-option [value]="null" *ngIf="!required">
|
||||||
|
---
|
||||||
|
</mat-option>
|
||||||
<mat-option *ngFor="let widgetsBundle of widgetsBundles$ | async" [value]="widgetsBundle">
|
<mat-option *ngFor="let widgetsBundle of widgetsBundles$ | async" [value]="widgetsBundle">
|
||||||
<div class="tb-bundle-item">
|
<div class="tb-bundle-item">
|
||||||
<span>{{widgetsBundle.title}}</span>
|
<span>{{widgetsBundle.title}}</span>
|
||||||
|
|||||||
@ -20,12 +20,12 @@ import { Observable } from 'rxjs';
|
|||||||
import { map, share, tap } from 'rxjs/operators';
|
import { map, share, tap } from 'rxjs/operators';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppState } from '@app/core/core.state';
|
import { AppState } from '@app/core/core.state';
|
||||||
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
||||||
import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
|
import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
|
||||||
import { WidgetService } from '@core/http/widget.service';
|
import { WidgetService } from '@core/http/widget.service';
|
||||||
import { isDefined } from '@core/utils';
|
import { isDefined } from '@core/utils';
|
||||||
import { NULL_UUID } from '@shared/models/id/has-uuid';
|
import { NULL_UUID } from '@shared/models/id/has-uuid';
|
||||||
import { getCurrentAuthState } from '@core/auth/auth.selectors';
|
import { getCurrentAuthState } from '@core/auth/auth.selectors';
|
||||||
|
import { coerceBoolean } from '@shared/decorators/coercion';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-widgets-bundle-select',
|
selector: 'tb-widgets-bundle-select',
|
||||||
@ -44,19 +44,15 @@ export class WidgetsBundleSelectComponent implements ControlValueAccessor, OnIni
|
|||||||
bundlesScope: 'system' | 'tenant';
|
bundlesScope: 'system' | 'tenant';
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
|
@coerceBoolean()
|
||||||
selectFirstBundle: boolean;
|
selectFirstBundle: boolean;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
selectBundleAlias: string;
|
selectBundleAlias: string;
|
||||||
|
|
||||||
private requiredValue: boolean;
|
|
||||||
get required(): boolean {
|
|
||||||
return this.requiredValue;
|
|
||||||
}
|
|
||||||
@Input()
|
@Input()
|
||||||
set required(value: boolean) {
|
@coerceBoolean()
|
||||||
this.requiredValue = coerceBooleanProperty(value);
|
required: boolean;
|
||||||
}
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
@ -70,7 +66,8 @@ export class WidgetsBundleSelectComponent implements ControlValueAccessor, OnIni
|
|||||||
|
|
||||||
widgetsBundle: WidgetsBundle | null;
|
widgetsBundle: WidgetsBundle | null;
|
||||||
|
|
||||||
private propagateChange = (v: any) => { };
|
onTouched = () => {};
|
||||||
|
private propagateChange: (value: any) => void = () => {};
|
||||||
|
|
||||||
constructor(private store: Store<AppState>,
|
constructor(private store: Store<AppState>,
|
||||||
private widgetService: WidgetService) {
|
private widgetService: WidgetService) {
|
||||||
@ -81,6 +78,7 @@ export class WidgetsBundleSelectComponent implements ControlValueAccessor, OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerOnTouched(fn: any): void {
|
registerOnTouched(fn: any): void {
|
||||||
|
this.onTouched = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user