From a9bb238ab31a80ee513431674cd5028432934e55 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 18 Oct 2024 16:33:19 +0300 Subject: [PATCH 1/2] UI: Dashboard widget copy/paste and scada symbol animation for chrome fixes. --- .../src/app/core/services/dashboard-utils.service.ts | 10 ++++++---- .../layout/dashboard-layout.component.ts | 5 +++-- .../components/dashboard-page/layout/layout.models.ts | 6 ++++-- .../home/components/dashboard/dashboard.component.ts | 4 ++-- .../components/widget/lib/scada/scada-symbol.models.ts | 6 +++--- .../modules/home/models/dashboard-component.models.ts | 7 ++++--- ui-ngx/src/app/shared/models/jquery-event.models.ts | 6 ++++++ ui-ngx/src/app/shared/models/widget.models.ts | 2 ++ 8 files changed, 30 insertions(+), 16 deletions(-) diff --git a/ui-ngx/src/app/core/services/dashboard-utils.service.ts b/ui-ngx/src/app/core/services/dashboard-utils.service.ts index f0341410bc..235924f98f 100644 --- a/ui-ngx/src/app/core/services/dashboard-utils.service.ts +++ b/ui-ngx/src/app/core/services/dashboard-utils.service.ts @@ -636,7 +636,7 @@ export class DashboardUtilsService { targetLayout: DashboardLayoutId, widget: Widget, originalColumns?: number, - originalSize?: {sizeX: number; sizeY: number}, + originalSize?: WidgetSize, row?: number, column?: number, breakpoint = 'default'): void { @@ -661,8 +661,8 @@ export class DashboardUtilsService { mobileHeight: widget.config.mobileHeight, mobileHide: widget.config.mobileHide, desktopHide: widget.config.desktopHide, - preserveAspectRatio: widget.config.preserveAspectRatio, - resizable: widget.config.resizable + preserveAspectRatio: originalSize ? originalSize.preserveAspectRatio : widget.config.preserveAspectRatio, + resizable: originalSize ? originalSize.resizable : widget.config.resizable }; if (isUndefined(originalColumns)) { originalColumns = 24; @@ -1065,7 +1065,9 @@ export class DashboardUtilsService { const widgetLayout = layout.widgets[widget.id]; return { sizeX: widgetLayout.sizeX, - sizeY: widgetLayout.sizeY + sizeY: widgetLayout.sizeY, + preserveAspectRatio: widgetLayout.preserveAspectRatio, + resizable: widgetLayout.resizable }; } diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts index c04a2af3df..52742c54c4 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/dashboard-layout.component.ts @@ -39,6 +39,7 @@ import { map } from 'rxjs/operators'; import { displayGrids } from 'angular-gridster2/lib/gridsterConfig.interface'; import { BreakpointId, LayoutType, ViewFormatType } from '@shared/models/dashboard.models'; import { isNotEmptyStr } from '@core/utils'; +import { TbContextMenuEvent } from '@shared/models/jquery-event.models'; @Component({ selector: 'tb-dashboard-layout', @@ -319,12 +320,12 @@ export class DashboardLayoutComponent extends PageComponent implements ILayoutCo this.layoutCtx.dashboardCtrl.copyWidgetReference($event, this.layoutCtx, widget); } - pasteWidget($event: Event) { + pasteWidget($event: TbContextMenuEvent | KeyboardEvent) { const pos = this.dashboard.getEventGridPosition($event); this.layoutCtx.dashboardCtrl.pasteWidget($event, this.layoutCtx, pos); } - pasteWidgetReference($event: Event) { + pasteWidgetReference($event: TbContextMenuEvent | KeyboardEvent) { const pos = this.dashboard.getEventGridPosition($event); this.layoutCtx.dashboardCtrl.pasteWidgetReference($event, this.layoutCtx, pos); } diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts index 3ea9f553a8..7b54261945 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/layout/layout.models.ts @@ -14,13 +14,15 @@ /// limitations under the License. /// +import { TbContextMenuEvent } from '@shared/models/jquery-event.models'; + export interface ILayoutController { reload(); resetHighlight(); highlightWidget(widgetId: string, delay?: number); selectWidget(widgetId: string, delay?: number); - pasteWidget($event: MouseEvent); - pasteWidgetReference($event: MouseEvent); + pasteWidget($event: TbContextMenuEvent | KeyboardEvent); + pasteWidgetReference($event: TbContextMenuEvent | KeyboardEvent); } export enum LayoutWidthType { diff --git a/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts b/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts index fd031fa90f..7169e4a20b 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard/dashboard.component.ts @@ -529,7 +529,7 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo return dashboardWidget ? dashboardWidget.widget : null; } - getEventGridPosition(event: Event): WidgetPosition { + getEventGridPosition(event: TbContextMenuEvent | KeyboardEvent): WidgetPosition { const pos: WidgetPosition = { row: 0, column: 0 @@ -537,7 +537,7 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo const parentElement = $(this.gridster.el); let pageX = 0; let pageY = 0; - if (event instanceof MouseEvent) { + if ('pageX' in event && 'pageY' in event) { pageX = event.pageX; pageY = event.pageY; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts index 41611d3f6e..6d3e9fde82 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/scada/scada-symbol.models.ts @@ -1168,13 +1168,13 @@ class CssScadaSymbolAnimation implements ScadaSymbolAnimation { private element: Element, duration = 1000) { this._duration = duration; - this.fixPatternAnimationForChromeBelow128(); + this.fixPatternAnimationForChrome(); } - private fixPatternAnimationForChromeBelow128(): void { + private fixPatternAnimationForChrome(): void { try { const userAgent = window.navigator.userAgent; - if (+(/Chrome\/(\d+)/i.exec(userAgent)[1]) <= 127) { + if (+(/Chrome\/(\d+)/i.exec(userAgent)[1]) > 0) { if (this.svgShape.defs().findOne('pattern') && !this.svgShape.defs().findOne('pattern.empty-animation')) { this.svgShape.defs().add(SVG('')); this.svgShape.style() diff --git a/ui-ngx/src/app/modules/home/models/dashboard-component.models.ts b/ui-ngx/src/app/modules/home/models/dashboard-component.models.ts index 65c6c23004..b4132bf882 100644 --- a/ui-ngx/src/app/modules/home/models/dashboard-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/dashboard-component.models.ts @@ -42,6 +42,7 @@ import { enumerable } from '@shared/decorators/enumerable'; import { UtilsService } from '@core/services/utils.service'; import { TbPopoverComponent } from '@shared/components/popover.component'; import { ComponentStyle, iconStyle, textStyle } from '@shared/models/widget-settings.models'; +import { TbContextMenuEvent } from '@shared/models/jquery-event.models'; export interface WidgetsData { widgets: Array; @@ -56,11 +57,11 @@ export interface ContextMenuItem { } export interface DashboardContextMenuItem extends ContextMenuItem { - action: (contextMenuEvent: MouseEvent) => void; + action: (contextMenuEvent: TbContextMenuEvent) => void; } export interface WidgetContextMenuItem extends ContextMenuItem { - action: (contextMenuEvent: MouseEvent, widget: Widget) => void; + action: (contextMenuEvent: TbContextMenuEvent, widget: Widget) => void; } export interface DashboardCallbacks { @@ -94,7 +95,7 @@ export interface IDashboardComponent { highlightWidget(widgetId: string, delay?: number); selectWidget(widgetId: string, delay?: number); getSelectedWidget(): Widget; - getEventGridPosition(event: Event): WidgetPosition; + getEventGridPosition(event: TbContextMenuEvent | KeyboardEvent): WidgetPosition; notifyGridsterOptionsChanged(); pauseChangeNotifications(); resumeChangeNotifications(); diff --git a/ui-ngx/src/app/shared/models/jquery-event.models.ts b/ui-ngx/src/app/shared/models/jquery-event.models.ts index b893da758c..a054210672 100644 --- a/ui-ngx/src/app/shared/models/jquery-event.models.ts +++ b/ui-ngx/src/app/shared/models/jquery-event.models.ts @@ -19,6 +19,8 @@ import Timeout = NodeJS.Timeout; export interface TbContextMenuEvent extends Event { clientX: number; clientY: number; + pageX: number; + pageY: number; ctrlKey: boolean; metaKey: boolean; } @@ -41,6 +43,8 @@ export const initCustomJQueryEvents = () => { const event = $.Event('tbcontextmenu', { clientX: touch.clientX, clientY: touch.clientY, + pageX: touch.pageX, + pageY: touch.pageY, ctrlKey: false, metaKey: false, originalEvent: e @@ -59,6 +63,8 @@ export const initCustomJQueryEvents = () => { const event = $.Event('tbcontextmenu', { clientX: e.originalEvent.clientX, clientY: e.originalEvent.clientY, + pageX: e.originalEvent.pageX, + pageY: e.originalEvent.pageY, ctrlKey: e.originalEvent.ctrlKey, metaKey: e.originalEvent.metaKey, originalEvent: e diff --git a/ui-ngx/src/app/shared/models/widget.models.ts b/ui-ngx/src/app/shared/models/widget.models.ts index 429bb79e35..dc3a94052b 100644 --- a/ui-ngx/src/app/shared/models/widget.models.ts +++ b/ui-ngx/src/app/shared/models/widget.models.ts @@ -836,6 +836,8 @@ export interface WidgetPosition { export interface WidgetSize { sizeX: number; sizeY: number; + preserveAspectRatio: boolean; + resizable: boolean; } export interface IWidgetSettingsComponent { From 40c5f9d66d08c7d1ca5e2f4cdb26e9b2b6f198d3 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 18 Oct 2024 17:51:07 +0300 Subject: [PATCH 2/2] UI: Initialize widget component in angular zone. Force detect widget changes in angular zone. --- .../components/widget/widget.component.ts | 20 +++++++++++++------ .../home/models/widget-component.models.ts | 16 +++++++++++++-- 2 files changed, 28 insertions(+), 8 deletions(-) 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 b58e9fe85b..d72b896862 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 @@ -956,11 +956,15 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.widgetContext.hiddenData = subscription.hiddenData; this.widgetContext.timeWindow = subscription.timeWindow; this.widgetContext.defaultSubscription = subscription; - createSubscriptionSubject.next(); - createSubscriptionSubject.complete(); + this.ngZone.run(() => { + createSubscriptionSubject.next(); + createSubscriptionSubject.complete(); + }); }, (err) => { - createSubscriptionSubject.error(err); + this.ngZone.run(() => { + createSubscriptionSubject.error(err); + }); } ); } else if (this.widget.type === widgetType.rpc) { @@ -1013,11 +1017,15 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI this.createSubscription(options).subscribe( (subscription) => { this.widgetContext.defaultSubscription = subscription; - createSubscriptionSubject.next(); - createSubscriptionSubject.complete(); + this.ngZone.run(() => { + createSubscriptionSubject.next(); + createSubscriptionSubject.complete(); + }); }, (err) => { - createSubscriptionSubject.error(err); + this.ngZone.run(() => { + createSubscriptionSubject.error(err); + }); } ); this.detectChanges(); 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 673bc21edb..9e739cafb4 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 @@ -415,7 +415,13 @@ export class WidgetContext { this.dashboardWidget.updateWidgetParams(); } try { - this.changeDetectorValue.detectChanges(); + if (this.ngZone) { + this.ngZone.run(() => { + this.changeDetectorValue?.detectChanges(); + }); + } else { + this.changeDetectorValue?.detectChanges(); + } } catch (e) { // console.log(e); } @@ -425,7 +431,13 @@ export class WidgetContext { detectContainerChanges() { if (!this.destroyed) { try { - this.containerChangeDetectorValue.detectChanges(); + if (this.ngZone) { + this.ngZone.run(() => { + this.containerChangeDetectorValue?.detectChanges(); + }); + } else { + this.containerChangeDetectorValue?.detectChanges(); + } } catch (e) { // console.log(e); }