UI: Add support select widget bundle when save as widget

This commit is contained in:
Vladyslav_Prykhodko 2023-10-23 11:13:51 +03:00
parent deb8cf3a22
commit 60fa8f5f80
6 changed files with 61 additions and 28 deletions

View File

@ -110,6 +110,7 @@
<span class="tb-details-subtitle">{{ 'widgets-bundle.current' | translate }}</span>
<tb-widgets-bundle-select fxFlexOffset="5"
fxFlex
required
[selectFirstBundle]="false"
[selectBundleAlias]="selectedWidgetsBundleAlias"
[ngModel]="null"

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<form [formGroup]="saveWidgetTypeAsFormGroup" (ngSubmit)="saveAs()">
<form [formGroup]="saveWidgetTypeAsFormGroup" (ngSubmit)="saveAs()" style="width: 360px">
<mat-toolbar color="primary">
<h2 translate>widget.save-widget-type-as</h2>
<span fxFlex></span>
@ -29,7 +29,6 @@
</mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<div mat-dialog-content>
<fieldset>
<span translate>widget.save-widget-type-as-text</span>
<mat-form-field class="mat-block">
<mat-label translate>widget.title</mat-label>
@ -38,7 +37,11 @@
{{ 'widget.title-required' | translate }}
</mat-error>
</mat-form-field>
</fieldset>
<tb-widgets-bundle-select
formControlName="widgetsBundle"
allowEmptyBundle
bundlesScope="{{bundlesScope}}">
</tb-widgets-bundle-select>
</div>
<div mat-dialog-actions fxLayoutAlign="end center">
<button mat-button color="primary"

View File

@ -18,12 +18,15 @@ import { Component, OnInit } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
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 { Router } from '@angular/router';
import { getCurrentAuthUser } from '@core/auth/auth.selectors';
import { Authority } from '@shared/models/authority.enum';
export interface SaveWidgetTypeAsDialogResult {
widgetName: string;
widgetBundleId?: string;
}
@Component({
@ -34,18 +37,27 @@ export interface SaveWidgetTypeAsDialogResult {
export class SaveWidgetTypeAsDialogComponent extends
DialogComponent<SaveWidgetTypeAsDialogComponent, SaveWidgetTypeAsDialogResult> implements OnInit {
saveWidgetTypeAsFormGroup: UntypedFormGroup;
saveWidgetTypeAsFormGroup: FormGroup;
bundlesScope: string;
constructor(protected store: Store<AppState>,
protected router: Router,
public dialogRef: MatDialogRef<SaveWidgetTypeAsDialogComponent, SaveWidgetTypeAsDialogResult>,
public fb: UntypedFormBuilder) {
public fb: FormBuilder) {
super(store, router, dialogRef);
const authUser = getCurrentAuthUser(store);
if (authUser.authority === Authority.TENANT_ADMIN) {
this.bundlesScope = 'tenant';
} else {
this.bundlesScope = 'system';
}
}
ngOnInit(): void {
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 {
const widgetName: string = this.saveWidgetTypeAsFormGroup.get('title').value;
const widgetBundleId: string = this.saveWidgetTypeAsFormGroup.get('widgetsBundle').value?.id?.id;
const result: SaveWidgetTypeAsDialogResult = {
widgetName
widgetName,
widgetBundleId
};
this.dialogRef.close(result);
}

View File

@ -588,11 +588,25 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
config.title = this.widget.widgetName;
this.widget.defaultConfig = JSON.stringify(config);
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) => {
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: () => {
this.saveWidgetAsPending = false;

View File

@ -19,9 +19,9 @@
<mat-select [required]="required"
[disabled]="disabled"
[(ngModel)]="widgetsBundle"
matInput
panelClass="tb-widgets-bundle-select"
placeholder="{{ 'widget.select-widgets-bundle' | translate }}"
(blur)="onTouched()"
(ngModelChange)="widgetsBundleChanged()">
<mat-select-trigger>
<div class="tb-bundle-item">
@ -29,6 +29,9 @@
<span translate class="tb-bundle-system" *ngIf="isSystem(widgetsBundle)">widgets-bundle.system</span>
</div>
</mat-select-trigger>
<mat-option [value]="null" *ngIf="!required">
---
</mat-option>
<mat-option *ngFor="let widgetsBundle of widgetsBundles$ | async" [value]="widgetsBundle">
<div class="tb-bundle-item">
<span>{{widgetsBundle.title}}</span>

View File

@ -20,12 +20,12 @@ import { Observable } from 'rxjs';
import { map, share, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { AppState } from '@app/core/core.state';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
import { WidgetService } from '@core/http/widget.service';
import { isDefined } from '@core/utils';
import { NULL_UUID } from '@shared/models/id/has-uuid';
import { getCurrentAuthState } from '@core/auth/auth.selectors';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({
selector: 'tb-widgets-bundle-select',
@ -44,19 +44,15 @@ export class WidgetsBundleSelectComponent implements ControlValueAccessor, OnIni
bundlesScope: 'system' | 'tenant';
@Input()
@coerceBoolean()
selectFirstBundle: boolean;
@Input()
selectBundleAlias: string;
private requiredValue: boolean;
get required(): boolean {
return this.requiredValue;
}
@Input()
set required(value: boolean) {
this.requiredValue = coerceBooleanProperty(value);
}
@coerceBoolean()
required: boolean;
@Input()
disabled: boolean;
@ -70,7 +66,8 @@ export class WidgetsBundleSelectComponent implements ControlValueAccessor, OnIni
widgetsBundle: WidgetsBundle | null;
private propagateChange = (v: any) => { };
onTouched = () => {};
private propagateChange: (value: any) => void = () => {};
constructor(private store: Store<AppState>,
private widgetService: WidgetService) {
@ -81,6 +78,7 @@ export class WidgetsBundleSelectComponent implements ControlValueAccessor, OnIni
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
ngOnInit() {