From 6da4b7f49805b6da937f1d63e545169bdf77680c Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 26 Jan 2026 16:53:48 +0200 Subject: [PATCH] Angular 20 migration --- ui-ngx/.browserslistrc | 17 +- ui-ngx/.postcssrc.json | 5 + ui-ngx/angular.json | 5 +- ui-ngx/package.json | 12 +- ui-ngx/patches/echarts+5.5.1-TB.patch | 15 + ...culated-field-arguments-table.component.ts | 4 +- .../dashboard-page.component.ts | 4 +- .../dashboard-page/dashboard-page.models.ts | 3 +- .../layout/dashboard-layout.component.ts | 3 +- .../dashboard/dashboard.component.ts | 3 +- .../notification-bell.component.ts | 4 +- .../vc/entity-versions-table.component.ts | 8 +- ...ries-chart-threshold-settings.component.ts | 4 +- .../time-series-chart-y-axis-row.component.ts | 4 +- .../common/date-format-select.component.ts | 8 +- .../dynamic-form-property-row.component.ts | 6 +- .../common/key/data-keys.component.ts | 2 +- .../map/map-data-layer-row.component.ts | 4 +- .../common/map/map-layer-row.component.ts | 4 +- .../map/map-tooltip-tag-actions.component.ts | 6 +- .../applications/mobile-app.component.ts | 4 +- .../layout/mobile-page-item-row.component.ts | 4 +- .../scada-symbol-behavior-row.component.ts | 6 +- .../components/fab-toolbar.component.ts | 9 +- .../shared/components/file-input.component.ts | 4 +- .../app/shared/components/icon.component.ts | 34 +- .../components/image-input.component.ts | 4 +- .../components/marked-options.service.ts | 42 +- .../multiple-image-input.component.ts | 6 +- .../components/time/datetime.component.ts | 3 +- ui-ngx/src/styles.scss | 4 +- ui-ngx/tsconfig.json | 2 +- ui-ngx/yarn.lock | 706 +++++++++--------- 33 files changed, 488 insertions(+), 461 deletions(-) create mode 100644 ui-ngx/.postcssrc.json create mode 100644 ui-ngx/patches/echarts+5.5.1-TB.patch diff --git a/ui-ngx/.browserslistrc b/ui-ngx/.browserslistrc index e368a649b3..af5c0c7df4 100644 --- a/ui-ngx/.browserslistrc +++ b/ui-ngx/.browserslistrc @@ -2,18 +2,17 @@ # For additional information regarding the format and rule options, please see: # https://github.com/browserslist/browserslist#queries -# For the full list of supported browsers by the Angular framework, please see: +# For Angular's browser support policy, please see: # https://angular.dev/reference/versions#browser-support # You can see what browsers were selected by your queries by running: # npx browserslist ->0.5% -not dead -last 2 Chrome versions -last 1 Firefox version -last 2 Edge major versions -last 2 Safari major versions -last 2 iOS major versions -last 2 Android major versions +Chrome >= 107 +ChromeAndroid >= 107 +Edge >= 107 +Firefox >= 104 +FirefoxAndroid >= 104 +Safari >= 16 +iOS >= 16 Firefox ESR diff --git a/ui-ngx/.postcssrc.json b/ui-ngx/.postcssrc.json new file mode 100644 index 0000000000..fddc8af8fe --- /dev/null +++ b/ui-ngx/.postcssrc.json @@ -0,0 +1,5 @@ +{ + "plugins": { + "@tailwindcss/postcss": {} + } +} diff --git a/ui-ngx/angular.json b/ui-ngx/angular.json index 54f44d90f4..6d90f9ec20 100644 --- a/ui-ngx/angular.json +++ b/ui-ngx/angular.json @@ -114,7 +114,10 @@ "stylePreprocessorOptions": { "includePaths": [ "src/scss" - ] + ], + "sass": { + "silenceDeprecations": ["mixed-decls", "color-functions", "global-builtin", "import"] + } }, "scripts": [ "node_modules/tinycolor2/dist/tinycolor-min.js", diff --git a/ui-ngx/package.json b/ui-ngx/package.json index cc2f3988c8..63d5103bd5 100644 --- a/ui-ngx/package.json +++ b/ui-ngx/package.json @@ -36,7 +36,7 @@ "@ngrx/store-devtools": "^20.1.0", "@ngx-translate/core": "^17.0.0", "@svgdotjs/svg.filter.js": "^3.0.9", - "@svgdotjs/svg.js": "^3.2.5", + "@svgdotjs/svg.js": "3.2.4", "@svgdotjs/svg.panzoom.js": "^2.1.2", "@tinymce/tinymce-angular": "^8.0.1", "ace-builds": "1.43.6", @@ -64,7 +64,7 @@ "leaflet.gridlayer.googlemutant": "0.15.0", "leaflet.markercluster": "1.5.3", "libphonenumber-js": "^1.12.35", - "maplibre-gl": "^5.16.0", + "maplibre-gl": "5.2.0", "marked": "~16.4.2", "moment": "^2.30.1", "moment-timezone": "^0.6.0", @@ -101,13 +101,14 @@ "@angular/cli": "20.3.15", "@angular/compiler-cli": "20.3.16", "@angular/language-service": "20.3.16", + "@tailwindcss/postcss": "^4.1.18", "@types/ace-diff": "^2.1.4", "@types/canvas-gauges": "^2.1.8", "@types/flot": "^0.0.36", "@types/flowjs": "^2.13.14", "@types/jquery": "^3.5.33", "@types/js-beautify": "^1.14.3", - "@types/leaflet": "1.9.20", + "@types/leaflet": "1.9.14", "@types/leaflet-polylinedecorator": "1.6.4", "@types/leaflet-providers": "1.2.4", "@types/leaflet.gridlayer.googlemutant": "0.4.9", @@ -130,13 +131,14 @@ "patch-package": "^8.0.1", "postcss": "^8.5.6", "postinstall-prepare": "^2.0.0", - "tailwindcss": "^3.4.15", + "tailwindcss": "^4.1.18", "ts-node": "^10.9.2", "typescript": "~5.9.3", "typescript-eslint": "^8.53.1" }, "resolutions": { "ace-builds": "1.43.6", - "tinymce": "6.8.6" + "tinymce": "6.8.6", + "@babel/core": "7.28.3" } } diff --git a/ui-ngx/patches/echarts+5.5.1-TB.patch b/ui-ngx/patches/echarts+5.5.1-TB.patch new file mode 100644 index 0000000000..0ca9ff80c0 --- /dev/null +++ b/ui-ngx/patches/echarts+5.5.1-TB.patch @@ -0,0 +1,15 @@ +diff --git a/node_modules/echarts/index.d.ts b/node_modules/echarts/index.d.ts +index 811908a..5f77c60 100644 +--- a/node_modules/echarts/index.d.ts ++++ b/node_modules/echarts/index.d.ts +@@ -17,7 +17,7 @@ + * under the License. + */ + +-import * as echarts from './types/dist/echarts'; ++// import * as echarts from './types/dist/echarts'; + // Export for UMD module. + export as namespace echarts; +-export = echarts; +\ No newline at end of file ++export * from './types/dist/echarts'; diff --git a/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.ts b/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.ts index 4b89028fb4..304d658399 100644 --- a/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/calculated-fields/components/arguments-table/calculated-field-arguments-table.component.ts @@ -44,7 +44,7 @@ import { CalculatedFieldType, } from '@shared/models/calculated-field.models'; import { CalculatedFieldArgumentPanelComponent } from '@home/components/calculated-fields/components/public-api'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { EntityId } from '@shared/models/id/entity-id'; @@ -154,7 +154,7 @@ export class CalculatedFieldArgumentsTableComponent implements ControlValueAcces this.argumentsFormArray.markAsDirty(); } - manageArgument($event: Event, matButton: MatButton, argument = {} as CalculatedFieldArgumentValue): void { + manageArgument($event: Event, matButton: MatIconButton, argument = {} as CalculatedFieldArgumentValue): void { $event?.stopPropagation(); if (this.popoverComponent && !this.popoverComponent.tbHidden) { this.popoverComponent.hide(); diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts index 8c1d73f3c6..c880f5eb95 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts @@ -146,7 +146,7 @@ import { SafeUrl } from '@angular/platform-browser'; import cssjs from '@core/css/css'; import { IAliasController } from '@core/api/widget-api.models'; -import { MatButton } from '@angular/material/button'; +import { MatButton, MatIconButton } from '@angular/material/button'; import { VersionControlComponent } from '@home/components/vc/version-control.component'; import { TbPopoverService } from '@shared/components/popover.service'; import { catchError, distinctUntilChanged, map, skip, tap } from 'rxjs/operators'; @@ -1754,7 +1754,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC }); } - toggleVersionControl($event: Event, versionControlButton: MatButton) { + toggleVersionControl($event: Event, versionControlButton: MatButton | MatIconButton) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts index cda6a3a7de..af45b01714 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.models.ts @@ -28,7 +28,6 @@ import { IAliasController, IStateController } from '@core/api/widget-api.models' import { ILayoutController } from './layout/layout.models'; import { DashboardContextMenuItem, WidgetContextMenuItem } from '@home/models/dashboard-component.models'; import { BehaviorSubject, Observable } from 'rxjs'; -import { displayGrids } from 'angular-gridster2/lib/gridsterConfig.interface'; import { ElementRef } from '@angular/core'; export declare type DashboardPageScope = 'tenant' | 'customer'; @@ -87,7 +86,7 @@ export interface DashboardPageLayoutContext { ctrl: ILayoutController; dashboardCtrl: IDashboardController; ignoreLoading: boolean; - displayGrid: displayGrids; + displayGrid: 'always' | 'onDrag&Resize' | 'none'; } export interface DashboardPageLayout { 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 1699fe6c54..acb772a063 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 @@ -36,7 +36,6 @@ import { TbCheatSheetComponent } from '@shared/components/cheatsheet.component'; import { TbPopoverComponent } from '@shared/components/popover.component'; import { ImagePipe } from '@shared/pipe/image.pipe'; 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'; @@ -115,7 +114,7 @@ export class DashboardLayoutComponent extends PageComponent implements ILayoutCo return this.layoutCtx.gridSettings.minColumns || this.layoutCtx.gridSettings.columns || 24; } - get displayGrid(): displayGrids { + get displayGrid(): 'always' | 'onDrag&Resize' | 'none' { return this.layoutCtx.displayGrid || 'onDrag&Resize'; } 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 a7df545332..791aac883a 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 @@ -58,7 +58,6 @@ import { distinct, take } from 'rxjs/operators'; import { UtilsService } from '@core/services/utils.service'; import { WidgetComponentAction, WidgetComponentActionType } from '@home/components/widget/widget-container.component'; import { TbPopoverComponent } from '@shared/components/popover.component'; -import { displayGrids } from 'angular-gridster2/lib/gridsterConfig.interface'; import { coerceBoolean } from '@shared/decorators/coercion'; import { TbContextMenuEvent } from '@shared/models/jquery-event.models'; @@ -102,7 +101,7 @@ export class DashboardComponent extends PageComponent implements IDashboardCompo outerMargin: boolean; @Input() - displayGrid: displayGrids = 'onDrag&Resize'; + displayGrid: 'always' | 'onDrag&Resize' | 'none' = 'onDrag&Resize'; @Input() gridType: GridType; diff --git a/ui-ngx/src/app/modules/home/components/notification/notification-bell.component.ts b/ui-ngx/src/app/modules/home/components/notification/notification-bell.component.ts index 40df0ed280..0ab521230e 100644 --- a/ui-ngx/src/app/modules/home/components/notification/notification-bell.component.ts +++ b/ui-ngx/src/app/modules/home/components/notification/notification-bell.component.ts @@ -26,7 +26,7 @@ import { import { NotificationWebsocketService } from '@core/ws/notification-websocket.service'; import { BehaviorSubject, ReplaySubject, Subscription } from 'rxjs'; import { distinctUntilChanged, map, share, skip, tap } from 'rxjs/operators'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { ShowNotificationPopoverComponent } from '@home/components/notification/show-notification-popover.component'; import { NotificationSubscriber } from '@shared/models/telemetry/telemetry.models'; @@ -74,7 +74,7 @@ export class NotificationBellComponent implements OnDestroy { this.unsubscribeSubscription(); } - showNotification($event: Event, createVersionButton: MatButton) { + showNotification($event: Event, createVersionButton: MatIconButton) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts index c50b7d6c36..f93cde1fb6 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts @@ -47,7 +47,7 @@ import { BranchAutocompleteComponent } from '@shared/components/vc/branch-autoco import { isNotEmptyStr } from '@core/utils'; import { TbPopoverService } from '@shared/components/popover.service'; import { EntityVersionCreateComponent } from '@home/components/vc/entity-version-create.component'; -import { MatButton } from '@angular/material/button'; +import { MatButton, MatIconButton } from '@angular/material/button'; import { EntityVersionRestoreComponent } from '@home/components/vc/entity-version-restore.component'; import { EntityVersionDiffComponent } from '@home/components/vc/entity-version-diff.component'; import { ComplexVersionCreateComponent } from '@home/components/vc/complex-version-create.component'; @@ -278,7 +278,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } } - toggleShowVersionDiff($event: Event, diffVersionButton: MatButton, entityVersion: EntityVersion) { + toggleShowVersionDiff($event: Event, diffVersionButton: MatIconButton, entityVersion: EntityVersion) { if ($event) { $event.stopPropagation(); } @@ -308,7 +308,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } } - toggleRestoreEntityVersion($event: Event, restoreVersionButton: MatButton, entityVersion: EntityVersion) { + toggleRestoreEntityVersion($event: Event, restoreVersionButton: MatIconButton, entityVersion: EntityVersion) { if ($event) { $event.stopPropagation(); } @@ -342,7 +342,7 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } } - toggleRestoreEntitiesVersion($event: Event, restoreEntitiesVersionButton: MatButton, entityVersion: EntityVersion) { + toggleRestoreEntitiesVersion($event: Event, restoreEntitiesVersionButton: MatIconButton, entityVersion: EntityVersion) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-threshold-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-threshold-settings.component.ts index 3195c3a944..1df07ffceb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-threshold-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-threshold-settings.component.ts @@ -16,7 +16,7 @@ import { Component, forwardRef, Input, OnInit, Renderer2, ViewContainerRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { deepClone } from '@core/utils'; import { coerceBoolean } from '@shared/decorators/coercion'; @@ -93,7 +93,7 @@ export class TimeSeriesChartThresholdSettingsComponent implements OnInit, Contro this.modelValue = value; } - openThresholdSettingsPopup($event: Event, matButton: MatButton) { + openThresholdSettingsPopup($event: Event, matButton: MatIconButton) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-row.component.ts index 67ec499ab1..42602d902f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-row.component.ts @@ -33,7 +33,7 @@ import { timeSeriesAxisPositionTranslations, TimeSeriesChartYAxisSettings } from '@home/components/widget/lib/chart/time-series-chart.models'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { coerceBoolean } from '@shared/decorators/coercion'; import { @@ -148,7 +148,7 @@ export class TimeSeriesChartYAxisRowComponent implements ControlValueAccessor, O this.cd.markForCheck(); } - editAxis($event: Event, matButton: MatButton) { + editAxis($event: Event, matButton: MatIconButton) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/date-format-select.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/date-format-select.component.ts index 746cc6c90b..a710fd27d3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/date-format-select.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/date-format-select.component.ts @@ -35,7 +35,7 @@ import { } from '@shared/models/widget-settings.models'; import { TranslateService } from '@ngx-translate/core'; import { DatePipe } from '@angular/common'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { deepClone, mergeDeep } from '@core/utils'; import { @@ -63,7 +63,7 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; export class DateFormatSelectComponent implements OnInit, ControlValueAccessor { @ViewChild('customFormatButton', {static: false}) - customFormatButton: MatButton; + customFormatButton: MatIconButton; @Input() disabled: boolean; @@ -155,7 +155,7 @@ export class DateFormatSelectComponent implements OnInit, ControlValueAccessor { } } - openDateFormatSettingsPopup($event: Event, matButton: MatButton) { + openDateFormatSettingsPopup($event: Event, matButton: MatIconButton) { if ($event) { $event.stopPropagation(); } @@ -182,7 +182,7 @@ export class DateFormatSelectComponent implements OnInit, ControlValueAccessor { } } - openAutoFormatSettingsPopup($event: Event, matButton: MatButton) { + openAutoFormatSettingsPopup($event: Event, matButton: MatIconButton) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/dynamic-form/dynamic-form-property-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/dynamic-form/dynamic-form-property-row.component.ts index 4f1dd8b23d..fd67997e63 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/dynamic-form/dynamic-form-property-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/dynamic-form/dynamic-form-property-row.component.ts @@ -41,7 +41,7 @@ import { Validators } from '@angular/forms'; import { deepClone } from '@core/utils'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { defaultPropertyValue, @@ -83,7 +83,7 @@ export class DynamicFormPropertyRowComponent implements ControlValueAccessor, On idInput: ElementRef; @ViewChild('editButton') - editButton: MatButton; + editButton: MatIconButton; formPropertyTypes = formPropertyTypes; formPropertyTypeTranslations = formPropertyTypeTranslations; @@ -161,7 +161,7 @@ export class DynamicFormPropertyRowComponent implements ControlValueAccessor, On this.cd.markForCheck(); } - editProperty($event: Event, matButton: MatButton, add = false, editCanceled = () => {}) { + editProperty($event: Event, matButton: MatIconButton, add = false, editCanceled = () => {}) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/key/data-keys.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/key/data-keys.component.ts index 02aa5b7548..525abd50a7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/key/data-keys.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/key/data-keys.component.ts @@ -64,7 +64,7 @@ import { import { deepClone, guid, isDefinedAndNotNull, isObject, isUndefined } from '@core/utils'; import { Dashboard } from '@shared/models/dashboard.models'; import { AggregationType } from '@shared/models/time/time.models'; -import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive'; +import { DndDropEvent } from 'ngx-drag-drop'; import { moveItemInArray } from '@angular/cdk/drag-drop'; import { coerceBoolean } from '@shared/decorators/coercion'; import { ColorPickerPanelComponent } from '@shared/components/color-picker/color-picker-panel.component'; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-row.component.ts index 707d8f983f..ba7bf53a21 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-data-layer-row.component.ts @@ -32,7 +32,7 @@ import { UntypedFormGroup, Validators } from '@angular/forms'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { CirclesDataLayerSettings, @@ -244,7 +244,7 @@ export class MapDataLayerRowComponent implements ControlValueAccessor, OnInit { ); } - editDataLayer($event: Event, matButton: MatButton) { + editDataLayer($event: Event, matButton: MatIconButton) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts index 1604ff8683..2fdd892fa9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-layer-row.component.ts @@ -34,7 +34,7 @@ import { UntypedFormGroup, Validators } from '@angular/forms'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { TranslateService } from '@ngx-translate/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -173,7 +173,7 @@ export class MapLayerRowComponent implements ControlValueAccessor, OnInit { return this.translate.instant(translationKey); } - editLayer($event: Event, matButton: MatButton) { + editLayer($event: Event, matButton: MatIconButton) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-tooltip-tag-actions.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-tooltip-tag-actions.component.ts index 8c9864c456..9d2983de90 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-tooltip-tag-actions.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/map/map-tooltip-tag-actions.component.ts @@ -32,7 +32,7 @@ import { MapSettingsContext } from '@home/components/widget/lib/settings/common/ import { WidgetActionSettingsPanelComponent } from '@home/components/widget/lib/settings/common/action/widget-action-settings-panel.component'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TranslateService } from '@ngx-translate/core'; import { deepClone } from '@core/utils'; @@ -109,7 +109,7 @@ export class MapTooltipTagActionsComponent implements ControlValueAccessor, OnIn } } - addAction($event: Event, matButton: MatButton): void { + addAction($event: Event, matButton: MatIconButton): void { if ($event) { $event.stopPropagation(); } @@ -128,7 +128,7 @@ export class MapTooltipTagActionsComponent implements ControlValueAccessor, OnIn }); } - editAction($event: Event, matButton: MatButton, index: number): void { + editAction($event: Event, matButton: MatIconButton, index: number): void { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts index d2c1fe3dc9..3f114c7707 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/applications/mobile-app.component.ts @@ -26,7 +26,7 @@ import { EntityType } from '@shared/models/entity-type.models'; import { MobileApp, MobileAppStatus, mobileAppStatusTranslations } from '@shared/models/mobile-app.models'; import { PlatformType, platformTypeTranslations } from '@shared/models/oauth2.models'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { EditorPanelComponent } from '@home/pages/mobile/common/editor-panel.component'; @@ -153,7 +153,7 @@ export class MobileAppComponent extends EntityComponent { this.entityForm.get('appSecret').markAsDirty(); } - editReleaseNote($event: Event, matButton: MatButton, isLatest: boolean) { + editReleaseNote($event: Event, matButton: MatIconButton, isLatest: boolean) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/pages/mobile/bundes/layout/mobile-page-item-row.component.ts b/ui-ngx/src/app/modules/home/pages/mobile/bundes/layout/mobile-page-item-row.component.ts index 8772b6ad71..c9c1bee48b 100644 --- a/ui-ngx/src/app/modules/home/pages/mobile/bundes/layout/mobile-page-item-row.component.ts +++ b/ui-ngx/src/app/modules/home/pages/mobile/bundes/layout/mobile-page-item-row.component.ts @@ -49,7 +49,7 @@ import { mobilePageTypeTranslations } from '@shared/models/mobile-app.models'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { deepClone } from '@core/utils'; import { TbPopoverService } from '@shared/components/popover.service'; import { CustomMobilePagePanelComponent } from '@home/pages/mobile/bundes/layout/custom-mobile-page-panel.component'; @@ -216,7 +216,7 @@ export class MobilePageItemRowComponent implements ControlValueAccessor, OnInit, this.pageRemoved.emit(); } - edit($event: Event, matButton: MatButton) { + edit($event: Event, matButton: MatIconButton) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-row.component.ts b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-row.component.ts index 18b3d3bf4c..a7116b8e8a 100644 --- a/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-row.component.ts +++ b/ui-ngx/src/app/modules/home/pages/scada-symbol/metadata-components/scada-symbol-behavior-row.component.ts @@ -47,7 +47,7 @@ import { scadaSymbolBehaviorTypeTranslations, updateBehaviorDefaultSettings } from '@home/components/widget/lib/scada/scada-symbol.models'; import { deepClone, isUndefinedOrNull } from '@core/utils'; -import { MatButton } from '@angular/material/button'; +import { MatIconButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { ScadaSymbolBehaviorPanelComponent @@ -115,7 +115,7 @@ export class ScadaSymbolBehaviorRowComponent implements ControlValueAccessor, On idInput: ElementRef; @ViewChild('editButton') - editButton: MatButton; + editButton: MatIconButton; scadaSymbolBehaviorTypes = scadaSymbolBehaviorTypes; scadaSymbolBehaviorTypeTranslations = scadaSymbolBehaviorTypeTranslations; @@ -196,7 +196,7 @@ export class ScadaSymbolBehaviorRowComponent implements ControlValueAccessor, On this.cd.markForCheck(); } - editBehavior($event: Event, matButton: MatButton, add = false, editCanceled = () => {}) { + editBehavior($event: Event, matButton: MatIconButton, add = false, editCanceled = () => {}) { if ($event) { $event.stopPropagation(); } diff --git a/ui-ngx/src/app/shared/components/fab-toolbar.component.ts b/ui-ngx/src/app/shared/components/fab-toolbar.component.ts index 1035dde5b2..e3b9cc66d4 100644 --- a/ui-ngx/src/app/shared/components/fab-toolbar.component.ts +++ b/ui-ngx/src/app/shared/components/fab-toolbar.component.ts @@ -28,15 +28,15 @@ import { ViewEncapsulation } from '@angular/core'; import { WINDOW } from '@core/services/window.service'; -import { _Constructor, CanColor, mixinColor, ThemePalette } from '@angular/material/core'; +import { ThemePalette } from '@angular/material/core'; export declare type FabToolbarDirection = 'left' | 'right'; class MatFabToolbarBase { + // eslint-disable-next-line @typescript-eslint/naming-convention, no-underscore-dangle, id-blacklist, id-match constructor(public _elementRef: ElementRef) {} } -const MatFabToolbarMixinBase: _Constructor & typeof MatFabToolbarBase = mixinColor(MatFabToolbarBase); @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector @@ -77,7 +77,7 @@ export class FabActionsDirective implements OnInit { encapsulation: ViewEncapsulation.None, standalone: false }) -export class FabToolbarComponent extends MatFabToolbarMixinBase implements OnInit, OnDestroy, AfterViewInit, OnChanges { +export class FabToolbarComponent extends MatFabToolbarBase implements OnInit, OnDestroy, AfterViewInit, OnChanges { private fabToolbarResize$: ResizeObserver; @@ -90,6 +90,9 @@ export class FabToolbarComponent extends MatFabToolbarMixinBase implements OnIni @Input() color: ThemePalette; + @Input() + defaultColor: ThemePalette | undefined; + constructor(private el: ElementRef, @Inject(WINDOW) private window: Window) { super(el); diff --git a/ui-ngx/src/app/shared/components/file-input.component.ts b/ui-ngx/src/app/shared/components/file-input.component.ts index 56f7a302bc..69945170da 100644 --- a/ui-ngx/src/app/shared/components/file-input.component.ts +++ b/ui-ngx/src/app/shared/components/file-input.component.ts @@ -32,7 +32,7 @@ import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { Subscription } from 'rxjs'; -import { FlowDirective } from '@flowjs/ngx-flow'; +import { FlowConfig } from '@flowjs/ngx-flow'; import { TranslateService } from '@ngx-translate/core'; import { UtilsService } from '@core/services/utils.service'; import { DialogService } from '@core/services/dialog.service'; @@ -140,7 +140,7 @@ export class FileInputComponent extends PageComponent implements AfterViewInit, mediaType: string; @ViewChild('flow', {static: true}) - flow: FlowDirective; + flow: FlowConfig; @ViewChild('flowInput', {static: true}) flowInput: ElementRef; diff --git a/ui-ngx/src/app/shared/components/icon.component.ts b/ui-ngx/src/app/shared/components/icon.component.ts index d5e65dbe8f..625810f695 100644 --- a/ui-ngx/src/app/shared/components/icon.component.ts +++ b/ui-ngx/src/app/shared/components/icon.component.ts @@ -14,15 +14,15 @@ /// limitations under the License. /// -import { CanColor, mixinColor } from '@angular/material/core'; +import { ThemePalette } from '@angular/material/core'; import { AfterContentInit, AfterViewChecked, ChangeDetectionStrategy, Component, ElementRef, - ErrorHandler, - Inject, + ErrorHandler, inject, + Inject, Input, OnDestroy, Renderer2, ViewChild, @@ -34,12 +34,6 @@ import { take } from 'rxjs/operators'; import { isSvgIcon, splitIconName } from '@shared/models/icon.models'; import { ContentObserver } from '@angular/cdk/observers'; -const _TbIconBase = mixinColor( - class { - constructor(public _elementRef: ElementRef) {} - }, -); - const funcIriAttributes = [ 'clip-path', 'color-profile', @@ -64,8 +58,6 @@ const funcIriPattern = /^url\(['"]?#(.*?)['"]?\)$/; selector: 'tb-icon', exportAs: 'tbIcon', styleUrls: [], - // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['color'], // eslint-disable-next-line @angular-eslint/no-host-metadata-property host: { role: 'img', @@ -79,12 +71,24 @@ const funcIriPattern = /^url\(['"]?#(.*?)['"]?\)$/; changeDetection: ChangeDetectionStrategy.OnPush, standalone: false }) -export class TbIconComponent extends _TbIconBase - implements AfterContentInit, AfterViewChecked, CanColor, OnDestroy { +export class TbIconComponent implements AfterContentInit, AfterViewChecked, OnDestroy { @ViewChild('iconNameContent', {static: true}) _iconNameContent: ElementRef; + readonly _elementRef = inject>(ElementRef); + + private _defaultColor: ThemePalette; + + @Input() + get color() { + return this._color || this._defaultColor; + } + set color(value: string | null | undefined) { + this._color = value; + } + private _color: string | null | undefined; + private icon: string; get viewValue(): string { @@ -106,13 +110,11 @@ export class TbIconComponent extends _TbIconBase private _currentIconFetch = Subscription.EMPTY; - constructor(elementRef: ElementRef, - private contentObserver: ContentObserver, + constructor(private contentObserver: ContentObserver, private renderer: Renderer2, private _iconRegistry: MatIconRegistry, @Inject(MAT_ICON_LOCATION) private _location: MatIconLocation, private readonly _errorHandler: ErrorHandler) { - super(elementRef); } ngAfterContentInit(): void { diff --git a/ui-ngx/src/app/shared/components/image-input.component.ts b/ui-ngx/src/app/shared/components/image-input.component.ts index 8962259431..c41e622787 100644 --- a/ui-ngx/src/app/shared/components/image-input.component.ts +++ b/ui-ngx/src/app/shared/components/image-input.component.ts @@ -30,7 +30,7 @@ import { AppState } from '@core/core.state'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, } from '@angular/forms'; import { Subscription } from 'rxjs'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; -import { FlowDirective } from '@flowjs/ngx-flow'; +import { FlowConfig } from '@flowjs/ngx-flow'; import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import { UtilsService } from '@core/services/utils.service'; import { DialogService } from '@core/services/dialog.service'; @@ -116,7 +116,7 @@ export class ImageInputComponent extends PageComponent implements AfterViewInit, safeImageUrl: SafeUrl; @ViewChild('flow', {static: true}) - flow: FlowDirective; + flow: FlowConfig; autoUploadSubscription: Subscription; diff --git a/ui-ngx/src/app/shared/components/marked-options.service.ts b/ui-ngx/src/app/shared/components/marked-options.service.ts index 6577b83ecb..27bb0fb574 100644 --- a/ui-ngx/src/app/shared/components/marked-options.service.ts +++ b/ui-ngx/src/app/shared/components/marked-options.service.ts @@ -70,47 +70,47 @@ export class MarkedOptionsService implements MarkedOptions { } }; marked.use({tokenizer}); - this.renderer.code = (code: string, language: string | undefined, isEscaped: boolean) => { - const codeContext = processCode(code); + this.renderer.code = (code: Tokens.Code) => { + const codeContext = processCode(code.text); + code.text = codeContext.code; if (codeContext.copyCode) { - const content = postProcessCodeContent(this.renderer2.code(codeContext.code, language, isEscaped), codeContext); + const content = postProcessCodeContent(this.renderer2.code(code), codeContext); this.id++; return this.wrapCopyCode(this.id, content, codeContext); } else { - return this.wrapDiv(postProcessCodeContent(this.renderer2.code(codeContext.code, language, isEscaped), codeContext)); + return this.wrapDiv(postProcessCodeContent(this.renderer2.code(code), codeContext)); } }; - this.renderer.table = (header: string, body: string) => { + this.renderer.table = (token: Tokens.Table) => { let autoLayout = false; - if (header.includes(autoBlock)) { - autoLayout = true; - header = header.replace(autoBlock, ''); + for (const h of token.header) { + if (h.text.includes(autoBlock)) { + autoLayout = true; + h.text = h.text.replace(autoBlock, ''); + } } - let table = this.renderer2.table(header, body); + let table = this.renderer2.table(token); if (autoLayout) { table = table.replace(' { - const codeContext = processCode(content); + this.renderer.tablecell = (token: Tokens.TableCell) => { + const codeContext = processCode(token.text); codeContext.multiline = false; if (codeContext.copyCode) { this.id++; - content = this.wrapCopyCode(this.id, codeContext.code, codeContext); + token.text = this.wrapCopyCode(this.id, codeContext.code, codeContext); } - return this.renderer2.tablecell(content, flags); + return this.renderer2.tablecell(token); }; - this.renderer.link = (href: string | null, title: string | null, text: string) => { - if (text.endsWith(targetBlankBlock)) { - text = text.substring(0, text.length - targetBlankBlock.length); - const content = this.renderer2.link(href, title, text); + this.renderer.link = (token: Tokens.Link) => { + if (token.text.endsWith(targetBlankBlock)) { + token.text = token.text.substring(0, token.text.length - targetBlankBlock.length); + const content = this.renderer2.link(token); return content.replace('= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - thingies@^1.20.0: version "1.21.0" resolved "https://registry.yarnpkg.com/thingies/-/thingies-1.21.0.tgz#e80fbe58fd6fdaaab8fad9b67bd0a5c943c445c1" @@ -10698,7 +10691,7 @@ tinyglobby@0.2.14: fdir "^6.4.4" picomatch "^4.0.2" -tinyglobby@^0.2.11, tinyglobby@^0.2.12, tinyglobby@^0.2.15: +tinyglobby@^0.2.12, tinyglobby@^0.2.15: version "0.2.15" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== @@ -10776,11 +10769,6 @@ ts-dedent@^2.2.0: resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== -ts-interface-checker@^0.1.9: - version "0.1.13" - resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" - integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== - ts-node@^10.0.0, ts-node@^10.9.2: version "10.9.2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" @@ -11145,6 +11133,15 @@ vscode-uri@~3.0.8: resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f" integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== +vt-pbf@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac" + integrity sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA== + dependencies: + "@mapbox/point-geometry" "0.1.0" + "@mapbox/vector-tile" "^1.3.1" + pbf "^3.2.1" + watchpack@2.4.4: version "2.4.4" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947" @@ -11348,6 +11345,13 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +which@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/which/-/which-4.0.0.tgz#cd60b5e74503a3fbcfbf6cd6b4138a8bae644c1a" + integrity sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg== + dependencies: + isexe "^3.1.1" + which@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/which/-/which-6.0.0.tgz#a3a721a14cdd9b991a722e493c177eeff82ff32a"