DM-408, add error highlighting for rule edits

This commit is contained in:
George 2023-09-05 19:43:20 +03:00
parent 9ebc5623fe
commit 00dd7963c9
2 changed files with 62 additions and 6 deletions

View File

@ -13,27 +13,35 @@ import ICodeEditor = monaco.editor.ICodeEditor;
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions;
interface SyntaxError {
line: number;
column: number;
message: string;
}
@Component({
templateUrl: './rules-screen.component.html',
styleUrls: ['./rules-screen.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RulesScreenComponent implements OnInit, ComponentCanDeactivate {
@ViewChild('fileInput')
private _fileInput: ElementRef;
private _codeEditor: ICodeEditor;
private _decorations: string[] = [];
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly iconButtonTypes = IconButtonTypes;
readonly editorOptions: IStandaloneEditorConstructionOptions = {
theme: 'vs',
language: 'java',
automaticLayout: true,
readOnly: !this.permissionsService.canEditRules(),
glyphMargin: true,
};
initialLines: string[] = [];
currentLines: string[] = [];
isLeaving = false;
@ViewChild('fileInput')
private _fileInput: ElementRef;
private _codeEditor: ICodeEditor;
private _decorations: string[] = [];
private _errorGlyphs: string[] = [];
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
constructor(
readonly permissionsService: PermissionsService,
@ -92,9 +100,12 @@ export class RulesScreenComponent implements OnInit, ComponentCanDeactivate {
).then(
async () => {
await this._initialize();
this._removeErrorMarkers();
this._toaster.success(_('rules-screen.success.generic'));
},
() => {
error => {
const errors = error.error as SyntaxError[] | undefined;
this._drawErrorMarkers(errors);
this._loadingService.stop();
this._toaster.error(_('rules-screen.error.generic'));
},
@ -104,6 +115,7 @@ export class RulesScreenComponent implements OnInit, ComponentCanDeactivate {
revert(): void {
this.currentLines = this.initialLines;
this._decorations = this._codeEditor?.deltaDecorations(this._decorations, []) || [];
this._removeErrorMarkers();
this._changeDetectorRef.detectChanges();
this._loadingService.stop();
}
@ -142,6 +154,45 @@ export class RulesScreenComponent implements OnInit, ComponentCanDeactivate {
} as IModelDeltaDecoration;
}
private _drawErrorMarkers(errors: SyntaxError[] | undefined) {
const model = this._codeEditor?.getModel();
if (!model || !errors?.length) {
return;
}
const markers = [];
const glyphs = [];
errors
.filter(e => e.line > 0)
.forEach(e => {
const endColumn = model.getLineLength(e.line) + 1;
markers.push({
message: e.message,
severity: monaco.MarkerSeverity.Error,
startLineNumber: e.line,
startColumn: e.column,
endLineNumber: e.line,
endColumn,
});
glyphs.push({
range: new monaco.Range(e.line, e.column, e.line, endColumn),
options: {
glyphMarginClassName: 'error-glyph-margin',
},
});
});
this._errorGlyphs = this._codeEditor.deltaDecorations(this._errorGlyphs, glyphs);
(window as any).monaco.editor.setModelMarkers(model, model.id, markers);
}
private _removeErrorMarkers() {
const model = this._codeEditor?.getModel();
if (!model) {
return;
}
(window as any).monaco.editor.setModelMarkers(model, model.id, []);
this._errorGlyphs = this._codeEditor?.deltaDecorations(this._errorGlyphs, []) || [];
}
private async _initialize() {
this._loadingService.start();
await firstValueFrom(this._rulesService.download(this.#dossierTemplateId)).then(

View File

@ -39,6 +39,11 @@
src: url('./assets/styles/fonts/Inter-VariableFont.ttf') format('truetype');
}
.error-glyph-margin {
background: url('./assets/icons/general/alert-circle.svg') no-repeat center;
background-size: 80%;
}
@include common-variables.configureLight(
$iqser-primary: vars.$primary,
$iqser-primary-rgb: common-functions.hexToRgb(vars.$primary),