diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index b13a4d7a10..31aef06f16 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -46,6 +46,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { CookieModule } from 'ngx-cookie'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { ToastrModule } from 'ngx-toastr'; +import { EditorComponent } from 'src/app/helpers/editor/editor.component'; import { HighlightPipeTransform, ModelDiagramCodeBlockComponent, @@ -178,6 +179,7 @@ import { UsersProfileComponent } from './users/users-profile/users-profile.compo DeleteSessionDialogComponent, DisplayValueComponent, EditGitSettingsComponent, + EditorComponent, EditProjectMetadataComponent, EditT4CInstanceComponent, EventsComponent, diff --git a/frontend/src/app/helpers/editor/editor.component.html b/frontend/src/app/helpers/editor/editor.component.html new file mode 100644 index 0000000000..617d466bad --- /dev/null +++ b/frontend/src/app/helpers/editor/editor.component.html @@ -0,0 +1,6 @@ + + +
diff --git a/frontend/src/app/helpers/editor/editor.component.ts b/frontend/src/app/helpers/editor/editor.component.ts new file mode 100644 index 0000000000..8edda593c7 --- /dev/null +++ b/frontend/src/app/helpers/editor/editor.component.ts @@ -0,0 +1,104 @@ +/* + * SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + Component, + EventEmitter, + HostListener, + Input, + NgZone, + Output, +} from '@angular/core'; + +import * as monaco from 'monaco-editor'; +import { MetadataService } from 'src/app/general/metadata/metadata.service'; +import { ToastService } from 'src/app/helpers/toast/toast.service'; +import { ConfigurationSettingsService } from 'src/app/settings/core/configuration-settings/configuration-settings.service'; +import { stringify, parse, YAMLParseError } from 'yaml'; + +@Component({ + selector: 'app-editor', + templateUrl: './editor.component.html', +}) +export class EditorComponent { + private editor?: monaco.editor.IStandaloneCodeEditor = undefined; + intialValue = 'Loading...'; + + @Output() + submitted = new EventEmitter(); + + constructor( + private ngZone: NgZone, + private configurationSettingsService: ConfigurationSettingsService, + private toastService: ToastService, + private metadataService: MetadataService, + ) {} + + ngOnInit() { + this.ngZone.runOutsideAngular(() => { + this.initMonaco(); + }); + } + + @Input() + // eslint-disable-next-line @typescript-eslint/no-explicit-any + set value(data: any) { + const yaml = stringify(data, { indent: 4 }); + this.intialValue = yaml; + this.editor?.setValue(yaml); + } + + resetValue() { + this.editor?.setValue(this.intialValue); + } + + submitValue() { + if (!this.editor?.getValue()) { + this.toastService.showError( + 'Configuration is empty', + "The configuration editor doesn't contain any content. Make sure to enter a valid YAML configuration.", + ); + return; + } + let jsonValue = ''; + + try { + jsonValue = parse(this.editor?.getValue()); + } catch (e) { + if (e instanceof YAMLParseError) { + this.toastService.showError('YAML parsing error', e.message); + } else { + this.toastService.showError( + 'YAML parsing error', + 'Unknown error. Please check the console for more information.', + ); + } + return; + } + + this.submitted.emit(jsonValue); + } + + private initMonaco() { + const configModel = monaco.editor.createModel(this.intialValue, 'yaml'); + + this.editor = monaco.editor.create(document.getElementById('editor')!, { + value: 'Loading...', + language: 'yaml', + scrollBeyondLastLine: false, + model: configModel, + automaticLayout: true, + }); + } + + @HostListener('document:keydown', ['$event']) + saveHandler(event: KeyboardEvent) { + if ((event.metaKey || event.ctrlKey) && event.key === 's') { + event.preventDefault(); + event.stopPropagation(); + this.submitValue(); + } + } +} diff --git a/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.html b/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.html index 8981c42ee0..c2c00205ca 100644 --- a/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.html +++ b/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.html @@ -3,13 +3,13 @@ ~ SPDX-License-Identifier: Apache-2.0 --> -
+
- -
diff --git a/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.ts b/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.ts index b4ea4c9da9..4d35987e1a 100644 --- a/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.ts +++ b/frontend/src/app/settings/core/configuration-settings/configuration-settings.component.ts @@ -3,95 +3,42 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Component, HostListener, NgZone } from '@angular/core'; +import { Component, OnInit, ViewChild } from '@angular/core'; -import * as monaco from 'monaco-editor'; import { MetadataService } from 'src/app/general/metadata/metadata.service'; +import { EditorComponent } from 'src/app/helpers/editor/editor.component'; import { ToastService } from 'src/app/helpers/toast/toast.service'; import { ConfigurationSettingsService } from 'src/app/settings/core/configuration-settings/configuration-settings.service'; -import { stringify, parse, YAMLParseError } from 'yaml'; + @Component({ selector: 'app-configuration-settings', templateUrl: './configuration-settings.component.html', }) -export class ConfigurationSettingsComponent { - private editor?: monaco.editor.IStandaloneCodeEditor = undefined; - - intialValue = 'Loading...'; +export class ConfigurationSettingsComponent implements OnInit { + @ViewChild(EditorComponent) editor: EditorComponent | undefined; constructor( - private ngZone: NgZone, private configurationSettingsService: ConfigurationSettingsService, private toastService: ToastService, private metadataService: MetadataService, ) {} - ngOnInit() { - this.ngZone.runOutsideAngular(() => { - this.initMonaco(); - }); - + ngOnInit(): void { this.fetchConfiguration(); } - ngOnDestroy() { - if (this.editor) { - this.editor.dispose(); - } - } - - private initMonaco() { - const configModel = monaco.editor.createModel(this.intialValue, 'yaml'); - - this.editor = monaco.editor.create(document.getElementById('editor')!, { - value: 'Loading...', - language: 'yaml', - scrollBeyondLastLine: false, - model: configModel, - automaticLayout: true, - }); - } - fetchConfiguration() { this.configurationSettingsService .getConfigurationSettings('global') .subscribe((data) => { - const yaml = stringify(data, { indent: 4 }); - this.intialValue = yaml; - this.editor?.setValue(yaml); + this.editor!.value = data; }); } - resetValue() { - this.editor?.setValue(this.intialValue); - } - - submitValue() { - if (!this.editor?.getValue()) { - this.toastService.showError( - 'Configuration is empty', - "The configuration editor doesn't contain any content. Make sure to enter a valid YAML configuration.", - ); - return; - } - let jsonValue = ''; - - try { - jsonValue = parse(this.editor?.getValue()); - } catch (e) { - if (e instanceof YAMLParseError) { - this.toastService.showError('YAML parsing error', e.message); - } else { - this.toastService.showError( - 'YAML parsing error', - 'Unknown error. Please check the console for more information.', - ); - } - return; - } - + // eslint-disable-next-line @typescript-eslint/no-explicit-any + submitValue(value: any) { this.configurationSettingsService - .putConfigurationSettings('global', jsonValue) + .putConfigurationSettings('global', value) .subscribe({ next: () => { this.toastService.showSuccess( @@ -103,13 +50,4 @@ export class ConfigurationSettingsComponent { }, }); } - - @HostListener('document:keydown', ['$event']) - saveHandler(event: KeyboardEvent) { - if ((event.metaKey || event.ctrlKey) && event.key === 's') { - event.preventDefault(); - event.stopPropagation(); - this.submitValue(); - } - } }