diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.html
index 256f6e7f9f..0a757fd34f 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.html
@@ -85,6 +85,39 @@
{{key.label}}
+
any;
@@ -90,6 +95,7 @@ interface MultipleInputWidgetDataKeySettings {
invalidDateErrorMessage?: string;
minValueErrorMessage?: string;
maxValueErrorMessage?: string;
+ invalidJsonErrorMessage?: string;
useCustomIcon: boolean;
icon: string;
customIcon: string ;
@@ -103,6 +109,9 @@ interface MultipleInputWidgetDataKeySettings {
useSetValueFunction?: boolean;
setValueFunctionBody?: string;
setValueFunction?: ConvertSetValueFunction;
+ dialogTitle?: string;
+ saveButtonLabel?: string;
+ cancelButtonLabel?: string;
}
interface MultipleInputWidgetDataKey extends DataKey {
@@ -161,7 +170,8 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
private fb: UntypedFormBuilder,
private attributeService: AttributeService,
private translate: TranslateService,
- private sanitizer: DomSanitizer) {
+ private sanitizer: DomSanitizer,
+ private dialog: MatDialog) {
super(store);
}
@@ -425,6 +435,13 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
case 'select':
value = keyValue !== null ? keyValue.toString() : null;
break;
+ case 'JSON':
+ try {
+ value = JSON.parse(keyValue);
+ } catch (e) {
+ value = keyValue ? keyValue : null;
+ }
+ break;
default:
value = keyValue;
}
@@ -520,6 +537,10 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
errorMessage = keySettings.invalidDateErrorMessage;
defaultMessage = 'widgets.input-widgets.invalid-date';
break;
+ case 'invalidJSON':
+ errorMessage = keySettings.invalidJsonErrorMessage;
+ defaultMessage = 'widgets.input-widgets.json-invalid';
+ break;
default:
return '';
}
@@ -670,8 +691,8 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
}
});
if (tasks.length) {
- forkJoin(tasks).subscribe(
- () => {
+ forkJoin(tasks).subscribe({
+ next: () => {
this.multipleInputFormGroup.markAsPristine();
this.ctx.detectChanges();
this.isSavingInProgress = false;
@@ -680,13 +701,13 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
1000, 'bottom', 'left', this.toastTargetId);
}
},
- () => {
+ error: () => {
this.isSavingInProgress = false;
if (this.settings.showResultMessage) {
this.ctx.showErrorToast(this.translate.instant('widgets.input-widgets.update-failed'),
'bottom', 'left', this.toastTargetId);
}
- });
+ }});
} else {
this.multipleInputFormGroup.markAsPristine();
this.ctx.detectChanges();
@@ -718,4 +739,31 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
});
this.multipleInputFormGroup.markAsPristine();
}
+
+ openEditJSONDialog($event: Event, key: MultipleInputWidgetDataKey, source: MultipleInputWidgetSource) {
+ if ($event) {
+ $event.stopPropagation();
+ }
+ const formControl = this.multipleInputFormGroup.controls[key.formId];
+ this.dialog.open(JsonObjectEditDialogComponent, {
+ disableClose: true,
+ panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
+ data: {
+ jsonValue: formControl.value,
+ title: key.settings.dialogTitle,
+ saveLabel: key.settings.saveButtonLabel,
+ cancelLabel: key.settings.cancelButtonLabel
+ }
+ }).afterClosed().subscribe(
+ (res) => {
+ if (!isEqual(res, formControl.value)) {
+ formControl.patchValue(res);
+ formControl.markAsDirty();
+ if(!this.settings.showActionButtons) {
+ this.inputChanged(source, key);
+ }
+ }
+ }
+ );
+ }
}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html
index 186583d5c1..3c62810000 100644
--- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html
+++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html
@@ -66,6 +66,9 @@
{{ 'widgets.input-widgets.datakey-value-type-select' | translate }}
+
+ {{ 'widgets.input-widgets.datakey-value-type-json' | translate }}
+
@@ -179,6 +182,28 @@
widgets.input-widgets.invalid-date-error-message
+
+ widgets.input-widgets.invalid-JSON-error-message
+
+
+
+
diff --git a/ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.ts b/ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.ts
index b1ca78b78a..e55431a327 100644
--- a/ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.ts
+++ b/ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.ts
@@ -14,18 +14,21 @@
/// limitations under the License.
///
-import { Component, Inject, OnInit } from '@angular/core';
+import { Component, Inject } from '@angular/core';
import { DialogComponent } from '@shared/components/dialog.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { Router } from '@angular/router';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
-import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
+import { FormBuilder, FormGroup } from '@angular/forms';
import { TranslateService } from '@ngx-translate/core';
+import { isNotEmptyStr } from '@core/utils';
export interface JsonObjectEditDialogData {
jsonValue: object;
title?: string;
+ saveLabel?: string;
+ cancelLabel?: string;
}
@Component({
@@ -33,24 +36,29 @@ export interface JsonObjectEditDialogData {
templateUrl: './json-object-edit-dialog.component.html',
styleUrls: []
})
-export class JsonObjectEditDialogComponent extends DialogComponent implements OnInit {
+export class JsonObjectEditDialogComponent extends DialogComponent {
- jsonFormGroup: UntypedFormGroup;
- title: string;
-
- submitted = false;
+ jsonFormGroup: FormGroup;
+ title = this.translate.instant('details.edit-json');
+ saveButtonLabel = this.translate.instant('action.save');
+ cancelButtonLabel = this.translate.instant('action.cancel');
constructor(protected store: Store,
protected router: Router,
@Inject(MAT_DIALOG_DATA) public data: JsonObjectEditDialogData,
public dialogRef: MatDialogRef,
- public fb: UntypedFormBuilder,
+ public fb: FormBuilder,
private translate: TranslateService) {
super(store, router, dialogRef);
- }
-
- ngOnInit(): void {
- this.title = this.data.title ? this.data.title : this.translate.instant('details.edit-json');
+ if (isNotEmptyStr(this.data.title)) {
+ this.title = this.data.title;
+ }
+ if (isNotEmptyStr(this.data.saveLabel)) {
+ this.saveButtonLabel = this.data.saveLabel;
+ }
+ if (isNotEmptyStr(this.data.cancelLabel)) {
+ this.cancelButtonLabel = this.data.cancelLabel;
+ }
this.jsonFormGroup = this.fb.group({
json: [this.data.jsonValue, []]
});
diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts
index 59003e7cf5..740b413afa 100644
--- a/ui-ngx/src/app/shared/shared.module.ts
+++ b/ui-ngx/src/app/shared/shared.module.ts
@@ -464,6 +464,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
HtmlComponent,
FabTriggerDirective,
FabActionsDirective,
+ TbJsonToStringDirective,
FabToolbarComponent,
WidgetsBundleSelectComponent,
ValueInputComponent,
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 93fb935d8f..420f7ae1ef 100644
--- a/ui-ngx/src/assets/locale/locale.constant-en_US.json
+++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json
@@ -4597,6 +4597,7 @@
"datakey-value-type-string": "String",
"datakey-value-type-double": "Double",
"datakey-value-type-integer": "Integer",
+ "datakey-value-type-json": "JSON",
"datakey-value-type-boolean-checkbox": "Boolean (Checkbox)",
"datakey-value-type-boolean-switch": "Boolean (Switch)",
"datakey-value-type-date-time": "Date & Time",
@@ -4622,7 +4623,9 @@
"min-value-error-message": "'Min value' error message",
"max-value-error-message": "'Max value' error message",
"invalid-date-error-message": "'Invalid date' error message",
+ "invalid-JSON-error-message": "'Invalid JSON' error message",
"icon-settings": "Icon settings",
+ "dialog-editor-settings": "Dialog editor settings",
"use-custom-icon": "Use custom icon",
"input-cell-icon": "Icon to show before input cell",
"value-conversion-settings": "Value conversion settings",
@@ -4631,7 +4634,10 @@
"get-value-function": "getValue function",
"set-value-settings": "Set value settings",
"use-set-value-function": "Use setValue function",
- "set-value-function": "setValue function"
+ "set-value-function": "setValue function",
+ "json-invalid": "JSON value has an invalid format",
+ "title": "Title",
+ "cancel-button-label": "'Cancel' button label"
},
"invalid-qr-code-text": "Invalid input text for QR code. Input should have a string type",
"qr-code": {