thingsboard/ui-ngx/src/app/shared/components/json-object-view.component.ts
2023-01-31 10:43:56 +02:00

172 lines
5.0 KiB
TypeScript

///
/// Copyright © 2016-2023 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 { Component, ElementRef, forwardRef, Input, OnDestroy, OnInit, Renderer2, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Ace } from 'ace-builds';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { RafService } from '@core/services/raf.service';
import { isDefinedAndNotNull, isUndefined } from '@core/utils';
import { getAce } from '@shared/models/ace/ace.models';
@Component({
selector: 'tb-json-object-view',
templateUrl: './json-object-view.component.html',
styleUrls: ['./json-object-view.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => JsonObjectViewComponent),
multi: true
}
]
})
export class JsonObjectViewComponent implements OnInit, OnDestroy {
@ViewChild('jsonViewer', {static: true})
jsonViewerElmRef: ElementRef;
private jsonViewer: Ace.Editor;
private viewerElement: Ace.Editor;
private propagateChange = null;
private modelValue: any;
private contentValue: string;
@Input() label: string;
@Input() fillHeight: boolean;
@Input() editorStyle: { [klass: string]: any };
@Input() sort: (key: string, value: any) => any;
private widthValue: boolean;
get autoWidth(): boolean {
return this.widthValue;
}
@Input()
set autoWidth(value: boolean) {
this.widthValue = coerceBooleanProperty(value);
}
private heigthValue: boolean;
get autoHeight(): boolean {
return this.heigthValue;
}
@Input()
set autoHeight(value: boolean) {
this.heigthValue = coerceBooleanProperty(value);
}
constructor(public elementRef: ElementRef,
protected store: Store<AppState>,
private raf: RafService,
private renderer: Renderer2) {
}
ngOnInit(): void {
this.viewerElement = this.jsonViewerElmRef.nativeElement;
let editorOptions: Partial<Ace.EditorOptions> = {
mode: 'ace/mode/java',
theme: 'ace/theme/github',
showGutter: false,
showPrintMargin: false,
readOnly: true
};
const advancedOptions = {
enableSnippets: false,
enableBasicAutocompletion: false,
enableLiveAutocompletion: false
};
editorOptions = {...editorOptions, ...advancedOptions};
getAce().subscribe(
(ace) => {
this.jsonViewer = ace.edit(this.viewerElement, editorOptions);
this.jsonViewer.session.setUseWrapMode(false);
this.jsonViewer.setValue(this.contentValue ? this.contentValue : '', -1);
if (this.contentValue && (this.widthValue || this.heigthValue)) {
this.updateEditorSize(this.viewerElement, this.contentValue, this.jsonViewer);
}
}
);
}
ngOnDestroy(): void {
if (this.jsonViewer) {
this.jsonViewer.destroy();
}
}
updateEditorSize(editorElement: any, content: string, editor: Ace.Editor) {
let newHeight = 200;
let newWidth = 600;
if (content && content.length > 0) {
const lines = content.split('\n');
newHeight = 17 * lines.length + 17;
let maxLineLength = 0;
lines.forEach((row) => {
const line = row.replace(/\t/g, ' ').replace(/\n/g, '');
const lineLength = line.length;
maxLineLength = Math.max(maxLineLength, lineLength);
});
newWidth = 8 * maxLineLength + 16;
}
if (this.heigthValue) {
this.renderer.setStyle(editorElement, 'height', newHeight.toString() + 'px');
}
if (this.widthValue) {
this.renderer.setStyle(editorElement, 'width', newWidth.toString() + 'px');
}
editor.resize();
}
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
registerOnTouched(fn: any): void {
}
writeValue(value: any): void {
this.modelValue = value;
this.contentValue = '';
try {
if (isDefinedAndNotNull(this.modelValue)) {
this.contentValue = JSON.stringify(this.modelValue, isUndefined(this.sort) ? undefined :
(key, objectValue) => {
return this.sort(key, objectValue);
}, 2);
}
} catch (e) {
console.error(e);
}
if (this.jsonViewer) {
this.jsonViewer.setValue(this.contentValue ? this.contentValue : '', -1);
if (this.contentValue && (this.widthValue || this.heigthValue)) {
this.updateEditorSize(this.viewerElement, this.contentValue, this.jsonViewer);
}
}
}
}