Browse Source

Review fixes

pull/16046/head
Maksym Tsymbarov 2 weeks ago
parent
commit
19c433edd5
  1. 9
      ui-ngx/package.json
  2. 2
      ui-ngx/src/app/modules/home/pages/mobile/common/editor-panel.component.html
  3. 50
      ui-ngx/src/app/modules/home/pages/mobile/common/editor-panel.component.ts
  4. 2
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html
  5. 12
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts
  6. 2
      ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.html
  7. 44
      ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.ts
  8. 34
      ui-ngx/src/app/shared/models/hugerte/hugerte.models.ts
  9. 3
      ui-ngx/src/app/shared/shared.module.ts
  10. 25
      ui-ngx/src/styles.scss
  11. 6
      ui-ngx/yarn.lock

9
ui-ngx/package.json

@ -9,7 +9,7 @@
"build:types": "node generate-types.js",
"build:icon-metadata": "node generate-icon-metadata.js",
"lint": "ng lint",
"prepare": "patch-package"
"prepare": "patch-package --error-on-fail"
},
"private": true,
"dependencies": {
@ -27,6 +27,7 @@
"@flowjs/flow.js": "^2.14.1",
"@flowjs/ngx-flow": "20.0.2",
"@geoman-io/leaflet-geoman-free": "2.19.3",
"@hugerte/hugerte-angular": "~1.1.1",
"@iplab/ngx-color-picker": "^20.0.0",
"@mat-datetimepicker/core": "~16.0.1",
"@mdi/svg": "^7.4.47",
@ -37,7 +38,6 @@
"@ngx-translate/core": "^17.0.0",
"@svgdotjs/svg.filter.js": "^3.0.9",
"@svgdotjs/svg.js": "3.2.4",
"@hugerte/hugerte-angular": "^1.1.1",
"@svgdotjs/svg.panzoom.js": "^2.1.2",
"ace-builds": "1.43.6",
"ace-diff": "^3.3.0",
@ -51,7 +51,7 @@
"flot.curvedlines": "https://github.com/MichaelZinsmaier/CurvedLines.git#master",
"font-awesome": "^4.7.0",
"html2canvas": "^1.4.1",
"hugerte": "^1.0.12",
"hugerte": "~1.0.12",
"jquery": "^3.7.1",
"jquery.terminal": "^2.45.2",
"js-beautify": "1.15.4",
@ -139,7 +139,8 @@
"resolutions": {
"@babel/core": "7.29.7",
"esbuild": "0.28.1",
"less": "4.9.0",
"rollup": "4.59.0",
"less": ">=4.9.0",
"js-beautify/**/minimatch": "^9.0.7"
}
}

2
ui-ngx/src/app/modules/home/pages/mobile/common/editor-panel.component.html

@ -17,7 +17,7 @@
-->
<div class="tb-editor-panel">
<div class="tb-editor-title">{{ title | translate }}</div>
<editor class="tb-editor" [init]="tinyMceOptions" [formControl]="editorControl"></editor>
<editor class="tb-editor" [init]="hugeRteOptions" [formControl]="editorControl"></editor>
<div class="tb-editor-buttons">
<button mat-button
color="primary"

50
ui-ngx/src/app/modules/home/pages/mobile/common/editor-panel.component.ts

@ -18,6 +18,7 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } fro
import { FormBuilder, FormControl } from '@angular/forms';
import { TbPopoverComponent } from '@shared/components/popover.component';
import { EditorOptions } from 'hugerte';
import { defaultHugeRteOptions } from '@shared/models/hugerte/hugerte.models';
@Component({
selector: 'tb-release-notes-panel',
@ -45,52 +46,15 @@ export class EditorPanelComponent implements OnInit {
editorControl: FormControl<string>;
tinyMceOptions: Partial<EditorOptions> = {
base_url: '/assets/hugerte',
suffix: '.min',
hugeRteOptions: Partial<EditorOptions> = defaultHugeRteOptions({
plugins: ['link', 'table', 'image', 'lists', 'fullscreen'],
menubar: 'edit insert view format',
toolbar: ['fontfamily fontsize | bold italic underline strikethrough forecolor backcolor',
'alignleft aligncenter alignright alignjustify | bullist | link table image | fullscreen'],
toolbar_mode: 'sliding',
height: 400,
autofocus: false,
branding: false,
resize: false,
setup: (editor) => {
editor.on('PostRender', function() {
const container = document.querySelector('.tox.tox-hugerte-aux');
const styleSheet = document.createElement('style');
styleSheet.innerText = `
.tox-tiered-menu .tox-menu {
width: fit-content;
max-width: min(80%, 440px);
@media screen and (max-width: 510px) {
max-width: calc(100% - 64px);
}
media screen and (min-width: 511px) and (max-width: 548px) {
max-width: calc(100% - 84px);
}
media screen and (min-width: 549px) and (max-width: 599px) {
max-width: calc(100% - 104px);
}
}
.tox-tiered-menu .tox-menu .tox-collection__item-label {
word-break: normal;
}
@media screen and (max-width: 890px) {
.tox-tiered-menu > .tox-collection--list:not(:first-child) {
left: auto !important;
right: 0 !important;
}
}
`;
container.prepend(styleSheet);
});
},
relative_urls: false,
urlconverter_callback: (url) => url
};
resize: false
});
constructor(private fb: FormBuilder) {
}
@ -99,9 +63,9 @@ export class EditorPanelComponent implements OnInit {
this.editorControl = this.fb.control(this.content);
if (this.disabled) {
this.editorControl.disable({emitEvent: false});
this.tinyMceOptions.toolbar = false;
this.tinyMceOptions.menubar = false;
this.tinyMceOptions.statusbar = false;
this.hugeRteOptions.toolbar = false;
this.hugeRteOptions.menubar = false;
this.hugeRteOptions.statusbar = false;
}
}

2
ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.component.html

@ -213,7 +213,7 @@
<div class="notification-content">
<div class="subject">{{ preview.processedTemplates.EMAIL.subject }}</div>
<mat-divider></mat-divider>
<editor [init]="tinyMceOptions" [initialValue]="preview.processedTemplates.EMAIL.body"></editor>
<editor [init]="hugeRteOptions" [initialValue]="preview.processedTemplates.EMAIL.body"></editor>
</div>
</section>
<section class="preview-group notification tb-form-panel stroked no-gap" *ngIf="preview.processedTemplates.SLACK?.enabled">

12
ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts

@ -47,6 +47,8 @@ import { AuthUser } from '@shared/models/user.model';
import { getCurrentAuthUser } from '@core/auth/auth.selectors';
import { TranslateService } from '@ngx-translate/core';
import { Router } from '@angular/router';
import { EditorOptions } from 'hugerte';
import { defaultHugeRteOptions, HUGERTE_BODY_ID } from '@shared/models/hugerte/hugerte.models';
export interface RequestNotificationDialogData {
request?: NotificationRequest;
@ -78,9 +80,7 @@ export class SentNotificationDialogComponent extends
showRefresh = false;
tinyMceOptions: Record<string, any> = {
base_url: '/assets/hugerte',
suffix: '.min',
hugeRteOptions: Partial<EditorOptions> = defaultHugeRteOptions({
plugins: ['autoresize'],
menubar: false,
toolbar: false,
@ -88,18 +88,16 @@ export class SentNotificationDialogComponent extends
resize: false,
readonly: true,
height: 400,
autofocus: false,
branding: false,
setup: (ed) => {
ed.on('PreInit', () => {
const document = $(ed.iframeElement.contentDocument);
const body = $('#hugerte', document);
const body = $(`#${HUGERTE_BODY_ID}`, document);
body.attr({contenteditable: false});
body.css('pointerEvents', 'none');
body.css('userSelect', 'none');
})
}
};
});
private authUser: AuthUser = getCurrentAuthUser(this.store);

2
ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.html

@ -214,7 +214,7 @@
[class.tb-error]="(interacted || templateConfigurationForm.get('EMAIL.body').touched) && templateConfigurationForm.get('EMAIL.body').hasError('required')"
translate>notification.message
</mat-label>
<editor [init]="tinyMceOptions" formControlName="body"></editor>
<editor [init]="hugeRteOptions" formControlName="body"></editor>
<mat-error class="tb-mat-error"
*ngIf="(interacted || templateConfigurationForm.get('EMAIL.body').touched) && templateConfigurationForm.get('EMAIL.body').hasError('required')">
{{ 'notification.message-required' | translate }}

44
ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.ts

@ -38,6 +38,7 @@ import { deepClone, isDefinedAndNotNull } from '@core/utils';
import { coerceBoolean } from '@shared/decorators/coercion';
import { TranslateService } from '@ngx-translate/core';
import { EditorOptions } from 'hugerte';
import { defaultHugeRteOptions } from '@shared/models/hugerte/hugerte.models';
@Component({
selector: 'tb-template-configuration',
@ -83,52 +84,15 @@ export class NotificationTemplateConfigurationComponent implements OnDestroy, Co
readonly NotificationDeliveryMethod = NotificationDeliveryMethod;
readonly NotificationTemplateTypeTranslateMap = NotificationTemplateTypeTranslateMap;
tinyMceOptions: Partial<EditorOptions> = {
base_url: '/assets/hugerte',
suffix: '.min',
hugeRteOptions: Partial<EditorOptions> = defaultHugeRteOptions({
plugins: ['link', 'table', 'image', 'lists', 'code', 'fullscreen'],
menubar: 'edit insert tools view format table',
toolbar: 'undo redo | fontfamily fontsize blocks | bold italic strikethrough | forecolor backcolor ' +
'| link table image | alignleft aligncenter alignright alignjustify ' +
'| numlist bullist | outdent indent | removeformat | code | fullscreen',
toolbar_mode: 'sliding',
height: 400,
autofocus: false,
branding: false,
setup: (editor) => {
editor.on('PostRender', function() {
const container = document.querySelector('.tox.tox-hugerte-aux');
const styleSheet = document.createElement('style');
styleSheet.innerText = `
.tox-tiered-menu .tox-menu {
width: fit-content;
max-width: min(80%, 440px);
@media screen and (max-width: 510px) {
max-width: calc(100% - 64px);
}
media screen and (min-width: 511px) and (max-width: 548px) {
max-width: calc(100% - 84px);
}
media screen and (min-width: 549px) and (max-width: 599px) {
max-width: calc(100% - 104px);
}
}
.tox-tiered-menu .tox-menu .tox-collection__item-label {
word-break: normal;
}
@media screen and (max-width: 890px) {
.tox-tiered-menu > .tox-collection--list:not(:first-child) {
left: auto !important;
right: 0 !important;
}
}
`;
container.prepend(styleSheet);
});
},
relative_urls: false,
urlconverter_callback: (url) => url
};
height: 400
});
private propagateChange = null;
private readonly destroy$ = new Subject<void>();

34
ui-ngx/src/app/shared/models/hugerte/hugerte.models.ts

@ -0,0 +1,34 @@
///
/// Copyright © 2016-2026 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { EditorOptions } from 'hugerte';
export const HUGERTE_ASSETS_PATH = 'assets/hugerte';
export const HUGERTE_BODY_ID = 'hugerte';
export function defaultHugeRteOptions(overrides: Partial<EditorOptions>): Partial<EditorOptions> {
return {
base_url: '/' + HUGERTE_ASSETS_PATH,
suffix: '.min',
body_id: HUGERTE_BODY_ID,
autofocus: false,
branding: false,
relative_urls: false,
urlconverter_callback: (url) => url,
...overrides
};
}

3
ui-ngx/src/app/shared/shared.module.ts

@ -65,6 +65,7 @@ import { HotkeyModule } from 'angular2-hotkeys';
import { ColorPickerModule } from '@iplab/ngx-color-picker';
import { NgxHmCarouselComponent, NgxHmCarouselDynamicDirective, NgxHmCarouselItemDirective } from 'ngx-hm-carousel';
import { EditorModule, HUGERTE_SCRIPT_SRC } from '@hugerte/hugerte-angular';
import { HUGERTE_ASSETS_PATH } from '@shared/models/hugerte/hugerte.models';
import { UserMenuComponent } from '@shared/components/user-menu.component';
import { TruncateWithTooltipDirective } from '@shared/directives/truncate-with-tooltip.directive';
import { ContextMenuDirective } from '@shared/directives/context-menu.directive';
@ -259,7 +260,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
},
{
provide: HUGERTE_SCRIPT_SRC,
useValue: 'assets/hugerte/hugerte.min.js'
useValue: `${HUGERTE_ASSETS_PATH}/hugerte.min.js`
},
{
provide: MAT_DATE_LOCALE,

25
ui-ngx/src/styles.scss

@ -1235,6 +1235,31 @@ pre.tb-highlight {
}
}
.tox-tiered-menu .tox-menu {
width: fit-content;
max-width: min(80%, 440px);
@media screen and (max-width: 510px) {
max-width: calc(100% - 64px);
}
@media screen and (min-width: 511px) and (max-width: 548px) {
max-width: calc(100% - 84px);
}
@media screen and (min-width: 549px) and (max-width: 599px) {
max-width: calc(100% - 104px);
}
}
.tox-tiered-menu .tox-menu .tox-collection__item-label {
word-break: normal;
}
@media screen and (max-width: 890px) {
.tox-tiered-menu > .tox-collection--list:not(:first-child) {
left: auto !important;
right: 0 !important;
}
}
.tb-toast-panel {
pointer-events: none !important;
}

6
ui-ngx/yarn.lock

@ -1619,7 +1619,7 @@
resolved "https://registry.yarnpkg.com/@hugerte/framework-integration-shared/-/framework-integration-shared-1.2.0.tgz#75f04e4249bbb2c314d1f7a962b9c2f5fed7db80"
integrity sha512-ogcvVO0dFcb/HQAY7itj8xnmeMcHZmtMaOj9uC34ZYopnvj12TGWnfRQwbt8jZMlmoZk2z1TTLmJgvQBuH013A==
"@hugerte/hugerte-angular@^1.1.1":
"@hugerte/hugerte-angular@~1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@hugerte/hugerte-angular/-/hugerte-angular-1.1.1.tgz#08b2c963d66d7a754e8cd4884b9111ca166781e7"
integrity sha512-ubh6ZG3+dU6g3BkS2ZHx0FO46nti6N2CpN2gG/URFtF+pau/V59N94E7w7+8VeoPjqsFRpjB6zefRGNUoTJLOA==
@ -6811,7 +6811,7 @@ https-proxy-agent@7.0.6, https-proxy-agent@^7.0.1:
agent-base "^7.1.2"
debug "4"
hugerte@^1.0.12:
hugerte@~1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/hugerte/-/hugerte-1.0.12.tgz#84337116bd7e76c39e851a51d5dc0214af9882b8"
integrity sha512-/JDCdJy1C83a7+RjlfWx6EjRvxqmmHFA5Pzcq8Y0ngdBESiC+2xa4ogsqnRPeadF04Cs95YfTd1SKquDdksjRw==
@ -7601,7 +7601,7 @@ less-loader@12.3.0:
resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-12.3.0.tgz#d4a00361568be86a97da3df4f16954b0d4c15340"
integrity sha512-0M6+uYulvYIWs52y0LqN4+QM9TqWAohYSNTo4htE8Z7Cn3G/qQMEmktfHmyJT23k+20kU9zHH2wrfFXkxNLtVw==
less@4.4.0, less@4.9.0:
less@4.4.0, less@>=4.9.0:
version "4.9.0"
resolved "https://registry.yarnpkg.com/less/-/less-4.9.0.tgz#df49f940f89a1d158c315609735d3ca12da3e740"
integrity sha512-umRhrCH7fCi8Uj2RcwKjJdvUORTjeWqkdKx0LbcZvjIwsAVsnIAGcxHaqowPeBFBjQuWOeC/bve0AlpFzF/+SQ==

Loading…
Cancel
Save