UI: Refactoring

This commit is contained in:
Artem Dzhereleiko 2025-03-07 13:26:21 +02:00
parent 1c80a41580
commit fd8d3fbf62
3 changed files with 89 additions and 84 deletions

View File

@ -14,7 +14,7 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Component, Inject, OnDestroy, OnInit, SkipSelf, ViewChild } from '@angular/core'; import { Component, DestroyRef, Inject, OnDestroy, OnInit, SkipSelf, ViewChild } from '@angular/core';
import { ErrorStateMatcher } from '@angular/material/core'; import { ErrorStateMatcher } from '@angular/material/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
@ -28,7 +28,6 @@ import {
ValidatorFn, ValidatorFn,
Validators Validators
} from '@angular/forms'; } from '@angular/forms';
import { Subject } from 'rxjs';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { DialogComponent } from '@app/shared/components/dialog.component'; import { DialogComponent } from '@app/shared/components/dialog.component';
import { import {
@ -48,12 +47,12 @@ import {
widgetHeaderActionButtonTypeTranslationMap, widgetHeaderActionButtonTypeTranslationMap,
widgetType widgetType
} from '@shared/models/widget.models'; } from '@shared/models/widget.models';
import { takeUntil } from 'rxjs/operators';
import { CustomActionEditorCompleter } from '@home/components/widget/lib/settings/common/action/custom-action.models'; import { CustomActionEditorCompleter } from '@home/components/widget/lib/settings/common/action/custom-action.models';
import { WidgetService } from '@core/http/widget.service'; import { WidgetService } from '@core/http/widget.service';
import { isDefinedAndNotNull, isNotEmptyStr } from '@core/utils'; import { isDefinedAndNotNull, isNotEmptyStr } from '@core/utils';
import { MatSelect } from '@angular/material/select'; import { MatSelect } from '@angular/material/select';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
export interface WidgetActionDialogData { export interface WidgetActionDialogData {
isAdd: boolean; isAdd: boolean;
@ -72,8 +71,6 @@ export interface WidgetActionDialogData {
export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDialogComponent, export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDialogComponent,
WidgetActionDescriptorInfo> implements OnInit, OnDestroy, ErrorStateMatcher { WidgetActionDescriptorInfo> implements OnInit, OnDestroy, ErrorStateMatcher {
private destroy$ = new Subject<void>();
widgetActionFormGroup: FormGroup; widgetActionFormGroup: FormGroup;
isAdd: boolean; isAdd: boolean;
@ -103,7 +100,8 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
@SkipSelf() private errorStateMatcher: ErrorStateMatcher, @SkipSelf() private errorStateMatcher: ErrorStateMatcher,
public dialogRef: MatDialogRef<WidgetActionDialogComponent, WidgetActionDescriptorInfo>, public dialogRef: MatDialogRef<WidgetActionDialogComponent, WidgetActionDescriptorInfo>,
public fb: FormBuilder, public fb: FormBuilder,
private translate: TranslateService) { private translate: TranslateService,
private destroyRef: DestroyRef) {
super(store, router, dialogRef); super(store, router, dialogRef);
this.isAdd = data.isAdd; this.isAdd = data.isAdd;
if (this.isAdd) { if (this.isAdd) {
@ -141,7 +139,7 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
this.updateShowWidgetActionForm(); this.updateShowWidgetActionForm();
this.widgetHeaderButtonValidators(); this.widgetHeaderButtonValidators();
this.widgetActionFormGroup.get('actionSourceId').valueChanges.pipe( this.widgetActionFormGroup.get('actionSourceId').valueChanges.pipe(
takeUntil(this.destroy$) takeUntilDestroyed(this.destroyRef)
).subscribe((value) => { ).subscribe((value) => {
this.widgetActionFormGroup.get('name').updateValueAndValidity(); this.widgetActionFormGroup.get('name').updateValueAndValidity();
this.updateShowWidgetActionForm(); this.updateShowWidgetActionForm();
@ -153,12 +151,12 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
} }
}); });
this.widgetActionFormGroup.get('useShowWidgetActionFunction').valueChanges.pipe( this.widgetActionFormGroup.get('useShowWidgetActionFunction').valueChanges.pipe(
takeUntil(this.destroy$) takeUntilDestroyed(this.destroyRef)
).subscribe(() => { ).subscribe(() => {
this.updateShowWidgetActionForm(); this.updateShowWidgetActionForm();
}); });
this.widgetActionFormGroup.get('buttonType').valueChanges.pipe( this.widgetActionFormGroup.get('buttonType').valueChanges.pipe(
takeUntil(this.destroy$) takeUntilDestroyed(this.destroyRef)
).subscribe(() => this.widgetHeaderButtonValidators()); ).subscribe(() => this.widgetHeaderButtonValidators());
setTimeout(() => { setTimeout(() => {
if (this.action?.actionSourceId === 'cellClick') { if (this.action?.actionSourceId === 'cellClick') {
@ -172,8 +170,6 @@ export class WidgetActionDialogComponent extends DialogComponent<WidgetActionDia
} }
ngOnDestroy() { ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
super.ngOnDestroy(); super.ngOnDestroy();
} }

View File

@ -37,77 +37,10 @@
class="tb-widget-actions" class="tb-widget-actions"
[class]="{'tb-widget-actions-absolute': !(widget.showWidgetTitlePanel && !widgetComponent.widgetContext?.embedTitlePanel && (widget.showTitle||widget.hasAggregation))}" [class]="{'tb-widget-actions-absolute': !(widget.showWidgetTitlePanel && !widgetComponent.widgetContext?.embedTitlePanel && (widget.showTitle||widget.hasAggregation))}"
(mousedown)="$event.stopPropagation()"> (mousedown)="$event.stopPropagation()">
<div class="flex items-center gap-2"> <div class="flex items-center">
<ng-container *ngFor="let action of widget.customHeaderActions"> @for (action of widget.customHeaderActions; track action.name; let last = $last) {
@switch (action.buttonType) { <ng-container *ngTemplateOutlet="widgetHeaderActionButton; context:{ action, last }"></ng-container>
@case (widgetHeaderActionButtonType.icon) { }
<button mat-icon-button
[style]="action.customButtonStyle"
[class.!hidden]="isEdit"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
</button>
}
@case (widgetHeaderActionButtonType.miniFab) {
<button mat-mini-fab
[style]="action.customButtonStyle"
[class.!hidden]="isEdit"
[style.background-color]="action.buttonFillColor"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
</button>
}
@case (widgetHeaderActionButtonType.basic) {
<button [class.!hidden]="isEdit" mat-button
[style]="action.customButtonStyle"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
</button>
}
@case (widgetHeaderActionButtonType.raised) {
<button [class.!hidden]="isEdit" mat-raised-button
[style]="action.customButtonStyle"
[style.background-color]="action.buttonFillColor"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
</button>
}
@case (widgetHeaderActionButtonType.stroked) {
<button [class.!hidden]="isEdit" mat-stroked-button
[style]="action.customButtonStyle"
[style.border-color]="action.buttonBorderColor"
[style.background-color]="action.buttonFillColor"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
</button>
}
@case (widgetHeaderActionButtonType.flat) {
<button [class.!hidden]="isEdit" mat-flat-button
[style]="action.customButtonStyle"
[style.background-color]="action.buttonFillColor"
[style.border-color]="action.buttonBorderColor"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
</button>
}
}
</ng-container>
</div> </div>
<button mat-icon-button *ngFor="let action of widget.widgetActions" <button mat-icon-button *ngFor="let action of widget.widgetActions"
@ -168,3 +101,79 @@
</tb-timewindow> </tb-timewindow>
</div> </div>
</ng-template> </ng-template>
<ng-template #widgetHeaderActionButton let-action="action" let-last="last">
@switch (action.buttonType) {
@case (widgetHeaderActionButtonType.icon) {
<button mat-icon-button
[style]="action.customButtonStyle"
[class.!hidden]="isEdit"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
</button>
}
@case (widgetHeaderActionButtonType.miniFab) {
<button mat-mini-fab
[style]="action.customButtonStyle"
[class.!hidden]="isEdit"
[class.mr-2]="!last"
[style.background-color]="action.buttonFillColor"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
</button>
}
@case (widgetHeaderActionButtonType.basic) {
<button [class.!hidden]="isEdit" mat-button
[class.mr-2]="!last"
[style]="action.customButtonStyle"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
</button>
}
@case (widgetHeaderActionButtonType.raised) {
<button [class.!hidden]="isEdit" mat-raised-button
[class.mr-2]="!last"
[style]="action.customButtonStyle"
[style.background-color]="action.buttonFillColor"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
</button>
}
@case (widgetHeaderActionButtonType.stroked) {
<button [class.!hidden]="isEdit" mat-stroked-button
[class.mr-2]="!last"
[style]="action.customButtonStyle"
[style.border-color]="action.buttonBorderColor"
[style.background-color]="action.buttonFillColor"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
</button>
}
@case (widgetHeaderActionButtonType.flat) {
<button [class.!hidden]="isEdit" mat-flat-button
[class.mr-2]="!last"
[style]="action.customButtonStyle"
[style.background-color]="action.buttonFillColor"
[style.border-color]="action.buttonBorderColor"
(click)="action.onAction($event)"
matTooltip="{{ action.displayName }}"
matTooltipPosition="above">
<tb-icon matButtonIcon *ngIf="action.showIcon" [style.color]="action.buttonColor">{{ action.icon }}</tb-icon>
<span [style.color]="action.buttonColor">{{ action.displayName }}</span>
</button>
}
}
</ng-template>

View File

@ -86,8 +86,8 @@ div.tb-widget {
flex-direction: row; flex-direction: row;
place-content: center flex-start; place-content: center flex-start;
align-items: center; align-items: center;
z-index: 19; z-index: 101;
margin: 5px 0 5px; margin: 5px 0 0;
&-absolute { &-absolute {
position: absolute; position: absolute;