From 8bca9baf3cb371eb45023eb986b8730e21cf728c Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Mon, 25 Oct 2021 20:56:35 +0200 Subject: feat(web): show lint status on lint button --- language-web/src/main/js/editor/EditorButtons.tsx | 23 +++++++++++- language-web/src/main/js/editor/EditorStore.ts | 45 ++++++++++++++++++++++- language-web/src/main/js/editor/XtextClient.ts | 4 +- 3 files changed, 67 insertions(+), 5 deletions(-) (limited to 'language-web/src/main/js') diff --git a/language-web/src/main/js/editor/EditorButtons.tsx b/language-web/src/main/js/editor/EditorButtons.tsx index 9622475c..bd843dfe 100644 --- a/language-web/src/main/js/editor/EditorButtons.tsx +++ b/language-web/src/main/js/editor/EditorButtons.tsx @@ -1,16 +1,35 @@ +import type { Diagnostic } from '@codemirror/lint'; import { observer } from 'mobx-react-lite'; import Stack from '@mui/material/Stack'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import CheckIcon from '@mui/icons-material/Check'; +import ErrorIcon from '@mui/icons-material/Error'; import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered'; +import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import RedoIcon from '@mui/icons-material/Redo'; import SearchIcon from '@mui/icons-material/Search'; import UndoIcon from '@mui/icons-material/Undo'; +import WarningIcon from '@mui/icons-material/Warning'; import React from 'react'; import { useRootStore } from '../RootStore'; +// Exhastive switch as proven by TypeScript. +// eslint-disable-next-line consistent-return +function getLintIcon(severity: Diagnostic['severity'] | null) { + switch (severity) { + case 'error': + return ; + case 'warning': + return ; + case 'info': + return ; + case null: + return ; + } +} + export const EditorButtons = observer(() => { const { editorStore } = useRootStore(); @@ -61,10 +80,10 @@ export const EditorButtons = observer(() => { editorStore.toggleLintPanel()} - aria-label="Show errors and warnings" + aria-label={`${editorStore.errorCount} errors, ${editorStore.warningCount} warnings, ${editorStore.infoCount} info`} value="show-lint-panel" > - + {getLintIcon(editorStore.highestDiagnosticLevel)} diff --git a/language-web/src/main/js/editor/EditorStore.ts b/language-web/src/main/js/editor/EditorStore.ts index 31bb0a11..32fe6fd1 100644 --- a/language-web/src/main/js/editor/EditorStore.ts +++ b/language-web/src/main/js/editor/EditorStore.ts @@ -14,7 +14,11 @@ import { undoDepth, } from '@codemirror/history'; import { indentOnInput } from '@codemirror/language'; -import { lintKeymap } from '@codemirror/lint'; +import { + Diagnostic, + lintKeymap, + setDiagnostics, +} from '@codemirror/lint'; import { bracketMatching } from '@codemirror/matchbrackets'; import { rectangularSelection } from '@codemirror/rectangular-selection'; import { searchConfig, searchKeymap } from '@codemirror/search'; @@ -58,6 +62,12 @@ export class EditorStore { showLintPanel = false; + errorCount = 0; + + warningCount = 0; + + infoCount = 0; + readonly defaultDispatcher = (tr: Transaction): void => { this.onTransaction(tr); }; @@ -153,6 +163,39 @@ export class EditorStore { }); } + updateDiagnostics(diagnostics: Diagnostic[]): void { + this.dispatch(setDiagnostics(this.state, diagnostics)); + this.errorCount = 0; + this.warningCount = 0; + this.infoCount = 0; + diagnostics.forEach(({ severity }) => { + switch (severity) { + case 'error': + this.errorCount += 1; + break; + case 'warning': + this.warningCount += 1; + break; + case 'info': + this.infoCount += 1; + break; + } + }); + } + + get highestDiagnosticLevel(): Diagnostic['severity'] | null { + if (this.errorCount > 0) { + return 'error'; + } + if (this.warningCount > 0) { + return 'warning'; + } + if (this.infoCount > 0) { + return 'info'; + } + return null; + } + /** * @returns `true` if there is history to undo */ diff --git a/language-web/src/main/js/editor/XtextClient.ts b/language-web/src/main/js/editor/XtextClient.ts index 27ef4165..1c6c0ae6 100644 --- a/language-web/src/main/js/editor/XtextClient.ts +++ b/language-web/src/main/js/editor/XtextClient.ts @@ -1,4 +1,4 @@ -import { Diagnostic, setDiagnostics } from '@codemirror/lint'; +import type { Diagnostic } from '@codemirror/lint'; import { ChangeDesc, ChangeSet, @@ -108,7 +108,7 @@ export class XtextClient { message: issue.description, }); }); - this.store.dispatch(setDiagnostics(this.store.state, diagnostics)); + this.store.updateDiagnostics(diagnostics); } private computeChangesSinceLastUpdate() { -- cgit v1.2.3-54-g00ecf