diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html index db7e68516c..e5d006076e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.html @@ -88,12 +88,74 @@ -
-
{{'widget-config.icon' | translate}}
- - -
+ @if (widgetActionFormGroup.get('actionSourceId').value === 'headerButton') { +
+
widget-config.header-button.button-settings
+
+
widget-config.header-button.button-type
+ + + + {{ widgetHeaderActionButtonTypeTranslationMap.get(widgetHeaderActionButtonType[button]) | translate }} + + + +
+
+
+ + +
widget-config.icon
+
+ + +
+
+
{{ 'widget-config.header-button.colors' | translate }}
+
+
widget-config.header-button.color
+ + + +
widget-config.header-button.background
+ + + +
widget-config.header-button.border
+ + +
+
+
+ + + + widget-config.header-button.advanced-button-style + + + + + + +
+
+ } @else { +
+
{{'widget-config.icon' | translate}}
+ + +
+ } +
diff --git a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts index ab2b8870d0..5dd2276591 100644 --- a/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/action/widget-action-dialog.component.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { Component, Inject, OnDestroy, OnInit, SkipSelf, ViewChild } from '@angular/core'; +import { Component, DestroyRef, Inject, OnInit, SkipSelf, ViewChild } from '@angular/core'; import { ErrorStateMatcher } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Store } from '@ngrx/store'; @@ -28,7 +28,6 @@ import { ValidatorFn, Validators } from '@angular/forms'; -import { Subject } from 'rxjs'; import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; import { @@ -44,14 +43,17 @@ import { defaultWidgetAction, WidgetActionSource, WidgetActionType, + WidgetHeaderActionButtonType, + WidgetHeaderActionButtonTypes, + widgetHeaderActionButtonTypeTranslationMap, widgetType } from '@shared/models/widget.models'; -import { takeUntil } from 'rxjs/operators'; import { CustomActionEditorCompleter } from '@home/components/widget/lib/settings/common/action/custom-action.models'; import { WidgetService } from '@core/http/widget.service'; import { isDefinedAndNotNull, isNotEmptyStr } from '@core/utils'; import { MatSelect } from '@angular/material/select'; import { TranslateService } from '@ngx-translate/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; export interface WidgetActionDialogData { isAdd: boolean; @@ -69,9 +71,7 @@ export interface WidgetActionDialogData { styleUrls: [] }) export class WidgetActionDialogComponent extends DialogComponent implements OnInit, OnDestroy, ErrorStateMatcher { - - private destroy$ = new Subject(); + WidgetActionDescriptorInfo> implements OnInit, ErrorStateMatcher { widgetActionFormGroup: FormGroup; @@ -87,6 +87,10 @@ export class WidgetActionDialogComponent extends DialogComponent = []; usedCellClickColumns: Array = []; + widgetHeaderActionButtonType = WidgetHeaderActionButtonType + widgetHeaderActionButtonTypes = WidgetHeaderActionButtonTypes; + widgetHeaderActionButtonTypeTranslationMap = widgetHeaderActionButtonTypeTranslationMap; + @ViewChild('columnIndexSelect') columnIndexSelect: MatSelect; columnIndexPlaceholderText = this.translate.instant('widget-config.select-column-index'); @@ -98,7 +102,8 @@ export class WidgetActionDialogComponent extends DialogComponent, public fb: FormBuilder, - private translate: TranslateService) { + private translate: TranslateService, + private destroyRef: DestroyRef) { super(store, router, dialogRef); this.isAdd = data.isAdd; if (this.isAdd) { @@ -122,14 +127,21 @@ export class WidgetActionDialogComponent extends DialogComponent { this.widgetActionFormGroup.get('name').updateValueAndValidity(); this.updateShowWidgetActionForm(); @@ -141,10 +153,13 @@ export class WidgetActionDialogComponent extends DialogComponent { this.updateShowWidgetActionForm(); }); + this.widgetActionFormGroup.get('buttonType').valueChanges.pipe( + takeUntilDestroyed(this.destroyRef) + ).subscribe(() => this.widgetHeaderButtonValidators()); setTimeout(() => { if (this.action?.actionSourceId === 'cellClick') { this.widgetActionFormGroup.get('columnIndex').enable(); @@ -156,10 +171,29 @@ export class WidgetActionDialogComponent extends DialogComponent - +
+ @for (action of widget.customHeaderActions; track action.name; let last = $last) { + + } +
+
+ + +@switch (action.buttonType) { + @case (widgetHeaderActionButtonType.icon) { + + } + @case (widgetHeaderActionButtonType.miniFab) { + + } + @case (widgetHeaderActionButtonType.basic) { + + } + @case (widgetHeaderActionButtonType.raised) { + + } + @case (widgetHeaderActionButtonType.stroked) { + + } + @case (widgetHeaderActionButtonType.flat) { + + } +} + diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.scss b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.scss index 0894da25f7..b246bc1662 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.scss @@ -86,7 +86,7 @@ div.tb-widget { flex-direction: row; place-content: center flex-start; align-items: center; - z-index: 19; + z-index: 101; margin: 5px 0 0; &-absolute { diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.ts index b6f19e62a1..72252ada2c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-container.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-container.component.ts @@ -47,6 +47,8 @@ import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import ITooltipsterInstance = JQueryTooltipster.ITooltipsterInstance; import ITooltipsterGeoHelper = JQueryTooltipster.ITooltipsterGeoHelper; import { TbContextMenuEvent } from '@shared/models/jquery-event.models'; +import { WidgetHeaderActionButtonType } from '@shared/models/widget.models'; +import ITooltipsterInstance = JQueryTooltipster.ITooltipsterInstance; export enum WidgetComponentActionType { MOUSE_DOWN, @@ -130,6 +132,8 @@ export class WidgetContainerComponent extends PageComponent implements OnInit, O return (this.isEditActionEnabled || this.isRemoveActionEnabled || this.isExportActionEnabled) && !this.widget?.isFullscreen; } + widgetHeaderActionButtonType = WidgetHeaderActionButtonType; + private cssClass: string; private editWidgetActionsTooltip: ITooltipsterInstance; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index 6a0ab460d0..404992e186 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -298,7 +298,13 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges, const headerAction: WidgetHeaderAction = { name: descriptor.name, displayName: descriptor.displayName, + buttonType: descriptor.buttonType, + showIcon: descriptor.showIcon, icon: descriptor.icon, + buttonColor: descriptor.buttonColor, + buttonFillColor: descriptor.buttonFillColor, + buttonBorderColor: descriptor.buttonBorderColor, + customButtonStyle: descriptor.customButtonStyle, descriptor, useShowWidgetHeaderActionFunction, showWidgetHeaderActionFunction, diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index 66bddabd62..8a8724c116 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -26,6 +26,7 @@ import { WidgetActionSource, WidgetConfig, WidgetControllerDescriptor, + WidgetHeaderActionButtonType, WidgetType, widgetType, WidgetTypeDescriptor, @@ -126,6 +127,12 @@ export type ShowWidgetHeaderActionFunction = (ctx: WidgetContext, data: Formatte export interface WidgetHeaderAction extends IWidgetAction { displayName: string; descriptor: WidgetActionDescriptor; + buttonType?: WidgetHeaderActionButtonType; + showIcon?:boolean; + buttonColor?: string; + buttonFillColor?: string; + buttonBorderColor?: string; + customButtonStyle?: string; useShowWidgetHeaderActionFunction: boolean; showWidgetHeaderActionFunction: CompiledTbFunction; } diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index 11c4d19d82..44e5ec9c1e 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -570,6 +570,26 @@ export interface LegendData { data: Array; } +export enum WidgetHeaderActionButtonType { + basic = 'basic', + raised = 'raised', + stroked = 'stroked', + flat = 'flat', + icon = 'icon', + miniFab = 'miniFab' +} + +export const WidgetHeaderActionButtonTypes = Object.keys(WidgetHeaderActionButtonType) as WidgetHeaderActionButtonType[]; + +export const widgetHeaderActionButtonTypeTranslationMap = new Map([ + [WidgetHeaderActionButtonType.basic, 'widget-config.header-button.button-type-basic'], + [WidgetHeaderActionButtonType.raised, 'widget-config.header-button.button-type-raised'], + [WidgetHeaderActionButtonType.stroked, 'widget-config.header-button.button-type-stroked'], + [WidgetHeaderActionButtonType.flat, 'widget-config.header-button.button-type-flat'], + [WidgetHeaderActionButtonType.icon, 'widget-config.header-button.button-type-icon'], + [WidgetHeaderActionButtonType.miniFab, 'widget-config.header-button.button-type-mini-fab'] +]); + export enum WidgetActionType { doNothing = 'doNothing', openDashboardState = 'openDashboardState', @@ -754,7 +774,13 @@ export interface WidgetAction extends CustomActionDescriptor { export interface WidgetActionDescriptor extends WidgetAction { id: string; name: string; + buttonType?: WidgetHeaderActionButtonType; + showIcon?: boolean; icon: string; + buttonColor?: string; + buttonFillColor?: string; + buttonBorderColor?: string; + customButtonStyle?: string; displayName?: string; useShowWidgetActionFunction?: boolean; showWidgetActionFunction?: TbFunction; @@ -765,7 +791,13 @@ export const actionDescriptorToAction = (descriptor: WidgetActionDescriptor): Wi const result: WidgetActionDescriptor = {...descriptor}; delete result.id; delete result.name; + delete result.buttonType; + delete result.showIcon; delete result.icon; + delete result.buttonColor; + delete result.buttonFillColor; + delete result.buttonBorderColor; + delete result.customButtonStyle; delete result.displayName; delete result.useShowWidgetActionFunction; delete result.showWidgetActionFunction; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 6fd68a8478..f3e7f159a8 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -6700,6 +6700,22 @@ "action-name-required": "Action name is required.", "action-name-not-unique": "Another action with the same name already exists.\nAction name should be unique within the same action source.", "action-icon": "Icon", + "header-button": { + "button-settings": "Button settings", + "button-type": "Button type", + "button-type-basic": "Basic", + "button-type-raised": "Raised", + "button-type-stroked": "Stroked", + "button-type-flat": "Flat", + "button-type-icon": "Icon", + "button-type-mini-fab": "FAB", + "colors": "Colors", + "color": "Color", + "background": "Background", + "border": "Border", + "advanced-button-style": "Advanced button style", + "button-style": "Button style" + }, "show-hide-action-using-function": "Show/hide action using function", "show-action-function": "Show action function", "action-type": "Type",