172 lines
5.0 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|