Browse Source

UI: Implements and refactoring JSON type value in multiple input widget

pull/5311/head
Vladyslav_Prykhodko 4 years ago
parent
commit
28db89368b
  1. 6
      ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.html
  2. 39
      ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.ts
  3. 28
      ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html
  4. 23
      ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.ts
  5. 2
      ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.html
  6. 36
      ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.ts
  7. 6
      ui-ngx/src/assets/locale/locale.constant-en_US.json

6
ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.html

@ -106,9 +106,7 @@
</ng-container> </ng-container>
<button [disabled]="key.settings.isEditable === 'disabled' || key.settings.isEditable === 'readonly'" <button [disabled]="key.settings.isEditable === 'disabled' || key.settings.isEditable === 'readonly'"
type="button" type="button"
matSuffix matSuffix mat-icon-button
mat-button
mat-icon-button
(click)="openEditJSONDialog($event, key, source)"> (click)="openEditJSONDialog($event, key, source)">
<mat-icon>open_in_new</mat-icon> <mat-icon>open_in_new</mat-icon>
</button> </button>
@ -116,7 +114,7 @@
{{ getErrorMessageText(key.settings,'required') }} {{ getErrorMessageText(key.settings,'required') }}
</mat-error> </mat-error>
<mat-error *ngIf="multipleInputFormGroup.get(key.formId).hasError('invalidJSON')"> <mat-error *ngIf="multipleInputFormGroup.get(key.formId).hasError('invalidJSON')">
{{ 'value.json-value-invalid' | translate }} {{ getErrorMessageText(key.settings,'invalidJSON') | translate }}
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
</div> </div>

39
ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.ts

@ -26,11 +26,10 @@ import { DataKey, Datasource, DatasourceData, DatasourceType, WidgetConfig } fro
import { IWidgetSubscription } from '@core/api/widget-api.models'; import { IWidgetSubscription } from '@core/api/widget-api.models';
import { import {
createLabelFromDatasource, createLabelFromDatasource,
isBoolean, isDefined, isBoolean,
isDefined,
isDefinedAndNotNull, isDefinedAndNotNull,
isEqual, isEqual,
isNotEmptyStr,
isString,
isUndefined isUndefined
} from '@core/utils'; } from '@core/utils';
import { EntityType } from '@shared/models/entity-type.models'; import { EntityType } from '@shared/models/entity-type.models';
@ -43,7 +42,10 @@ import { forkJoin, Observable, Subject } from 'rxjs';
import { EntityId } from '@shared/models/id/entity-id'; import { EntityId } from '@shared/models/id/entity-id';
import { ResizeObserver } from '@juggle/resize-observer'; import { ResizeObserver } from '@juggle/resize-observer';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { JsonObjectEditDialogComponent, JsonObjectEditDialogData } from '@shared/components/dialog/json-object-edit-dialog.component'; import {
JsonObjectEditDialogComponent,
JsonObjectEditDialogData
} from '@shared/components/dialog/json-object-edit-dialog.component';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
@ -51,8 +53,8 @@ type FieldAlignment = 'row' | 'column';
type MultipleInputWidgetDataKeyType = 'server' | 'shared' | 'timeseries'; type MultipleInputWidgetDataKeyType = 'server' | 'shared' | 'timeseries';
export type MultipleInputWidgetDataKeyValueType = 'string' | 'double' | 'integer' | export type MultipleInputWidgetDataKeyValueType = 'string' | 'double' | 'integer' |
'JSON'| 'booleanCheckbox' | 'booleanSwitch' | 'JSON' | 'booleanCheckbox' | 'booleanSwitch' |
'dateTime' | 'date' | 'time' | 'select'; 'dateTime' | 'date' | 'time' | 'select';
type MultipleInputWidgetDataKeyEditableType = 'editable' | 'disabled' | 'readonly'; type MultipleInputWidgetDataKeyEditableType = 'editable' | 'disabled' | 'readonly';
type ConvertGetValueFunction = (value: any, ctx: WidgetContext) => any; type ConvertGetValueFunction = (value: any, ctx: WidgetContext) => any;
@ -93,6 +95,7 @@ interface MultipleInputWidgetDataKeySettings {
invalidDateErrorMessage?: string; invalidDateErrorMessage?: string;
minValueErrorMessage?: string; minValueErrorMessage?: string;
maxValueErrorMessage?: string; maxValueErrorMessage?: string;
invalidJsonErrorMessage?: string;
useCustomIcon: boolean; useCustomIcon: boolean;
icon: string; icon: string;
customIcon: string ; customIcon: string ;
@ -106,9 +109,9 @@ interface MultipleInputWidgetDataKeySettings {
useSetValueFunction?: boolean; useSetValueFunction?: boolean;
setValueFunctionBody?: string; setValueFunctionBody?: string;
setValueFunction?: ConvertSetValueFunction; setValueFunction?: ConvertSetValueFunction;
dialogTitle?: string;
saveButtonLabel?: string; saveButtonLabel?: string;
resetButtonLabel?: string; cancelButtonLabel?: string;
dialogLabel?: string;
} }
interface MultipleInputWidgetDataKey extends DataKey { interface MultipleInputWidgetDataKey extends DataKey {
@ -434,9 +437,9 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
break; break;
case 'JSON': case 'JSON':
try { try {
value = JSON.parse(keyData[0][1]); value = JSON.parse(keyValue);
} catch (e) { } catch (e) {
value = keyData[0][1] ? keyData[0][1] : null; value = keyValue ? keyValue : null;
} }
break; break;
default: default:
@ -534,6 +537,10 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
errorMessage = keySettings.invalidDateErrorMessage; errorMessage = keySettings.invalidDateErrorMessage;
defaultMessage = 'widgets.input-widgets.invalid-date'; defaultMessage = 'widgets.input-widgets.invalid-date';
break; break;
case 'invalidJSON':
errorMessage = keySettings.invalidJsonErrorMessage;
defaultMessage = 'widgets.input-widgets.json-invalid';
break;
default: default:
return ''; return '';
} }
@ -684,8 +691,8 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
} }
}); });
if (tasks.length) { if (tasks.length) {
forkJoin(tasks).subscribe( forkJoin(tasks).subscribe({
() => { next: () => {
this.multipleInputFormGroup.markAsPristine(); this.multipleInputFormGroup.markAsPristine();
this.ctx.detectChanges(); this.ctx.detectChanges();
this.isSavingInProgress = false; this.isSavingInProgress = false;
@ -694,13 +701,13 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
1000, 'bottom', 'left', this.toastTargetId); 1000, 'bottom', 'left', this.toastTargetId);
} }
}, },
() => { error: () => {
this.isSavingInProgress = false; this.isSavingInProgress = false;
if (this.settings.showResultMessage) { if (this.settings.showResultMessage) {
this.ctx.showErrorToast(this.translate.instant('widgets.input-widgets.update-failed'), this.ctx.showErrorToast(this.translate.instant('widgets.input-widgets.update-failed'),
'bottom', 'left', this.toastTargetId); 'bottom', 'left', this.toastTargetId);
} }
}); }});
} else { } else {
this.multipleInputFormGroup.markAsPristine(); this.multipleInputFormGroup.markAsPristine();
this.ctx.detectChanges(); this.ctx.detectChanges();
@ -743,9 +750,9 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
data: { data: {
jsonValue: formControl.value, jsonValue: formControl.value,
title: key.settings.dialogLabel, title: key.settings.dialogTitle,
saveLabel: key.settings.saveButtonLabel, saveLabel: key.settings.saveButtonLabel,
undoLabel: key.settings.saveButtonLabel cancelLabel: key.settings.cancelButtonLabel
} }
}).afterClosed().subscribe( }).afterClosed().subscribe(
(res) => { (res) => {

28
ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.html

@ -48,9 +48,6 @@
<mat-option [value]="'integer'"> <mat-option [value]="'integer'">
{{ 'widgets.input-widgets.datakey-value-type-integer' | translate }} {{ 'widgets.input-widgets.datakey-value-type-integer' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'JSON'">
{{ 'widgets.input-widgets.datakey-value-type-json' | translate }}
</mat-option>
<mat-option [value]="'booleanCheckbox'"> <mat-option [value]="'booleanCheckbox'">
{{ 'widgets.input-widgets.datakey-value-type-boolean-checkbox' | translate }} {{ 'widgets.input-widgets.datakey-value-type-boolean-checkbox' | translate }}
</mat-option> </mat-option>
@ -69,6 +66,9 @@
<mat-option [value]="'select'"> <mat-option [value]="'select'">
{{ 'widgets.input-widgets.datakey-value-type-select' | translate }} {{ 'widgets.input-widgets.datakey-value-type-select' | translate }}
</mat-option> </mat-option>
<mat-option [value]="'JSON'">
{{ 'widgets.input-widgets.datakey-value-type-json' | translate }}
</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</section> </section>
@ -182,6 +182,28 @@
<mat-label translate>widgets.input-widgets.invalid-date-error-message</mat-label> <mat-label translate>widgets.input-widgets.invalid-date-error-message</mat-label>
<input matInput formControlName="invalidDateErrorMessage"> <input matInput formControlName="invalidDateErrorMessage">
</mat-form-field> </mat-form-field>
<mat-form-field [fxShow]="updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value === 'JSON'" fxFlex class="mat-block">
<mat-label translate>widgets.input-widgets.invalid-JSON-error-message</mat-label>
<input matInput formControlName="invalidJsonErrorMessage">
</mat-form-field>
</fieldset>
<fieldset [fxShow]="!updateMultipleAttributesKeySettingsForm.get('dataKeyHidden').value &&
updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value === 'JSON'" class="fields-group">
<legend class="group-title" translate>widgets.input-widgets.dialog-editor-settings</legend>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.input-widgets.title</mat-label>
<input matInput formControlName="dialogTitle">
</mat-form-field>
<section fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px" fxLayoutAlign.gt-xs="start center">
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.input-widgets.save-button-label</mat-label>
<input matInput formControlName="saveButtonLabel">
</mat-form-field>
<mat-form-field fxFlex class="mat-block">
<mat-label translate>widgets.input-widgets.cancel-button-label</mat-label>
<input matInput formControlName="cancelButtonLabel">
</mat-form-field>
</section>
</fieldset> </fieldset>
<fieldset [fxShow]="!updateMultipleAttributesKeySettingsForm.get('dataKeyHidden').value" class="fields-group"> <fieldset [fxShow]="!updateMultipleAttributesKeySettingsForm.get('dataKeyHidden').value" class="fields-group">
<legend class="group-title" translate>widgets.input-widgets.icon-settings</legend> <legend class="group-title" translate>widgets.input-widgets.icon-settings</legend>

23
ui-ngx/src/app/modules/home/components/widget/lib/settings/input/update-multiple-attributes-key-settings.component.ts

@ -63,6 +63,11 @@ export class UpdateMultipleAttributesKeySettingsComponent extends WidgetSettings
minValueErrorMessage: '', minValueErrorMessage: '',
maxValueErrorMessage: '', maxValueErrorMessage: '',
invalidDateErrorMessage: '', invalidDateErrorMessage: '',
invalidJsonErrorMessage: '',
dialogTitle: '',
saveButtonLabel: '',
cancelButtonLabel: '',
useCustomIcon: false, useCustomIcon: false,
icon: '', icon: '',
@ -108,6 +113,13 @@ export class UpdateMultipleAttributesKeySettingsComponent extends WidgetSettings
minValueErrorMessage: [settings.minValueErrorMessage, []], minValueErrorMessage: [settings.minValueErrorMessage, []],
maxValueErrorMessage: [settings.maxValueErrorMessage, []], maxValueErrorMessage: [settings.maxValueErrorMessage, []],
invalidDateErrorMessage: [settings.invalidDateErrorMessage, []], invalidDateErrorMessage: [settings.invalidDateErrorMessage, []],
invalidJsonErrorMessage: [settings.invalidJsonErrorMessage, []],
// Dialog settings
dialogTitle: [settings.dialogTitle, []],
saveButtonLabel: [settings.saveButtonLabel, []],
cancelButtonLabel: [settings.cancelButtonLabel, []],
// Icon settings // Icon settings
@ -131,7 +143,8 @@ export class UpdateMultipleAttributesKeySettingsComponent extends WidgetSettings
protected updateValidators(emitEvent: boolean) { protected updateValidators(emitEvent: boolean) {
const dataKeyHidden: boolean = this.updateMultipleAttributesKeySettingsForm.get('dataKeyHidden').value; const dataKeyHidden: boolean = this.updateMultipleAttributesKeySettingsForm.get('dataKeyHidden').value;
const dataKeyValueType: MultipleInputWidgetDataKeyValueType = this.updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value; const dataKeyValueType: MultipleInputWidgetDataKeyValueType =
this.updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value;
const required: boolean = this.updateMultipleAttributesKeySettingsForm.get('required').value; const required: boolean = this.updateMultipleAttributesKeySettingsForm.get('required').value;
const isEditable: string = this.updateMultipleAttributesKeySettingsForm.get('isEditable').value; const isEditable: string = this.updateMultipleAttributesKeySettingsForm.get('isEditable').value;
const useCustomIcon: boolean = this.updateMultipleAttributesKeySettingsForm.get('useCustomIcon').value; const useCustomIcon: boolean = this.updateMultipleAttributesKeySettingsForm.get('useCustomIcon').value;
@ -166,6 +179,11 @@ export class UpdateMultipleAttributesKeySettingsComponent extends WidgetSettings
this.updateMultipleAttributesKeySettingsForm.get('maxValueErrorMessage').enable({emitEvent: false}); this.updateMultipleAttributesKeySettingsForm.get('maxValueErrorMessage').enable({emitEvent: false});
} else if (dataKeyValueType === 'dateTime' || dataKeyValueType === 'date' || dataKeyValueType === 'time') { } else if (dataKeyValueType === 'dateTime' || dataKeyValueType === 'date' || dataKeyValueType === 'time') {
this.updateMultipleAttributesKeySettingsForm.get('invalidDateErrorMessage').enable({emitEvent: false}); this.updateMultipleAttributesKeySettingsForm.get('invalidDateErrorMessage').enable({emitEvent: false});
} else if (dataKeyValueType === 'JSON') {
this.updateMultipleAttributesKeySettingsForm.get('invalidJsonErrorMessage').enable({emitEvent: false});
this.updateMultipleAttributesKeySettingsForm.get('dialogTitle').enable({emitEvent: false});
this.updateMultipleAttributesKeySettingsForm.get('saveButtonLabel').enable({emitEvent: false});
this.updateMultipleAttributesKeySettingsForm.get('cancelButtonLabel').enable({emitEvent: false});
} }
if (required) { if (required) {
this.updateMultipleAttributesKeySettingsForm.get('requiredErrorMessage').enable({emitEvent: false}); this.updateMultipleAttributesKeySettingsForm.get('requiredErrorMessage').enable({emitEvent: false});
@ -244,7 +262,8 @@ export class UpdateMultipleAttributesKeySettingsComponent extends WidgetSettings
displayErrorMessagesSection(): boolean { displayErrorMessagesSection(): boolean {
const dataKeyHidden: boolean = this.updateMultipleAttributesKeySettingsForm.get('dataKeyHidden').value; const dataKeyHidden: boolean = this.updateMultipleAttributesKeySettingsForm.get('dataKeyHidden').value;
const required: boolean = this.updateMultipleAttributesKeySettingsForm.get('required').value; const required: boolean = this.updateMultipleAttributesKeySettingsForm.get('required').value;
const dataKeyValueType: string = this.updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value; const dataKeyValueType: MultipleInputWidgetDataKeyValueType =
this.updateMultipleAttributesKeySettingsForm.get('dataKeyValueType').value;
return !dataKeyHidden && (required || (['integer', 'double', 'dateTime', 'date', 'time', 'JSON'].includes(dataKeyValueType))); return !dataKeyHidden && (required || (['integer', 'double', 'dateTime', 'date', 'time', 'JSON'].includes(dataKeyValueType)));
} }
} }

2
ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.html

@ -45,7 +45,7 @@
type="button" type="button"
[disabled]="(isLoading$ | async)" [disabled]="(isLoading$ | async)"
(click)="cancel()" cdkFocusInitial> (click)="cancel()" cdkFocusInitial>
{{ undoButtonLabel }} {{ cancelButtonLabel }}
</button> </button>
<button mat-button mat-raised-button color="primary" <button mat-button mat-raised-button color="primary"
type="submit" type="submit"

36
ui-ngx/src/app/shared/components/dialog/json-object-edit-dialog.component.ts

@ -14,20 +14,21 @@
/// limitations under the License. /// 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 { DialogComponent } from '@shared/components/dialog.component';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; 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 { TranslateService } from '@ngx-translate/core';
import { isNotEmptyStr } from '@core/utils';
export interface JsonObjectEditDialogData { export interface JsonObjectEditDialogData {
jsonValue: object; jsonValue: object;
title?: string; title?: string;
saveLabel?: string; saveLabel?: string;
undoLabel?: string; cancelLabel?: string;
} }
@Component({ @Component({
@ -35,28 +36,29 @@ export interface JsonObjectEditDialogData {
templateUrl: './json-object-edit-dialog.component.html', templateUrl: './json-object-edit-dialog.component.html',
styleUrls: [] styleUrls: []
}) })
export class JsonObjectEditDialogComponent extends DialogComponent<JsonObjectEditDialogComponent, object> implements OnInit { export class JsonObjectEditDialogComponent extends DialogComponent<JsonObjectEditDialogComponent, object> {
jsonFormGroup: UntypedFormGroup; jsonFormGroup: FormGroup;
title: string; title = this.translate.instant('details.edit-json');
saveButtonLabel: string; saveButtonLabel = this.translate.instant('action.save');
undoButtonLabel: string; cancelButtonLabel = this.translate.instant('action.cancel');
submitted = false;
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
protected router: Router, protected router: Router,
@Inject(MAT_DIALOG_DATA) public data: JsonObjectEditDialogData, @Inject(MAT_DIALOG_DATA) public data: JsonObjectEditDialogData,
public dialogRef: MatDialogRef<JsonObjectEditDialogComponent, object>, public dialogRef: MatDialogRef<JsonObjectEditDialogComponent, object>,
public fb: UntypedFormBuilder, public fb: FormBuilder,
private translate: TranslateService) { private translate: TranslateService) {
super(store, router, dialogRef); super(store, router, dialogRef);
} if (isNotEmptyStr(this.data.title)) {
this.title = this.data.title;
ngOnInit(): void { }
this.title = this.data.title ? this.data.title : this.translate.instant('details.edit-json'); if (isNotEmptyStr(this.data.saveLabel)) {
this.saveButtonLabel = this.data.saveLabel ? this.data.saveLabel : this.translate.instant('action.save'); this.saveButtonLabel = this.data.saveLabel;
this.undoButtonLabel = this.data.undoLabel ? this.data.undoLabel : this.translate.instant('action.cancel'); }
if (isNotEmptyStr(this.data.cancelLabel)) {
this.cancelButtonLabel = this.data.cancelLabel;
}
this.jsonFormGroup = this.fb.group({ this.jsonFormGroup = this.fb.group({
json: [this.data.jsonValue, []] json: [this.data.jsonValue, []]
}); });

6
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -4617,6 +4617,7 @@
"invalid-date-error-message": "'Invalid date' error message", "invalid-date-error-message": "'Invalid date' error message",
"invalid-JSON-error-message": "'Invalid JSON' error message", "invalid-JSON-error-message": "'Invalid JSON' error message",
"icon-settings": "Icon settings", "icon-settings": "Icon settings",
"dialog-editor-settings": "Dialog editor settings",
"use-custom-icon": "Use custom icon", "use-custom-icon": "Use custom icon",
"input-cell-icon": "Icon to show before input cell", "input-cell-icon": "Icon to show before input cell",
"value-conversion-settings": "Value conversion settings", "value-conversion-settings": "Value conversion settings",
@ -4625,7 +4626,10 @@
"get-value-function": "getValue function", "get-value-function": "getValue function",
"set-value-settings": "Set value settings", "set-value-settings": "Set value settings",
"use-set-value-function": "Use setValue function", "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", "invalid-qr-code-text": "Invalid input text for QR code. Input should have a string type",
"qr-code": { "qr-code": {

Loading…
Cancel
Save