Merge branch 'master' into lwm2m_write_obj_19
This commit is contained in:
		
						commit
						4cb83e8f6e
					
				@ -56,13 +56,13 @@ sudo yum update
 | 
			
		||||
sudo yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
 | 
			
		||||
# Install packages
 | 
			
		||||
sudo yum -y install epel-release yum-utils
 | 
			
		||||
sudo yum-config-manager --enable pgdg15
 | 
			
		||||
sudo yum install postgresql15-server postgresql15
 | 
			
		||||
sudo yum-config-manager --enable pgdg16
 | 
			
		||||
sudo yum install postgresql16-server postgresql16 postgresql16-contrib
 | 
			
		||||
# Initialize your PostgreSQL DB
 | 
			
		||||
sudo /usr/pgsql-15/bin/postgresql-15-setup initdb
 | 
			
		||||
sudo systemctl start postgresql-15
 | 
			
		||||
sudo /usr/pgsql-16/bin/postgresql-16-setup initdb
 | 
			
		||||
sudo systemctl start postgresql-16
 | 
			
		||||
# Optional: Configure PostgreSQL to start on boot
 | 
			
		||||
sudo systemctl enable --now postgresql-15
 | 
			
		||||
sudo systemctl enable --now postgresql-16
 | 
			
		||||
 | 
			
		||||
{:copy-code}
 | 
			
		||||
```
 | 
			
		||||
@ -74,12 +74,12 @@ sudo systemctl enable --now postgresql-15
 | 
			
		||||
sudo yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
 | 
			
		||||
# Install packages
 | 
			
		||||
sudo dnf -qy module disable postgresql
 | 
			
		||||
sudo dnf -y install postgresql15 postgresql15-server
 | 
			
		||||
sudo dnf -y install postgresql16 postgresql16-server postgresql16-contrib
 | 
			
		||||
# Initialize your PostgreSQL DB
 | 
			
		||||
sudo /usr/pgsql-15/bin/postgresql-15-setup initdb
 | 
			
		||||
sudo systemctl start postgresql-15
 | 
			
		||||
sudo /usr/pgsql-16/bin/postgresql-16-setup initdb
 | 
			
		||||
sudo systemctl start postgresql-16
 | 
			
		||||
# Optional: Configure PostgreSQL to start on boot
 | 
			
		||||
sudo systemctl enable --now postgresql-15
 | 
			
		||||
sudo systemctl enable --now postgresql-16
 | 
			
		||||
 | 
			
		||||
{:copy-code}
 | 
			
		||||
```
 | 
			
		||||
@ -101,7 +101,7 @@ After configuring the password, edit the pg_hba.conf to use MD5 authentication w
 | 
			
		||||
Edit pg_hba.conf file:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo nano /var/lib/pgsql/15/data/pg_hba.conf
 | 
			
		||||
sudo nano /var/lib/pgsql/16/data/pg_hba.conf
 | 
			
		||||
{:copy-code}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -121,7 +121,7 @@ host    all             all             127.0.0.1/32            md5
 | 
			
		||||
Finally, you should restart the PostgreSQL service to initialize the new configuration:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo systemctl restart postgresql-15.service
 | 
			
		||||
sudo systemctl restart postgresql-16.service
 | 
			
		||||
{:copy-code}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ services:
 | 
			
		||||
    ${EXTRA_HOSTS}
 | 
			
		||||
  postgres:
 | 
			
		||||
    restart: always
 | 
			
		||||
    image: "postgres:15"
 | 
			
		||||
    image: "postgres:16"
 | 
			
		||||
    ports:
 | 
			
		||||
      - "5432"
 | 
			
		||||
    environment:
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ echo "deb http://apt.postgresql.org/pub/repos/apt/ ${RELEASE}"-pgdg main | sudo
 | 
			
		||||
 | 
			
		||||
# install and launch the postgresql service:
 | 
			
		||||
sudo apt update
 | 
			
		||||
sudo apt -y install postgresql-15
 | 
			
		||||
sudo apt -y install postgresql-16
 | 
			
		||||
sudo service postgresql start
 | 
			
		||||
{:copy-code}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ services:
 | 
			
		||||
    entrypoint: upgrade-tb-edge.sh
 | 
			
		||||
  postgres:
 | 
			
		||||
    restart: always
 | 
			
		||||
    image: "postgres:15"
 | 
			
		||||
    image: "postgres:16"
 | 
			
		||||
    ports:
 | 
			
		||||
      - "5432"
 | 
			
		||||
    environment:
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ version: '3.0'
 | 
			
		||||
services:
 | 
			
		||||
  postgres:
 | 
			
		||||
    restart: always
 | 
			
		||||
    image: "postgres:15"
 | 
			
		||||
    image: "postgres:16"
 | 
			
		||||
    ports:
 | 
			
		||||
      - "5432"
 | 
			
		||||
    environment:
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ version: '3.0'
 | 
			
		||||
services:
 | 
			
		||||
  postgres:
 | 
			
		||||
    restart: always
 | 
			
		||||
    image: "postgres:15"
 | 
			
		||||
    image: "postgres:16"
 | 
			
		||||
    ports:
 | 
			
		||||
    - "5432"
 | 
			
		||||
    environment:
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
FROM thingsboard/openjdk17:bookworm-slim
 | 
			
		||||
 | 
			
		||||
ENV PG_MAJOR=15
 | 
			
		||||
ENV PG_MAJOR=16
 | 
			
		||||
 | 
			
		||||
ENV DATA_FOLDER=/data
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -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 {
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -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('<pattern class="empty-animation"></pattern>'));
 | 
			
		||||
          this.svgShape.style()
 | 
			
		||||
 | 
			
		||||
@ -959,11 +959,15 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges,
 | 
			
		||||
          this.widgetContext.hiddenData = subscription.hiddenData;
 | 
			
		||||
          this.widgetContext.timeWindow = subscription.timeWindow;
 | 
			
		||||
          this.widgetContext.defaultSubscription = subscription;
 | 
			
		||||
          this.ngZone.run(() => {
 | 
			
		||||
            createSubscriptionSubject.next();
 | 
			
		||||
            createSubscriptionSubject.complete();
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
        (err) => {
 | 
			
		||||
          this.ngZone.run(() => {
 | 
			
		||||
            createSubscriptionSubject.error(err);
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
    } else if (this.widget.type === widgetType.rpc) {
 | 
			
		||||
@ -1016,11 +1020,15 @@ export class WidgetComponent extends PageComponent implements OnInit, OnChanges,
 | 
			
		||||
      this.createSubscription(options).subscribe(
 | 
			
		||||
        (subscription) => {
 | 
			
		||||
          this.widgetContext.defaultSubscription = subscription;
 | 
			
		||||
          this.ngZone.run(() => {
 | 
			
		||||
            createSubscriptionSubject.next();
 | 
			
		||||
            createSubscriptionSubject.complete();
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
        (err) => {
 | 
			
		||||
          this.ngZone.run(() => {
 | 
			
		||||
            createSubscriptionSubject.error(err);
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      );
 | 
			
		||||
      this.detectChanges();
 | 
			
		||||
 | 
			
		||||
@ -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<Widget>;
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -836,6 +836,8 @@ export interface WidgetPosition {
 | 
			
		||||
export interface WidgetSize {
 | 
			
		||||
  sizeX: number;
 | 
			
		||||
  sizeY: number;
 | 
			
		||||
  preserveAspectRatio: boolean;
 | 
			
		||||
  resizable: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IWidgetSettingsComponent {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user