From 1db0eb573769ab867ef5120bbd45e30cfcd4a001 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Thu, 20 May 2021 17:06:42 +0300 Subject: [PATCH 1/3] monaco editor wip --- apps/red-ui/src/app/app.module.ts | 18 +- .../dictionary-overview-screen.component.html | 4 +- .../dictionary-overview-screen.component.ts | 10 +- .../dossier-dictionary-dialog.component.html | 2 +- .../dossier-dictionary-dialog.component.ts | 4 +- .../edit-project-dictionary.component.html | 2 +- .../edit-project-dictionary.component.ts | 4 +- .../dictionary-manager.component.html | 67 +++-- .../dictionary-manager.component.scss | 6 + .../dictionary-manager.component.ts | 265 ++++++++---------- .../src/app/modules/shared/shared.module.ts | 3 +- package.json | 5 +- yarn.lock | 7 + 13 files changed, 191 insertions(+), 206 deletions(-) diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index 3b5d314a6..aa408141d 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -1,5 +1,5 @@ import { BrowserModule } from '@angular/platform-browser'; -import { APP_INITIALIZER, Inject, NgModule } from '@angular/core'; +import { APP_INITIALIZER, NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { ActivatedRoute, Router } from '@angular/router'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -20,7 +20,6 @@ import { AuthErrorComponent } from '@components/auth-error/auth-error.component' import { ToastComponent } from '@components/toast/toast.component'; import { HttpCacheInterceptor } from '@redaction/red-cache'; import { NotificationsComponent } from '@components/notifications/notifications.component'; -import { KeycloakService } from 'keycloak-angular'; import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component'; import { AppRoutingModule } from './app-routing.module'; import { SharedModule } from '@shared/shared.module'; @@ -28,8 +27,9 @@ import { FileUploadDownloadModule } from '@upload-download/file-upload-download. import { UserProfileScreenComponent } from '@components/user-profile/user-profile-screen.component'; import { PlatformLocation } from '@angular/common'; import { BASE_HREF } from './tokens'; +import { MONACO_PATH, MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'; -declare let ace; +// declare let ace; export function httpLoaderFactory(httpClient: HttpClient) { return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json'); @@ -67,6 +67,7 @@ const components = [ AuthModule, ApiModule, AppRoutingModule, + MonacoEditorModule, ToastrModule.forRoot({ closeButton: true, enableHtml: true, @@ -102,20 +103,23 @@ const components = [ multi: true, useFactory: languageInitializer, deps: [LanguageService] + }, + { + provide: MONACO_PATH, + useValue: 'https://unpkg.com/monaco-editor@0.24.0/min/vs' } ], bootstrap: [AppComponent] }) export class AppModule { constructor( - @Inject(BASE_HREF) private readonly _baseHref: string, + // @Inject(BASE_HREF) private readonly _baseHref: string, private readonly _router: Router, - private readonly _route: ActivatedRoute, - private readonly _keyCloakService: KeycloakService + private readonly _route: ActivatedRoute ) { this._configureKeyCloakRouteHandling(); - ace.config.set('basePath', _baseHref + '/assets/ace-builds/'); + // ace.config.set('basePath', _baseHref + '/assets/ace-builds/'); } private _configureKeyCloakRouteHandling() { diff --git a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.html index 91f14e497..16300d4e3 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.html @@ -63,7 +63,7 @@
- {{ dictionaryManager.initialDictionaryEntries?.length }} + {{ dictionaryManager.initialEntries?.length }}
diff --git a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts index d8c5b401d..373bc680a 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts @@ -3,11 +3,9 @@ import { DictionaryControllerService, TypeValue } from '@redaction/red-ui-http'; import { AppStateService } from '@state/app-state.service'; import { PermissionsService } from '@services/permissions.service'; import { ActivatedRoute, Router } from '@angular/router'; -import { NotificationService } from '@services/notification.service'; import { TranslateService } from '@ngx-translate/core'; import { saveAs } from 'file-saver'; import { ComponentHasChanges } from '@guards/can-deactivate.guard'; -import { FormBuilder } from '@angular/forms'; import { AdminDialogService } from '../../services/admin-dialog.service'; import { DictionaryManagerComponent } from '../../../shared/components/dictionary-manager/dictionary-manager.component'; import { DictionarySaveService } from '../../../shared/services/dictionary-save.service'; @@ -22,20 +20,18 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple entries: string[] = []; @ViewChild('dictionaryManager', { static: false }) - private _dictionaryManager: DictionaryManagerComponent; - @ViewChild('fileInput') private _fileInput: ElementRef; + private readonly _dictionaryManager: DictionaryManagerComponent; + @ViewChild('fileInput') private readonly _fileInput: ElementRef; constructor( readonly permissionsService: PermissionsService, - private readonly _notificationService: NotificationService, protected readonly _translateService: TranslateService, private readonly _dictionarySaveService: DictionarySaveService, private readonly _dictionaryControllerService: DictionaryControllerService, private readonly _dialogService: AdminDialogService, private readonly _router: Router, private readonly _activatedRoute: ActivatedRoute, - private readonly _appStateService: AppStateService, - private readonly _formBuilder: FormBuilder + private readonly _appStateService: AppStateService ) { super(_translateService); this._appStateService.activateDictionary( diff --git a/apps/red-ui/src/app/modules/projects/dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component.html b/apps/red-ui/src/app/modules/projects/dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component.html index ed6607f78..2f61b1b69 100644 --- a/apps/red-ui/src/app/modules/projects/dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component.html +++ b/apps/red-ui/src/app/modules/projects/dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component.html @@ -7,7 +7,7 @@ #dictionaryManager [withFloatingActions]="false" [canEdit]="canEdit" - [initialDictionaryEntries]="project.type?.entries" + [initialEntries]="project.type?.entries" >
diff --git a/apps/red-ui/src/app/modules/projects/dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component.ts b/apps/red-ui/src/app/modules/projects/dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component.ts index d07667e21..900fb9966 100644 --- a/apps/red-ui/src/app/modules/projects/dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component.ts +++ b/apps/red-ui/src/app/modules/projects/dialogs/dossier-dictionary-dialog/dossier-dictionary-dialog.component.ts @@ -31,8 +31,8 @@ export class DossierDictionaryDialogComponent { saveDossierDictionary() { this._dictionarySaveService .saveEntries( - this._dictionaryManager.currentDictionaryEntries, - this._dictionaryManager.initialDictionaryEntries, + this._dictionaryManager.currentEntries, + this._dictionaryManager.initialEntries, this.project.ruleSetId, 'dossier_redaction', this.project.projectId diff --git a/apps/red-ui/src/app/modules/projects/dialogs/edit-project-dialog/dictionary/edit-project-dictionary.component.html b/apps/red-ui/src/app/modules/projects/dialogs/edit-project-dialog/dictionary/edit-project-dictionary.component.html index 9a82a73a6..bc28e0f49 100644 --- a/apps/red-ui/src/app/modules/projects/dialogs/edit-project-dialog/dictionary/edit-project-dictionary.component.html +++ b/apps/red-ui/src/app/modules/projects/dialogs/edit-project-dialog/dictionary/edit-project-dictionary.component.html @@ -1,5 +1,5 @@ diff --git a/apps/red-ui/src/app/modules/projects/dialogs/edit-project-dialog/dictionary/edit-project-dictionary.component.ts b/apps/red-ui/src/app/modules/projects/dialogs/edit-project-dialog/dictionary/edit-project-dictionary.component.ts index c7d014cb2..8c00c41f0 100644 --- a/apps/red-ui/src/app/modules/projects/dialogs/edit-project-dialog/dictionary/edit-project-dictionary.component.ts +++ b/apps/red-ui/src/app/modules/projects/dialogs/edit-project-dialog/dictionary/edit-project-dictionary.component.ts @@ -39,8 +39,8 @@ export class EditProjectDictionaryComponent implements EditProjectSectionInterfa save() { this._dictionarySaveService .saveEntries( - this._dictionaryManager.currentDictionaryEntries, - this._dictionaryManager.initialDictionaryEntries, + this._dictionaryManager.currentEntries, + this._dictionaryManager.initialEntries, this.projectWrapper.ruleSetId, 'dossier_redaction', this.projectWrapper.projectId, diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html index dcdd4db08..ce0578af2 100644 --- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html +++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html @@ -36,7 +36,7 @@ -
+
{{ 'dictionary-overview.compare.compare' | translate }} @@ -64,45 +64,52 @@
- - + + + + + + + + + + + + +
- - + + + + + + + + + +
(); - activeEditMarkers: any[] = []; - activeSearchMarkers: any[] = []; - searchPositions: any[] = []; + editDecorations: IModelDeltaDecoration[] = []; + searchDecorations: IModelDeltaDecoration[] = []; + searchPositions: ISearchPosition[] = []; currentMatch = 1; - currentDictionaryEntries: string[] = []; - compareDictionaryEntries: string[] = []; + currentEntries: string[] = []; changedLines: number[] = []; - aceOptions = { showPrintMargin: false }; + editorOptions = { theme: 'vs-light', language: 'text/plain', automaticLayout: true }; + diffEditorText = ''; searchText = ''; selectRuleSet = { name: 'dictionary-overview.compare.select-ruleset' }; selectDictionary = { label: 'dictionary-overview.compare.select-dictionary' }; ruleSets: RuleSetModel[]; dictionaries: TypeValue[] = [this.selectDictionary]; - compareForm: FormGroup; + form: FormGroup; - @ViewChild('editorComponent', { static: true }) private _editorComponent: AceEditorComponent; - @ViewChild('compareEditorComponent') private _compareEditorComponent: AceEditorComponent; + private _codeEditor: ICodeEditor; + private _diffEditor: IDiffEditor; constructor( - private readonly _notificationService: NotificationService, - protected readonly _translateService: TranslateService, private readonly _dictionaryControllerService: DictionaryControllerService, - private readonly _router: Router, - private readonly _activatedRoute: ActivatedRoute, private readonly _appStateService: AppStateService, - private readonly _formBuilder: FormBuilder + private readonly _formBuilder: FormBuilder, + private readonly _changeDetector: ChangeDetectorRef ) { - this.compareForm = this._formBuilder.group({ + this.form = this._formBuilder.group({ active: [false], ruleSet: [{ value: this.selectRuleSet, disabled: true }], dictionary: [{ value: this.selectDictionary, disabled: true }] }); - this.compareForm.valueChanges.subscribe((value) => { + this.form.valueChanges.subscribe((value) => { this._setFieldStatus('ruleSet', value.active); this._setFieldStatus( 'dictionary', - value.active && this.compareForm.get('ruleSet').value !== this.selectRuleSet + value.active && this.form.get('ruleSet').value !== this.selectRuleSet ); this._loadDictionaries(); }); this.ruleSets = [this.selectRuleSet, ...this._appStateService.ruleSets]; - this.compareForm.controls.ruleSet.valueChanges.subscribe(() => { + this.form.controls.ruleSet.valueChanges.subscribe(() => { this._onRuleSetChanged(); }); - this.compareForm.controls.dictionary.valueChanges.subscribe((dictionary) => { + this.form.controls.dictionary.valueChanges.subscribe((dictionary) => { this._onDictionaryChanged(dictionary); }); } - private static _setEditorValue(editor: AceEditorComponent, entries: string[]) { - const dictionaryEntriesAsText = entries.join('\n'); - editor.getEditor().setValue(dictionaryEntriesAsText); - editor.getEditor().gotoLine(1); + onDiffEditorInit(editor: IDiffEditor): void { + this._diffEditor = editor; + } + + onCodeEditorInit(editor: ICodeEditor): void { + this._codeEditor = editor; + } + + get showDiffEditor(): boolean { + return ( + this.form.get('active').value && + this.form.get('dictionary').value !== this.selectDictionary + ); } get editorValue() { - return this._editorComponent.getEditor().getValue(); + return this._codeEditor.getModel().getValue(); } set editorValue(value: any) { - this._editorComponent.getEditor().setValue(value); - } - - ngOnInit(): void { - this._editorComponent.getEditor().selection.on('changeCursor', () => { - this._syncActiveLines(); - }); + this._codeEditor.getModel().setValue(value); } revert() { - DictionaryManagerComponent._setEditorValue( - this._editorComponent, - this.initialDictionaryEntries - ); + this.currentEntries = this.initialEntries; this.searchChanged(''); } @debounce() searchChanged(text: string) { this.searchText = text.toLowerCase(); - this._applySearchMarkers(); + this._applySearchDecorations(); this.currentMatch = 0; this.nextSearchMatch(); } - @debounce(500) - textChanged($event: any) { - this._applySearchMarkers(); - this.currentDictionaryEntries = $event.split('\n'); + get codeEditorText(): string { + return this.currentEntries.join('\n'); + } + + set codeEditorText(text: string) { + this._applySearchDecorations(); + this.currentEntries = text.split('\n'); this.changedLines = []; - this.activeEditMarkers.forEach((am) => { - this._editorComponent.getEditor().getSession().removeMarker(am); + this.editDecorations = []; + this._codeEditor.deltaDecorations([], this.editDecorations); + + this.currentEntries.forEach((entry, index) => { + if (this.initialEntries.indexOf(entry) < 0) { + this.changedLines.push(index); + } }); - this.activeEditMarkers = []; - for (let i = 0; i < this.currentDictionaryEntries.length; i++) { - const currentEntry = this.currentDictionaryEntries[i]; - if (this.initialDictionaryEntries.indexOf(currentEntry) < 0) { - this.changedLines.push(i); - } - } + this.changedLines.forEach((line) => this._makeDecorations(line)); + this._codeEditor.deltaDecorations([], this.editDecorations); + } - const range = ace.require('ace/range').Range; - for (const i of this.changedLines) { - const entry = this.currentDictionaryEntries[i]; - if (entry?.trim().length > 0) { - // only mark non-empty lines - this.activeEditMarkers.push( - this._editorComponent - .getEditor() - .getSession() - .addMarker(new range(i, 0, i, 1), 'changed-row-marker', 'fullLine') - ); - } - if (entry?.trim().length > 0 && entry.trim().length < MIN_WORD_LENGTH) { - // show lines that are too short - this.activeEditMarkers.push( - this._editorComponent - .getEditor() - .getSession() - .addMarker(new range(i, 0, i, 1), 'too-short-marker', 'fullLine') - ); - } + private _makeDecorations(line: number) { + const entry = this.currentEntries[line]; + if (entry.trim().length === 0) return; + const wholeLine = new monaco.Range(line, 0, line, 1); + const decoration: IModelDeltaDecoration = { + range: wholeLine, + options: { isWholeLine: true, inlineClassName: 'changed-row-marker' } + }; + this.editDecorations.push(decoration); + if (entry.trim().length < MIN_WORD_LENGTH) { + this.editDecorations.push({ + range: wholeLine, + options: { isWholeLine: true, inlineClassName: 'too-short-marker' } + }); } } get hasChanges() { return ( - this.currentDictionaryEntries.length && - (this.activeEditMarkers.length > 0 || - this.currentDictionaryEntries.filter((e) => e && e.trim().length > 0).length < - this.initialDictionaryEntries.length) + this.currentEntries.length && + (this.editDecorations.length > 0 || + this.currentEntries.filter((e) => e.trim().length > 0).length < + this.initialEntries.length) ); } nextSearchMatch() { - // length = 3 if (this.searchPositions.length > 0) { this.currentMatch = this.currentMatch < this.searchPositions.length ? this.currentMatch + 1 : 1; @@ -195,11 +188,11 @@ export class DictionaryManagerComponent implements OnInit, OnChanges { } private _setFieldStatus(field: 'ruleSet' | 'dictionary', enabled: boolean) { - this.compareForm.get(field)[enabled ? 'enable' : 'disable']({ emitEvent: false }); + this.form.get(field)[enabled ? 'enable' : 'disable']({ emitEvent: false }); } private _loadDictionaries() { - const ruleSetId = this.compareForm.get('ruleSet').value.ruleSetId; + const ruleSetId = this.form.get('ruleSet').value.ruleSetId; if (!ruleSetId) { this.dictionaries = [this.selectDictionary]; return; @@ -207,46 +200,29 @@ export class DictionaryManagerComponent implements OnInit, OnChanges { const appStateDictionaryData = this._appStateService.dictionaryData[ruleSetId]; this.dictionaries = [ this.selectDictionary, - ...Object.keys(appStateDictionaryData) - .map((key) => appStateDictionaryData[key]) - .filter((d) => !d.virtual || d.type === 'false_positive') + ...Object.values(appStateDictionaryData).filter( + (d) => !d.virtual || d.type === 'false_positive' + ) ]; } - private _applySearchMarkers() { + private _applySearchDecorations() { this.searchPositions = this._getSearchPositions(); - this.activeSearchMarkers.forEach((am) => { - this._editorComponent.getEditor().getSession().removeMarker(am); - }); - this.activeSearchMarkers = []; + this.searchDecorations = this.searchPositions.map(({ row, column, length }) => ({ + range: new monaco.Range(row, column, row, column + length), + options: { inlineClassName: 'search-marker' } + })); - const range = ace.require('ace/range').Range; - for (const position of this.searchPositions) { - this.activeSearchMarkers.push( - this._editorComponent - .getEditor() - .getSession() - .addMarker( - new range( - position.row, - position.column, - position.row, - position.column + position.length - ), - 'search-marker', - 'text' - ) - ); - } + this._codeEditor.deltaDecorations([], this.searchDecorations); } - private _getSearchPositions() { - const lowerCaseSearchText = this.searchText.toLowerCase(); - return this.currentDictionaryEntries + private _getSearchPositions(): ISearchPosition[] { + const searchText = this.searchText.toLowerCase(); + return this.currentEntries .map((val, index) => { - const columnIndex = val.toLowerCase().indexOf(lowerCaseSearchText); + const columnIndex = val.toLowerCase().indexOf(searchText); if (columnIndex >= 0) { - return { row: index, column: columnIndex, length: lowerCaseSearchText.length }; + return { row: index, column: columnIndex, length: searchText.length }; } }) .filter((entry) => !!entry); @@ -254,47 +230,34 @@ export class DictionaryManagerComponent implements OnInit, OnChanges { private _gotoLine() { const position = this.searchPositions[this.currentMatch - 1]; - this._editorComponent.getEditor().scrollToLine(position.row, true, true, () => {}); - this._editorComponent.getEditor().gotoLine(position.row + 1, position.column, true); + this._codeEditor.setScrollPosition({ scrollTop: position.row }); + // this._editorComponent.getEditor().scrollToLine(position.row, true, true, () => {}); + // this._editorComponent.getEditor().gotoLine(position.row + 1, position.column, true); } private _onRuleSetChanged() { this._loadDictionaries(); - this.compareForm.patchValue({ dictionary: this.selectDictionary }); + this.form.patchValue({ dictionary: this.selectDictionary }); } private _onDictionaryChanged(dictionary: TypeValue) { - if (dictionary !== this.selectDictionary) { - this._dictionaryControllerService - .getDictionaryForType(dictionary.ruleSetId, dictionary.type) - .subscribe( - (data) => { - this.compareDictionaryEntries = data.entries.sort((str1, str2) => - str1.localeCompare(str2, undefined, { sensitivity: 'accent' }) - ); - DictionaryManagerComponent._setEditorValue( - this._compareEditorComponent, - this.compareDictionaryEntries - ); - this._syncActiveLines(); - }, - () => {} - ); + if (dictionary === this.selectDictionary) { + return; } - } - - private _syncActiveLines() { - if (this._compareEditorComponent) { - this._compareEditorComponent.getEditor().gotoLine(this._activeRow); - } - } - - private get _activeRow(): number { - return this._editorComponent.getEditor().selection.getCursor().row + 1; + this._dictionaryControllerService + .getDictionaryForType(dictionary.ruleSetId, dictionary.type) + .subscribe((data) => { + this.diffEditorText = data.entries + .sort((str1, str2) => + str1.localeCompare(str2, undefined, { sensitivity: 'accent' }) + ) + .join('\n'); + this._changeDetector.detectChanges(); + }); } saveEntries() { - this.saveDictionary.emit(this.currentDictionaryEntries); + this.saveDictionary.emit(this.currentEntries); } ngOnChanges(): void { diff --git a/apps/red-ui/src/app/modules/shared/shared.module.ts b/apps/red-ui/src/app/modules/shared/shared.module.ts index f9cee8881..36380dcea 100644 --- a/apps/red-ui/src/app/modules/shared/shared.module.ts +++ b/apps/red-ui/src/app/modules/shared/shared.module.ts @@ -35,6 +35,7 @@ import { NavigateLastProjectsScreenDirective } from './directives/navigate-last- import { DictionaryManagerComponent } from './components/dictionary-manager/dictionary-manager.component'; import { AceEditorModule } from 'ng2-ace-editor'; import { SideNavComponent } from '@shared/components/side-nav/side-nav.component'; +import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'; const buttons = [ ChevronButtonComponent, @@ -84,7 +85,7 @@ const modules = [ @NgModule({ declarations: [...components, ...utils, DictionaryManagerComponent], - imports: [CommonModule, ...modules, AceEditorModule], + imports: [CommonModule, ...modules, AceEditorModule, MonacoEditorModule], exports: [...modules, ...components, ...utils, DictionaryManagerComponent], providers: [ { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] }, diff --git a/package.json b/package.json index a3a7623b7..b5ab2a7b5 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@angular/platform-browser-dynamic": "12.0.0", "@angular/router": "12.0.0", "@angular/service-worker": "12.0.0", + "@materia-ui/ngx-monaco-editor": "^5.1.0", "@ngx-translate/core": "^13.0.0", "@ngx-translate/http-loader": "^6.0.0", "@nrwl/angular": "12.3.3", @@ -108,7 +109,7 @@ "superagent-promise": "^1.1.0", "ts-jest": "26.5.6", "ts-node": "9.1.1", - "webpack": "^4.18.1", - "typescript": "4.2.4" + "typescript": "4.2.4", + "webpack": "^4.18.1" } } diff --git a/yarn.lock b/yarn.lock index 86175bee8..fe9e2baf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2379,6 +2379,13 @@ merge-source-map "^1.1.0" schema-utils "^2.7.0" +"@materia-ui/ngx-monaco-editor@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@materia-ui/ngx-monaco-editor/-/ngx-monaco-editor-5.1.0.tgz#76c2f7ec3654f4ad30fa4a5b8439dcf0fa0f47f4" + integrity sha512-5k4yJzh1rbygbgwomcTOA63NABr/pYMZZNmtwN/2/eo07ZNxiJY3puNKjJkNN2cuWeZA5Qu7LKDS0E8oYpN/cg== + dependencies: + tslib "^1.10.0" + "@ngtools/webpack@12.0.0": version "12.0.0" resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-12.0.0.tgz#b2f6cc8f727cc9fdf54faac27ce1b4865c471b1c" From 0a457a64e6cb1c260c9a37f816436386ecfa044c Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Tue, 25 May 2021 10:59:13 +0300 Subject: [PATCH 2/3] working editor --- .../dictionary-overview-screen.component.ts | 2 +- .../dictionary-manager.component.html | 25 +- .../dictionary-manager.component.ts | 224 +++++++++--------- apps/red-ui/src/assets/styles/red-editor.scss | 3 - 4 files changed, 117 insertions(+), 137 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts index 373bc680a..e952312da 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/dictionary-overview/dictionary-overview-screen.component.ts @@ -89,7 +89,7 @@ export class DictionaryOverviewScreenComponent extends ComponentHasChanges imple if (file) { fileReader.onload = () => { - this._dictionaryManager.editorValue = fileReader.result; + this._dictionaryManager.editorValue = fileReader.result as string; this._fileInput.nativeElement.value = null; }; fileReader.readAsText(file); diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html index ce0578af2..ada7c69d8 100644 --- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html +++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.html @@ -16,7 +16,7 @@
- {{ currentMatch + '/' + searchPositions.length }} + {{ currentMatch + '/' + searchMatches.length }}
- - - - - - - - - - - + +
- - - - - - - - - -
(); - editDecorations: IModelDeltaDecoration[] = []; - searchDecorations: IModelDeltaDecoration[] = []; - searchPositions: ISearchPosition[] = []; - currentMatch = 1; + currentMatch = 0; + searchMatches: FindMatch[] = []; currentEntries: string[] = []; - changedLines: number[] = []; - editorOptions = { theme: 'vs-light', language: 'text/plain', automaticLayout: true }; + editorOptions: IStandaloneEditorConstructionOptions = { + theme: 'vs', + language: 'text/plain', + automaticLayout: true, + readOnly: !this.canEdit + }; diffEditorText = ''; + showDiffEditor = false; searchText = ''; selectRuleSet = { name: 'dictionary-overview.compare.select-ruleset' }; @@ -55,13 +50,15 @@ export class DictionaryManagerComponent implements OnChanges { private _codeEditor: ICodeEditor; private _diffEditor: IDiffEditor; + private _decorations: string[] = []; + private _searchDecorations: string[] = []; constructor( private readonly _dictionaryControllerService: DictionaryControllerService, private readonly _appStateService: AppStateService, - private readonly _formBuilder: FormBuilder, - private readonly _changeDetector: ChangeDetectorRef + private readonly _formBuilder: FormBuilder ) { + this.currentEntries = this.initialEntries; this.form = this._formBuilder.group({ active: [false], ruleSet: [{ value: this.selectRuleSet, disabled: true }], @@ -83,8 +80,17 @@ export class DictionaryManagerComponent implements OnChanges { this._onRuleSetChanged(); }); + this.form.controls.active.valueChanges.subscribe((value) => { + this.showDiffEditor = + value && this.form.get('dictionary').value !== this.selectDictionary; + }); + this.form.controls.dictionary.valueChanges.subscribe((dictionary) => { - this._onDictionaryChanged(dictionary); + this._onDictionaryChanged(dictionary).subscribe((data) => { + this.diffEditorText = data; + this.showDiffEditor = dictionary !== this.selectDictionary; + if (this.showDiffEditor) this._diffEditor?.getOriginalEditor().setValue(data); + }); }); } @@ -94,21 +100,23 @@ export class DictionaryManagerComponent implements OnChanges { onCodeEditorInit(editor: ICodeEditor): void { this._codeEditor = editor; + (window as any).monaco.editor.defineTheme('redaction', { + base: 'vs', + inherit: true, + rules: [], + colors: { + 'editor.lineHighlightBackground': '#f4f5f7' + } + }); + (window as any).monaco.editor.setTheme('redaction'); } - get showDiffEditor(): boolean { - return ( - this.form.get('active').value && - this.form.get('dictionary').value !== this.selectDictionary - ); + get editorValue(): string { + return this._codeEditor?.getModel()?.getValue(); } - get editorValue() { - return this._codeEditor.getModel().getValue(); - } - - set editorValue(value: any) { - this._codeEditor.getModel().setValue(value); + set editorValue(value: string) { + this._codeEditor?.getModel()?.setValue(value); } revert() { @@ -119,71 +127,88 @@ export class DictionaryManagerComponent implements OnChanges { @debounce() searchChanged(text: string) { this.searchText = text.toLowerCase(); + this.searchMatches = this._getMatches(this.searchText); this._applySearchDecorations(); + this.currentMatch = 0; this.nextSearchMatch(); } + private _applySearchDecorations() { + this._searchDecorations = this._codeEditor.deltaDecorations(this._searchDecorations, []); + + const decorations = this.searchMatches.map( + (match) => + ({ + range: match.range, + options: { inlineClassName: 'search-marker' } + } as IModelDeltaDecoration) + ); + + this._searchDecorations = this._codeEditor.deltaDecorations( + this._searchDecorations, + decorations + ); + } + + private _getMatches(text: string): FindMatch[] { + const model = this._codeEditor?.getModel(); + return model.findMatches(text, false, false, false, null, false) || []; + } + get codeEditorText(): string { return this.currentEntries.join('\n'); } set codeEditorText(text: string) { - this._applySearchDecorations(); this.currentEntries = text.split('\n'); - this.changedLines = []; - this.editDecorations = []; - this._codeEditor.deltaDecorations([], this.editDecorations); - - this.currentEntries.forEach((entry, index) => { - if (this.initialEntries.indexOf(entry) < 0) { - this.changedLines.push(index); - } - }); - - this.changedLines.forEach((line) => this._makeDecorations(line)); - this._codeEditor.deltaDecorations([], this.editDecorations); + this.codeEditorTextChanged(); } - private _makeDecorations(line: number) { - const entry = this.currentEntries[line]; - if (entry.trim().length === 0) return; - const wholeLine = new monaco.Range(line, 0, line, 1); - const decoration: IModelDeltaDecoration = { - range: wholeLine, - options: { isWholeLine: true, inlineClassName: 'changed-row-marker' } - }; - this.editDecorations.push(decoration); - if (entry.trim().length < MIN_WORD_LENGTH) { - this.editDecorations.push({ - range: wholeLine, - options: { isWholeLine: true, inlineClassName: 'too-short-marker' } - }); - } + @debounce() + codeEditorTextChanged() { + const newDecorations = this.currentEntries + .filter((entry) => this._isNew(entry)) + .map((entry) => this._makeDecorationFor(entry)); + + this._decorations = this._codeEditor.deltaDecorations(this._decorations, newDecorations); } - get hasChanges() { + private _isNew(entry: string): boolean { + return this.initialEntries.indexOf(entry) < 0 && entry?.trim().length > 0; + } + + private _makeDecorationFor(entry: string): IModelDeltaDecoration { + const line = this.currentEntries.indexOf(entry) + 1; + const cssClass = entry.length < MIN_WORD_LENGTH ? 'too-short-marker' : 'changed-row-marker'; + + return { + range: new monaco.Range(line, 1, line, 1), + options: { isWholeLine: true, className: cssClass } + } as IModelDeltaDecoration; + } + + get hasChanges(): boolean { return ( this.currentEntries.length && - (this.editDecorations.length > 0 || - this.currentEntries.filter((e) => e.trim().length > 0).length < - this.initialEntries.length) + this.currentEntries.filter((e) => e.trim().length > 0).length < + this.initialEntries.length ); } - nextSearchMatch() { - if (this.searchPositions.length > 0) { + nextSearchMatch(): void { + if (this.searchMatches?.length > 0) { this.currentMatch = - this.currentMatch < this.searchPositions.length ? this.currentMatch + 1 : 1; - this._gotoLine(); + this.currentMatch < this.searchMatches.length ? this.currentMatch + 1 : 1; + this._scrollToCurrentMatch(); } } - previousSearchMatch() { - if (this.searchPositions.length > 0) { + previousSearchMatch(): void { + if (this.searchMatches.length > 0) { this.currentMatch = - this.currentMatch > 1 ? this.currentMatch - 1 : this.searchPositions.length; - this._gotoLine(); + this.currentMatch > 1 ? this.currentMatch - 1 : this.searchMatches.length; + this._scrollToCurrentMatch(); } } @@ -206,33 +231,11 @@ export class DictionaryManagerComponent implements OnChanges { ]; } - private _applySearchDecorations() { - this.searchPositions = this._getSearchPositions(); - this.searchDecorations = this.searchPositions.map(({ row, column, length }) => ({ - range: new monaco.Range(row, column, row, column + length), - options: { inlineClassName: 'search-marker' } - })); + private _scrollToCurrentMatch(): void { + const range = this.searchMatches[this.currentMatch - 1].range; - this._codeEditor.deltaDecorations([], this.searchDecorations); - } - - private _getSearchPositions(): ISearchPosition[] { - const searchText = this.searchText.toLowerCase(); - return this.currentEntries - .map((val, index) => { - const columnIndex = val.toLowerCase().indexOf(searchText); - if (columnIndex >= 0) { - return { row: index, column: columnIndex, length: searchText.length }; - } - }) - .filter((entry) => !!entry); - } - - private _gotoLine() { - const position = this.searchPositions[this.currentMatch - 1]; - this._codeEditor.setScrollPosition({ scrollTop: position.row }); - // this._editorComponent.getEditor().scrollToLine(position.row, true, true, () => {}); - // this._editorComponent.getEditor().gotoLine(position.row + 1, position.column, true); + this._codeEditor.setSelection(range); + this._codeEditor.revealLineInCenter(range.startLineNumber, SMOOTH_SCROLL); } private _onRuleSetChanged() { @@ -240,20 +243,19 @@ export class DictionaryManagerComponent implements OnChanges { this.form.patchValue({ dictionary: this.selectDictionary }); } - private _onDictionaryChanged(dictionary: TypeValue) { + private _onDictionaryChanged(dictionary: TypeValue): Observable { if (dictionary === this.selectDictionary) { - return; + return of(''); } - this._dictionaryControllerService + return this._dictionaryControllerService .getDictionaryForType(dictionary.ruleSetId, dictionary.type) - .subscribe((data) => { - this.diffEditorText = data.entries - .sort((str1, str2) => - str1.localeCompare(str2, undefined, { sensitivity: 'accent' }) - ) - .join('\n'); - this._changeDetector.detectChanges(); - }); + .pipe(map((data) => this._toString(data.entries))); + } + + private _toString(entries: string[]) { + return entries + .sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'accent' })) + .join('\n'); } saveEntries() { diff --git a/apps/red-ui/src/assets/styles/red-editor.scss b/apps/red-ui/src/assets/styles/red-editor.scss index cb53946c0..920726438 100644 --- a/apps/red-ui/src/assets/styles/red-editor.scss +++ b/apps/red-ui/src/assets/styles/red-editor.scss @@ -2,19 +2,16 @@ @import 'red-mixins'; .changed-row-marker { - position: absolute; background: rgba($primary, 0.1); z-index: 20; } .too-short-marker { - position: absolute; background: rgba($primary, 0.5); z-index: 30; } .search-marker { - position: absolute; background: rgba($blue-5, 0.3); z-index: 40; } From 4c3add97f0a75b78090dc677b597a1691777b6c2 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Tue, 25 May 2021 12:50:15 +0300 Subject: [PATCH 3/3] add monaco editor to rule sets --- angular.json | 12 +- apps/red-ui/src/app/app.module.ts | 10 +- .../src/app/modules/admin/admin.module.ts | 6 +- .../screens/rules/rules-screen.component.html | 17 +-- .../screens/rules/rules-screen.component.scss | 5 + .../screens/rules/rules-screen.component.ts | 108 ++++++++++-------- .../dictionary-manager.component.ts | 2 +- .../src/app/modules/shared/shared.module.ts | 8 +- .../src/assets/ace-editor/theme-redaction.js | 3 - apps/red-ui/src/assets/styles/red-editor.scss | 64 ----------- package.json | 1 - yarn.lock | 18 --- 12 files changed, 81 insertions(+), 173 deletions(-) delete mode 100644 apps/red-ui/src/assets/ace-editor/theme-redaction.js diff --git a/angular.json b/angular.json index 0ac3d1def..fb22eefd4 100644 --- a/angular.json +++ b/angular.json @@ -48,20 +48,10 @@ "input": "apps/red-ui/src/assets/", "output": "/assets/" }, - { - "glob": "**/*", - "input": "node_modules/ace-builds/src-min/", - "output": "/assets/ace-builds" - }, "apps/red-ui/src/manifest.webmanifest" ], "styles": ["apps/red-ui/src/styles.scss"], - "scripts": [ - "node_modules/@pdftron/webviewer/webviewer.min.js", - "node_modules/ace-builds/src-min/ace.js", - "node_modules/ace-builds/src-min/mode-java.js", - "node_modules/ace-builds/src-min/theme-eclipse.js" - ], + "scripts": ["node_modules/@pdftron/webviewer/webviewer.min.js"], "vendorChunk": true, "extractLicenses": false, "buildOptimizer": false, diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index aa408141d..1ca904ec7 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -29,8 +29,6 @@ import { PlatformLocation } from '@angular/common'; import { BASE_HREF } from './tokens'; import { MONACO_PATH, MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'; -// declare let ace; - export function httpLoaderFactory(httpClient: HttpClient) { return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json'); } @@ -112,14 +110,8 @@ const components = [ bootstrap: [AppComponent] }) export class AppModule { - constructor( - // @Inject(BASE_HREF) private readonly _baseHref: string, - private readonly _router: Router, - private readonly _route: ActivatedRoute - ) { + constructor(private readonly _router: Router, private readonly _route: ActivatedRoute) { this._configureKeyCloakRouteHandling(); - - // ace.config.set('basePath', _baseHref + '/assets/ace-builds/'); } private _configureKeyCloakRouteHandling() { diff --git a/apps/red-ui/src/app/modules/admin/admin.module.ts b/apps/red-ui/src/app/modules/admin/admin.module.ts index a4e541468..42e561b77 100644 --- a/apps/red-ui/src/app/modules/admin/admin.module.ts +++ b/apps/red-ui/src/app/modules/admin/admin.module.ts @@ -15,7 +15,6 @@ import { UserListingScreenComponent } from './screens/user-listing/user-listing- import { WatermarkScreenComponent } from './screens/watermark/watermark-screen.component'; import { AdminBreadcrumbsComponent } from './components/breadcrumbs/admin-breadcrumbs.component'; import { RuleSetActionsComponent } from './components/rule-set-actions/rule-set-actions.component'; -import { AceEditorModule } from 'ng2-ace-editor'; import { ColorPickerModule } from 'ngx-color-picker'; import { AddEditFileAttributeDialogComponent } from './dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component'; import { AddEditRuleSetDialogComponent } from './dialogs/add-edit-rule-set-dialog/add-edit-rule-set-dialog.component'; @@ -33,6 +32,7 @@ import { ConfirmDeleteUsersDialogComponent } from './dialogs/confirm-delete-user import { FileAttributesCsvImportDialogComponent } from './dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component'; import { ActiveFieldsListingComponent } from './dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component'; import { AdminSideNavComponent } from './admin-side-nav/admin-side-nav.component'; +import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'; const dialogs = [ AddEditRuleSetDialogComponent, @@ -81,9 +81,9 @@ const components = [ CommonModule, SharedModule, AdminRoutingModule, - AceEditorModule, NgxChartsModule, - ColorPickerModule + ColorPickerModule, + MonacoEditorModule ] }) export class AdminModule {} diff --git a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.html index dcac0f4c7..c04706a24 100644 --- a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.html @@ -20,18 +20,11 @@
- - +
0; + onCodeEditorInit(editor: ICodeEditor) { + this._codeEditor = editor; + (window as any).monaco.editor.defineTheme('redaction', { + base: 'vs', + inherit: true, + rules: [], + colors: { + 'editor.lineHighlightBackground': '#f4f5f7' + } + }); + (window as any).monaco.editor.setTheme('redaction'); } - textChanged($event: any) { + get hasChanges(): boolean { + return this._decorations.length > 0; + } + + get codeEditorText() { + return this.currentLines.join('\n'); + } + + set codeEditorText($event: any) { this.currentLines = $event.split('\n'); - this.changedLines = []; - this.activeEditMarkers.forEach((am) => { - this.editorComponent.getEditor().getSession().removeMarker(am); - }); - this.activeEditMarkers = []; + this.codeEditorTextChanged(); + } - for (let i = 0; i < this.currentLines.length; i++) { - const currentEntry = this.currentLines[i]; - if (this.initialLines.indexOf(currentEntry) < 0) { - this.changedLines.push(i); - } - } + @debounce() + codeEditorTextChanged() { + const newDecorations = this.currentLines + .filter((entry) => this._isNew(entry)) + .map((entry) => this._makeDecorationFor(entry)); - const range = ace.require('ace/range').Range; - for (const i of this.changedLines) { - const entry = this.currentLines[i]; - if (entry?.trim().length > 0) { - // only mark non-empty lines - this.activeEditMarkers.push( - this.editorComponent - .getEditor() - .getSession() - .addMarker(new range(i, 0, i, 1), 'changed-row-marker', 'fullLine') - ); - } - } + this._decorations = this._codeEditor.deltaDecorations(this._decorations, newDecorations); + } + + private _isNew(entry: string): boolean { + return this.initialLines.indexOf(entry) < 0 && entry?.trim().length > 0; + } + + private _makeDecorationFor(entry: string): IModelDeltaDecoration { + const line = this.currentLines.indexOf(entry) + 1; + + return { + range: new monaco.Range(line, 1, line, 1), + options: { isWholeLine: true, className: 'changed-row-marker' } + } as IModelDeltaDecoration; } async save(): Promise { this.processing = true; this._rulesControllerService .uploadRules({ - rules: this.editorComponent.getEditor().getValue(), + rules: this._codeEditor.getModel().getValue(), ruleSetId: this._appStateService.activeRuleSetId }) .subscribe( @@ -107,14 +124,13 @@ export class RulesScreenComponent extends ComponentHasChanges { } revert(): void { - this.initialLines = this.rules.split('\n'); - this.editorComponent.getEditor().setValue(this.rules); - this.editorComponent.getEditor().clearSelection(); + this.currentLines = this.initialLines; + this._decorations = this._codeEditor?.deltaDecorations(this._decorations, []) || []; this.processing = false; } download(): void { - const content = this.editorComponent.getEditor().getValue(); + const content = this._codeEditor.getModel().getValue(); const blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); @@ -127,7 +143,7 @@ export class RulesScreenComponent extends ComponentHasChanges { if (file) { fileReader.onload = () => { - this.editorComponent.getEditor().setValue(fileReader.result); + this._codeEditor.getModel().setValue(fileReader.result as string); this._fileInput.nativeElement.value = null; }; fileReader.readAsText(file); @@ -137,12 +153,10 @@ export class RulesScreenComponent extends ComponentHasChanges { private _initialize() { this._rulesControllerService.downloadRules(this._appStateService.activeRuleSetId).subscribe( (rules) => { - this.rules = rules.rules; + this.currentLines = this.initialLines = rules.rules.split('\n'); this.revert(); }, - () => { - this.processing = false; - } + () => (this.processing = false) ); } } diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts index 1f65abcba..7c7cb1e1c 100644 --- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts @@ -153,7 +153,7 @@ export class DictionaryManagerComponent implements OnChanges { private _getMatches(text: string): FindMatch[] { const model = this._codeEditor?.getModel(); - return model.findMatches(text, false, false, false, null, false) || []; + return model?.findMatches(text, false, false, false, null, false) || []; } get codeEditorText(): string { diff --git a/apps/red-ui/src/app/modules/shared/shared.module.ts b/apps/red-ui/src/app/modules/shared/shared.module.ts index 36380dcea..c70bd00e7 100644 --- a/apps/red-ui/src/app/modules/shared/shared.module.ts +++ b/apps/red-ui/src/app/modules/shared/shared.module.ts @@ -33,7 +33,6 @@ import { MomentDateAdapter } from '@angular/material-moment-adapter'; import { SelectComponent } from './components/select/select.component'; import { NavigateLastProjectsScreenDirective } from './directives/navigate-last-projects-screen.directive'; import { DictionaryManagerComponent } from './components/dictionary-manager/dictionary-manager.component'; -import { AceEditorModule } from 'ng2-ace-editor'; import { SideNavComponent } from '@shared/components/side-nav/side-nav.component'; import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'; @@ -63,6 +62,7 @@ const components = [ RoundCheckboxComponent, SelectComponent, SideNavComponent, + DictionaryManagerComponent, ...buttons ]; @@ -84,9 +84,9 @@ const modules = [ ]; @NgModule({ - declarations: [...components, ...utils, DictionaryManagerComponent], - imports: [CommonModule, ...modules, AceEditorModule, MonacoEditorModule], - exports: [...modules, ...components, ...utils, DictionaryManagerComponent], + declarations: [...components, ...utils], + imports: [CommonModule, ...modules, MonacoEditorModule], + exports: [...modules, ...components, ...utils], providers: [ { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] }, { diff --git a/apps/red-ui/src/assets/ace-editor/theme-redaction.js b/apps/red-ui/src/assets/ace-editor/theme-redaction.js deleted file mode 100644 index 38fb52867..000000000 --- a/apps/red-ui/src/assets/ace-editor/theme-redaction.js +++ /dev/null @@ -1,3 +0,0 @@ -ace.define('ace/theme/redaction', [], function (exports, object) { - object.cssClass = 'ace-redaction'; -}); diff --git a/apps/red-ui/src/assets/styles/red-editor.scss b/apps/red-ui/src/assets/styles/red-editor.scss index 920726438..acd3cf62a 100644 --- a/apps/red-ui/src/assets/styles/red-editor.scss +++ b/apps/red-ui/src/assets/styles/red-editor.scss @@ -16,72 +16,8 @@ z-index: 40; } -.ace-redaction { - color: $accent; - - .ace_gutter { - background: $grey-2; - color: $grey-7; - border-right: none; - } - - .ace_gutter-cell:after { - content: '.'; - } - - .ace_active-line { - background: $grey-6; - } - - .ace_print-margin { - width: 0; - background: $white; - } - - .ace_cursor { - color: $grey-5; - } - - .ace_marker-layer .ace_selection { - background: $grey-4; - } - - .ace_multiselect .ace_selection.ace_start { - box-shadow: 0 0 3px 0 $white; - } - - .ace_gutter-active-line { - background-color: $grey-6; - } - - .ace_marker-layer .ace_selected-word { - border: 1px solid $grey-4; - } - - .ace_invisible { - color: $grey-4; - } - - &[ng-reflect-read-only='true'] { - background-color: $grey-2; - - *:not(.ace_scrollbar) { - pointer-events: none; - } - } -} - .editor-container { width: 100%; - - ace-editor { - width: 100%; - height: 100%; - box-sizing: border-box; - border: 1px solid $grey-5; - border-radius: 8px; - background-color: $white; - } } .changes-box { diff --git a/package.json b/package.json index b5ab2a7b5..4b40789e7 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,6 @@ "keycloak-js": "13.0.0", "lodash": "^4.17.21", "moment": "^2.29.1", - "ng2-ace-editor": "^0.3.9", "ngx-color-picker": "^11.0.0", "ngx-toastr": "^13.2.1", "papaparse": "^5.3.0", diff --git a/yarn.lock b/yarn.lock index fe9e2baf1..43d2d1cb4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3354,11 +3354,6 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" -ace-builds@^1.4.2: - version "1.4.12" - resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.12.tgz#888efa386e36f4345f40b5233fcc4fe4c588fae7" - integrity sha512-G+chJctFPiiLGvs3+/Mly3apXTcfgE45dT5yp12BcWZ1kUs+gm0qd3/fv4gsz6fVag4mM0moHVpjHDIgph6Psg== - acorn-globals@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" @@ -4078,11 +4073,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace@^0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/brace/-/brace-0.11.1.tgz#4896fcc9d544eef45f4bb7660db320d3b379fe58" - integrity sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg= - braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -9563,14 +9553,6 @@ ng-packagr@12.0.0: sass "^1.32.8" stylus "^0.54.8" -ng2-ace-editor@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/ng2-ace-editor/-/ng2-ace-editor-0.3.9.tgz#5ae68712e9ca49591eda31df8fe02eca1c3634e1" - integrity sha512-e8Q4YCirlL/OEiekewmzupG+zV3prYsiYmQnRzQzd0wNgsPjOLOdb0it7cCbzFfIXKGyIIHKTW5584WxPr2LnQ== - dependencies: - ace-builds "^1.4.2" - brace "^0.11.1" - ngx-color-picker@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/ngx-color-picker/-/ngx-color-picker-11.0.0.tgz#c1e5468505953bc579bf21014a135808820ea753"