From e182930da5db2f5a0837874c51bccdfa49ac43c9 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Wed, 21 Sep 2022 15:54:30 +0300 Subject: [PATCH 1/7] Fix mardown widget --- .../widget/lib/markdown-widget.component.ts | 3 +- .../markdown-widget-settings.component.html | 3 +- .../components/markdown-editor.component.html | 56 +++++++++++++------ .../components/markdown-editor.component.scss | 33 ++++++----- .../components/markdown-editor.component.ts | 2 + 5 files changed, 65 insertions(+), 32 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts index daf2e40221..76da48e3ad 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts @@ -119,8 +119,7 @@ export class MarkdownWidgetComponent extends PageComponent implements OnInit { const data = formattedDataFormDatasourceData(initialData); let markdownText = this.settings.useMarkdownTextFunction ? safeExecute(this.markdownTextFunction, [data]) : this.settings.markdownTextPattern; - const allData = flatFormattedData(data); - markdownText = createLabelFromPattern(markdownText, allData); + markdownText = createLabelFromPattern(markdownText, data[0]); if (this.markdownText !== markdownText) { this.markdownText = this.utils.customTranslation(markdownText, markdownText); this.cd.detectChanges(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html index 3859a17e90..57aa379b96 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html @@ -28,7 +28,8 @@ + label="{{ 'widgets.markdown.markdown-text-pattern' | translate }}" + helpId="widget/editor/test"> diff --git a/ui-ngx/src/app/shared/components/markdown-editor.component.html b/ui-ngx/src/app/shared/components/markdown-editor.component.html index 2259f4d38f..d29aca1c7f 100644 --- a/ui-ngx/src/app/shared/components/markdown-editor.component.html +++ b/ui-ngx/src/app/shared/components/markdown-editor.component.html @@ -17,25 +17,49 @@ -->
-
+ + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+ +
+
-
- - - -
diff --git a/ui-ngx/src/app/shared/components/markdown-editor.component.scss b/ui-ngx/src/app/shared/components/markdown-editor.component.scss index a4149c54d7..0cb67e9223 100644 --- a/ui-ngx/src/app/shared/components/markdown-editor.component.scss +++ b/ui-ngx/src/app/shared/components/markdown-editor.component.scss @@ -58,20 +58,27 @@ overflow: auto; height: 100%; } - .buttons-panel { - position: absolute; - top: 5px; - right: 24px; - z-index: 1; - button.edit-toggle { - min-width: 32px; - min-height: 15px; - padding: 4px; - margin: 0; - font-size: .8rem; - line-height: 15px; + button.edit-toggle { + min-width: 32px; + min-height: 15px; + padding: 4px; + margin-right: 4px; + font-size: .8rem; + line-height: 15px; + color: #7b7b7b; + background: rgba(220, 220, 220, .35); + } + button.mat-button, button.mat-icon-button, button.mat-icon-button.tb-mat-32 { + background: rgba(220, 220, 220, .35); + align-items: center; + vertical-align: middle; + min-width: 32px; + min-height: 15px; + padding: 4px; + font-size: .8rem; + line-height: 15px; + &:not(.tb-help-popup-button) { color: #7b7b7b; - background: rgba(220, 220, 220, .35); } } } diff --git a/ui-ngx/src/app/shared/components/markdown-editor.component.ts b/ui-ngx/src/app/shared/components/markdown-editor.component.ts index 7c1c9c7c02..3038b906f5 100644 --- a/ui-ngx/src/app/shared/components/markdown-editor.component.ts +++ b/ui-ngx/src/app/shared/components/markdown-editor.component.ts @@ -40,6 +40,8 @@ export class MarkdownEditorComponent implements OnInit, ControlValueAccessor { @Input() readonly: boolean; + @Input() helpId: string; + @ViewChild('markdownEditor', {static: true}) markdownEditorElmRef: ElementRef; From ddd64c88fbcc0b0cc604da6febe2d606f29c5e02 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Mon, 3 Oct 2022 16:43:53 +0300 Subject: [PATCH 2/7] Add UI help --- .../lib/settings/cards/markdown-widget-settings.component.html | 2 +- .../lib/settings/cards/qrcode-widget-settings.component.html | 1 + ui-ngx/src/assets/locale/locale.constant-en_US.json | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html index 57aa379b96..040e470be1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/markdown-widget-settings.component.html @@ -29,7 +29,7 @@ + helpId="widget/editor/widget_js_markdown_pattern"> diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/qrcode-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/qrcode-widget-settings.component.html index 715d1f1fe6..f0157c8987 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/qrcode-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/qrcode-widget-settings.component.html @@ -22,6 +22,7 @@ widgets.qr-code.qr-code-text-pattern + {{ 'widgets.qr-code.qr-code-text-pattern-hint' | translate }} {{ 'widgets.qr-code.qr-code-text-pattern-required' | translate }} 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 26f6834b11..484a6fea83 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4190,6 +4190,7 @@ "qr-code": { "use-qr-code-text-function": "Use QR code text function", "qr-code-text-pattern": "QR code text pattern (for ex. '${entityName} | ${keyName} - some text.')", + "qr-code-text-pattern-hint": "QR code text pattern get keys only from the first entity in the entity alias.", "qr-code-text-pattern-required": "QR code text pattern is required.", "qr-code-text-function": "QR code text function" }, From bdb41aab0da1488f321c0ff46bd61d1ff4fb9112 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Mon, 3 Oct 2022 16:48:54 +0300 Subject: [PATCH 3/7] Refactoring --- .../components/markdown-editor.component.html | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/ui-ngx/src/app/shared/components/markdown-editor.component.html b/ui-ngx/src/app/shared/components/markdown-editor.component.html index d29aca1c7f..2bb2e7b6f5 100644 --- a/ui-ngx/src/app/shared/components/markdown-editor.component.html +++ b/ui-ngx/src/app/shared/components/markdown-editor.component.html @@ -17,25 +17,6 @@ -->
- - - - - - - - - - - - - - - - - - -
From dcfece71d131f4466fb51c15802b170c40dba164 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Mon, 3 Oct 2022 17:54:02 +0300 Subject: [PATCH 4/7] Add UI helper to Markdown/HTML pattern --- .../editor/widget_js_markdown_pattern.md | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 ui-ngx/src/assets/help/en_US/widget/editor/widget_js_markdown_pattern.md diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_markdown_pattern.md b/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_markdown_pattern.md new file mode 100644 index 0000000000..68c0e43a70 --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_markdown_pattern.md @@ -0,0 +1,68 @@ +#### Markdown pattern + +
+
+ +The Markdown template gets keys only from the first entity in the entity alias. + +
+
+ +#### Examples + +Use # to create a Markdown header. The number of characters # specifies the type of header: # - h1, ## - h2, ### - h3, etc. + +```markdown + ###### Markdown/HTML card +{:copy-code} +``` + ###### Markdown/HTML card + +
+
+ +Use - character to create list item. You can create nested lists separating them with tabs in the pattern: + + ```markdown + - Element 1 + - Element 2 + - Element 2.1 + - Element 2.2 + -Element 3 +{:copy-code} + ``` +- Element 1 +- Element 2 + - Element 2.1 + - Element 2.2 +- Element 3 + +
+
+ +Use * character to choose style: + + ```markdown + - *Element 1* + - **Element 2** + - ***Element 3*** +{:copy-code} + ``` +- *Element 1* +- **Element 2** +- ***Element 3*** + +
+
+ +Use ${} to add some value from your key: + ```markdown + - **Element 1**: ${key1Name} + - **Element 1**: ${key2Name} + - **Element 1**: ${key3Name} +{:copy-code} + ``` + - **Element 1**: key1Value + - **Element 2**: key2Value + - **Element 3**: key3Value + From d330def8807727d0436c6cf2d2af9a775c88c50f Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Tue, 25 Oct 2022 12:07:15 +0300 Subject: [PATCH 5/7] Refactoring css style --- .../components/markdown-editor.component.html | 6 +++--- .../components/markdown-editor.component.scss | 16 ++-------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/ui-ngx/src/app/shared/components/markdown-editor.component.html b/ui-ngx/src/app/shared/components/markdown-editor.component.html index 2bb2e7b6f5..74e69216de 100644 --- a/ui-ngx/src/app/shared/components/markdown-editor.component.html +++ b/ui-ngx/src/app/shared/components/markdown-editor.component.html @@ -21,11 +21,11 @@
@@ -34,7 +34,7 @@ matTooltipPosition="above" style="border-radius: 50%" (click)="fullscreen = !fullscreen"> -
diff --git a/ui-ngx/src/app/shared/components/markdown-editor.component.scss b/ui-ngx/src/app/shared/components/markdown-editor.component.scss index 0cb67e9223..1a1cf57a63 100644 --- a/ui-ngx/src/app/shared/components/markdown-editor.component.scss +++ b/ui-ngx/src/app/shared/components/markdown-editor.component.scss @@ -58,17 +58,7 @@ overflow: auto; height: 100%; } - button.edit-toggle { - min-width: 32px; - min-height: 15px; - padding: 4px; - margin-right: 4px; - font-size: .8rem; - line-height: 15px; - color: #7b7b7b; - background: rgba(220, 220, 220, .35); - } - button.mat-button, button.mat-icon-button, button.mat-icon-button.tb-mat-32 { + button.panel-button { background: rgba(220, 220, 220, .35); align-items: center; vertical-align: middle; @@ -77,8 +67,6 @@ padding: 4px; font-size: .8rem; line-height: 15px; - &:not(.tb-help-popup-button) { - color: #7b7b7b; - } + color: #7b7b7b; } } From c6dff4145bfa44f94b47d44927e51d811da77426 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Wed, 2 Nov 2022 11:32:53 +0200 Subject: [PATCH 6/7] Update logic for markdown and QR code widgets --- ui-ngx/src/app/core/utils.ts | 14 ++++++++++++++ .../widget/lib/markdown-widget.component.ts | 8 ++++---- .../widget/lib/qrcode-widget.component.ts | 5 ++--- .../widget/editor/widget_js_markdown_pattern.md | 2 +- .../src/assets/locale/locale.constant-en_US.json | 2 +- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ui-ngx/src/app/core/utils.ts b/ui-ngx/src/app/core/utils.ts index bedc963186..8b288cd5a1 100644 --- a/ui-ngx/src/app/core/utils.ts +++ b/ui-ngx/src/app/core/utils.ts @@ -25,6 +25,7 @@ import { HttpErrorResponse } from '@angular/common/http'; import { letterSpacing } from 'html2canvas/dist/types/css/property-descriptors/letter-spacing'; import { TranslateService } from '@ngx-translate/core'; import { serverErrorCodesTranslations } from '@shared/models/constants'; +import { isNotNullOrUndefined } from 'codelyzer/util/isNotNullOrUndefined'; const varsRegex = /\${([^}]*)}/g; @@ -479,6 +480,19 @@ export function flatFormattedData(input: FormattedData[]): FormattedData { return result; } +export function filteringData(data: FormattedData[]): FormattedData { + const processingKeyValue = {}; + for (const deviceData of data) { + Object.keys(deviceData).forEach((valueKey) => { + if (!isNotNullOrUndefined(processingKeyValue[valueKey]) && isNotNullOrUndefined(deviceData[valueKey]) && + deviceData[valueKey] !== '') { + processingKeyValue[valueKey] = deviceData[valueKey]; + } + }); + } + return processingKeyValue as FormattedData; +} + export function mergeFormattedData(first: FormattedData[], second: FormattedData[]): FormattedData[] { const merged = first.concat(second); return _(merged).groupBy(el => el.$datasource) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts index 76da48e3ad..f37d5eb17d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts @@ -23,12 +23,11 @@ import { DatasourceData, FormattedData } from '@shared/models/widget.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { createLabelFromPattern, - fillDataPattern, - flatFormattedData, + filteringData, formattedDataFormDatasourceData, hashCode, isDefinedAndNotNull, isNotEmptyStr, - parseFunction, processDataPattern, + parseFunction, safeExecute } from '@core/utils'; import cssjs from '@core/css/css'; @@ -119,7 +118,8 @@ export class MarkdownWidgetComponent extends PageComponent implements OnInit { const data = formattedDataFormDatasourceData(initialData); let markdownText = this.settings.useMarkdownTextFunction ? safeExecute(this.markdownTextFunction, [data]) : this.settings.markdownTextPattern; - markdownText = createLabelFromPattern(markdownText, data[0]); + const allData: FormattedData = filteringData(data); + markdownText = createLabelFromPattern(markdownText, allData); if (this.markdownText !== markdownText) { this.markdownText = this.utils.customTranslation(markdownText, markdownText); this.cd.detectChanges(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/qrcode-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/qrcode-widget.component.ts index 07e5334419..88207caeb2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/qrcode-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/qrcode-widget.component.ts @@ -23,7 +23,7 @@ import { DatasourceData, FormattedData } from '@shared/models/widget.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { createLabelFromPattern, - flatFormattedData, + filteringData, formattedDataFormDatasourceData, isNumber, isObject, @@ -101,7 +101,7 @@ export class QrCodeWidgetComponent extends PageComponent implements OnInit, Afte const data = formattedDataFormDatasourceData(initialData); const pattern = this.settings.useQrCodeTextFunction ? safeExecute(this.qrCodeTextFunction, [data]) : this.settings.qrCodeTextPattern; - const allData = flatFormattedData(data); + const allData: FormattedData = filteringData(data); qrCodeText = createLabelFromPattern(pattern, allData); this.updateQrCodeText(qrCodeText); } @@ -132,5 +132,4 @@ export class QrCodeWidgetComponent extends PageComponent implements OnInit, Afte this.scheduleUpdateCanvas = true; } } - } diff --git a/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_markdown_pattern.md b/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_markdown_pattern.md index 68c0e43a70..fd4ab60a9c 100644 --- a/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_markdown_pattern.md +++ b/ui-ngx/src/assets/help/en_US/widget/editor/widget_js_markdown_pattern.md @@ -3,7 +3,7 @@

-The Markdown template gets keys only from the first entity in the entity alias. +The Markdown template displays the value of the first found key in the entities in the entity alias.

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 484a6fea83..f1491d264f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4190,7 +4190,7 @@ "qr-code": { "use-qr-code-text-function": "Use QR code text function", "qr-code-text-pattern": "QR code text pattern (for ex. '${entityName} | ${keyName} - some text.')", - "qr-code-text-pattern-hint": "QR code text pattern get keys only from the first entity in the entity alias.", + "qr-code-text-pattern-hint": "QR code text pattern use the value of the first found key in the entities in the entity alias.", "qr-code-text-pattern-required": "QR code text pattern is required.", "qr-code-text-function": "QR code text function" }, From de0a196d7a4b9c435698c812c217b81670282f6a Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Wed, 2 Nov 2022 11:58:33 +0200 Subject: [PATCH 7/7] Refactoring --- ui-ngx/src/app/core/utils.ts | 17 +++++++---------- .../widget/lib/markdown-widget.component.ts | 4 ++-- .../widget/lib/qrcode-widget.component.ts | 4 ++-- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/ui-ngx/src/app/core/utils.ts b/ui-ngx/src/app/core/utils.ts index 8b288cd5a1..ab64f0c165 100644 --- a/ui-ngx/src/app/core/utils.ts +++ b/ui-ngx/src/app/core/utils.ts @@ -22,10 +22,8 @@ import { EntityId } from '@shared/models/id/entity-id'; import { NULL_UUID } from '@shared/models/id/has-uuid'; import { EntityType, baseDetailsPageByEntityType } from '@shared/models/entity-type.models'; import { HttpErrorResponse } from '@angular/common/http'; -import { letterSpacing } from 'html2canvas/dist/types/css/property-descriptors/letter-spacing'; import { TranslateService } from '@ngx-translate/core'; import { serverErrorCodesTranslations } from '@shared/models/constants'; -import { isNotNullOrUndefined } from 'codelyzer/util/isNotNullOrUndefined'; const varsRegex = /\${([^}]*)}/g; @@ -480,17 +478,16 @@ export function flatFormattedData(input: FormattedData[]): FormattedData { return result; } -export function filteringData(data: FormattedData[]): FormattedData { - const processingKeyValue = {}; - for (const deviceData of data) { - Object.keys(deviceData).forEach((valueKey) => { - if (!isNotNullOrUndefined(processingKeyValue[valueKey]) && isNotNullOrUndefined(deviceData[valueKey]) && - deviceData[valueKey] !== '') { - processingKeyValue[valueKey] = deviceData[valueKey]; +export function flatDataWithoutOverride(data: FormattedData[]): FormattedData { + const processingKeyValue = data[0]; + for (let i = 1; i < data.length; i++) { + Object.keys(data[i]).forEach((key) => { + if (!isDefinedAndNotNull(processingKeyValue[key]) || isEmptyStr(processingKeyValue[key])) { + processingKeyValue[key] = data[i][key]; } }); } - return processingKeyValue as FormattedData; + return processingKeyValue; } export function mergeFormattedData(first: FormattedData[], second: FormattedData[]): FormattedData[] { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts index f37d5eb17d..d76e43d765 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/markdown-widget.component.ts @@ -23,7 +23,7 @@ import { DatasourceData, FormattedData } from '@shared/models/widget.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { createLabelFromPattern, - filteringData, + flatDataWithoutOverride, formattedDataFormDatasourceData, hashCode, isDefinedAndNotNull, isNotEmptyStr, @@ -118,7 +118,7 @@ export class MarkdownWidgetComponent extends PageComponent implements OnInit { const data = formattedDataFormDatasourceData(initialData); let markdownText = this.settings.useMarkdownTextFunction ? safeExecute(this.markdownTextFunction, [data]) : this.settings.markdownTextPattern; - const allData: FormattedData = filteringData(data); + const allData: FormattedData = flatDataWithoutOverride(data); markdownText = createLabelFromPattern(markdownText, allData); if (this.markdownText !== markdownText) { this.markdownText = this.utils.customTranslation(markdownText, markdownText); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/qrcode-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/qrcode-widget.component.ts index 88207caeb2..94f7d10471 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/qrcode-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/qrcode-widget.component.ts @@ -23,7 +23,7 @@ import { DatasourceData, FormattedData } from '@shared/models/widget.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { createLabelFromPattern, - filteringData, + flatDataWithoutOverride, formattedDataFormDatasourceData, isNumber, isObject, @@ -101,7 +101,7 @@ export class QrCodeWidgetComponent extends PageComponent implements OnInit, Afte const data = formattedDataFormDatasourceData(initialData); const pattern = this.settings.useQrCodeTextFunction ? safeExecute(this.qrCodeTextFunction, [data]) : this.settings.qrCodeTextPattern; - const allData: FormattedData = filteringData(data); + const allData: FormattedData = flatDataWithoutOverride(data); qrCodeText = createLabelFromPattern(pattern, allData); this.updateQrCodeText(qrCodeText); }