diff options
author | Kristóf Marussy <kristof@marussy.com> | 2021-10-25 20:56:35 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2021-10-31 19:26:12 +0100 |
commit | 8bca9baf3cb371eb45023eb986b8730e21cf728c (patch) | |
tree | 07e3bae4e84f40a61ac13ac122a3a7e7de32b798 /language-web | |
parent | feat(web): disconnect background tabs only (diff) | |
download | refinery-8bca9baf3cb371eb45023eb986b8730e21cf728c.tar.gz refinery-8bca9baf3cb371eb45023eb986b8730e21cf728c.tar.zst refinery-8bca9baf3cb371eb45023eb986b8730e21cf728c.zip |
feat(web): show lint status on lint button
Diffstat (limited to 'language-web')
-rw-r--r-- | language-web/src/main/js/editor/EditorButtons.tsx | 23 | ||||
-rw-r--r-- | language-web/src/main/js/editor/EditorStore.ts | 45 | ||||
-rw-r--r-- | language-web/src/main/js/editor/XtextClient.ts | 4 |
3 files changed, 67 insertions, 5 deletions
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 @@ | |||
1 | import type { Diagnostic } from '@codemirror/lint'; | ||
1 | import { observer } from 'mobx-react-lite'; | 2 | import { observer } from 'mobx-react-lite'; |
2 | import Stack from '@mui/material/Stack'; | 3 | import Stack from '@mui/material/Stack'; |
3 | import ToggleButton from '@mui/material/ToggleButton'; | 4 | import ToggleButton from '@mui/material/ToggleButton'; |
4 | import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; | 5 | import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; |
5 | import CheckIcon from '@mui/icons-material/Check'; | 6 | import CheckIcon from '@mui/icons-material/Check'; |
7 | import ErrorIcon from '@mui/icons-material/Error'; | ||
6 | import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered'; | 8 | import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered'; |
9 | import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; | ||
7 | import RedoIcon from '@mui/icons-material/Redo'; | 10 | import RedoIcon from '@mui/icons-material/Redo'; |
8 | import SearchIcon from '@mui/icons-material/Search'; | 11 | import SearchIcon from '@mui/icons-material/Search'; |
9 | import UndoIcon from '@mui/icons-material/Undo'; | 12 | import UndoIcon from '@mui/icons-material/Undo'; |
13 | import WarningIcon from '@mui/icons-material/Warning'; | ||
10 | import React from 'react'; | 14 | import React from 'react'; |
11 | 15 | ||
12 | import { useRootStore } from '../RootStore'; | 16 | import { useRootStore } from '../RootStore'; |
13 | 17 | ||
18 | // Exhastive switch as proven by TypeScript. | ||
19 | // eslint-disable-next-line consistent-return | ||
20 | function getLintIcon(severity: Diagnostic['severity'] | null) { | ||
21 | switch (severity) { | ||
22 | case 'error': | ||
23 | return <ErrorIcon fontSize="small" />; | ||
24 | case 'warning': | ||
25 | return <WarningIcon fontSize="small" />; | ||
26 | case 'info': | ||
27 | return <InfoOutlinedIcon fontSize="small" />; | ||
28 | case null: | ||
29 | return <CheckIcon fontSize="small" />; | ||
30 | } | ||
31 | } | ||
32 | |||
14 | export const EditorButtons = observer(() => { | 33 | export const EditorButtons = observer(() => { |
15 | const { editorStore } = useRootStore(); | 34 | const { editorStore } = useRootStore(); |
16 | 35 | ||
@@ -61,10 +80,10 @@ export const EditorButtons = observer(() => { | |||
61 | <ToggleButton | 80 | <ToggleButton |
62 | selected={editorStore.showLintPanel} | 81 | selected={editorStore.showLintPanel} |
63 | onClick={() => editorStore.toggleLintPanel()} | 82 | onClick={() => editorStore.toggleLintPanel()} |
64 | aria-label="Show errors and warnings" | 83 | aria-label={`${editorStore.errorCount} errors, ${editorStore.warningCount} warnings, ${editorStore.infoCount} info`} |
65 | value="show-lint-panel" | 84 | value="show-lint-panel" |
66 | > | 85 | > |
67 | <CheckIcon fontSize="small" /> | 86 | {getLintIcon(editorStore.highestDiagnosticLevel)} |
68 | </ToggleButton> | 87 | </ToggleButton> |
69 | </ToggleButtonGroup> | 88 | </ToggleButtonGroup> |
70 | </Stack> | 89 | </Stack> |
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 { | |||
14 | undoDepth, | 14 | undoDepth, |
15 | } from '@codemirror/history'; | 15 | } from '@codemirror/history'; |
16 | import { indentOnInput } from '@codemirror/language'; | 16 | import { indentOnInput } from '@codemirror/language'; |
17 | import { lintKeymap } from '@codemirror/lint'; | 17 | import { |
18 | Diagnostic, | ||
19 | lintKeymap, | ||
20 | setDiagnostics, | ||
21 | } from '@codemirror/lint'; | ||
18 | import { bracketMatching } from '@codemirror/matchbrackets'; | 22 | import { bracketMatching } from '@codemirror/matchbrackets'; |
19 | import { rectangularSelection } from '@codemirror/rectangular-selection'; | 23 | import { rectangularSelection } from '@codemirror/rectangular-selection'; |
20 | import { searchConfig, searchKeymap } from '@codemirror/search'; | 24 | import { searchConfig, searchKeymap } from '@codemirror/search'; |
@@ -58,6 +62,12 @@ export class EditorStore { | |||
58 | 62 | ||
59 | showLintPanel = false; | 63 | showLintPanel = false; |
60 | 64 | ||
65 | errorCount = 0; | ||
66 | |||
67 | warningCount = 0; | ||
68 | |||
69 | infoCount = 0; | ||
70 | |||
61 | readonly defaultDispatcher = (tr: Transaction): void => { | 71 | readonly defaultDispatcher = (tr: Transaction): void => { |
62 | this.onTransaction(tr); | 72 | this.onTransaction(tr); |
63 | }; | 73 | }; |
@@ -153,6 +163,39 @@ export class EditorStore { | |||
153 | }); | 163 | }); |
154 | } | 164 | } |
155 | 165 | ||
166 | updateDiagnostics(diagnostics: Diagnostic[]): void { | ||
167 | this.dispatch(setDiagnostics(this.state, diagnostics)); | ||
168 | this.errorCount = 0; | ||
169 | this.warningCount = 0; | ||
170 | this.infoCount = 0; | ||
171 | diagnostics.forEach(({ severity }) => { | ||
172 | switch (severity) { | ||
173 | case 'error': | ||
174 | this.errorCount += 1; | ||
175 | break; | ||
176 | case 'warning': | ||
177 | this.warningCount += 1; | ||
178 | break; | ||
179 | case 'info': | ||
180 | this.infoCount += 1; | ||
181 | break; | ||
182 | } | ||
183 | }); | ||
184 | } | ||
185 | |||
186 | get highestDiagnosticLevel(): Diagnostic['severity'] | null { | ||
187 | if (this.errorCount > 0) { | ||
188 | return 'error'; | ||
189 | } | ||
190 | if (this.warningCount > 0) { | ||
191 | return 'warning'; | ||
192 | } | ||
193 | if (this.infoCount > 0) { | ||
194 | return 'info'; | ||
195 | } | ||
196 | return null; | ||
197 | } | ||
198 | |||
156 | /** | 199 | /** |
157 | * @returns `true` if there is history to undo | 200 | * @returns `true` if there is history to undo |
158 | */ | 201 | */ |
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 @@ | |||
1 | import { Diagnostic, setDiagnostics } from '@codemirror/lint'; | 1 | import type { Diagnostic } from '@codemirror/lint'; |
2 | import { | 2 | import { |
3 | ChangeDesc, | 3 | ChangeDesc, |
4 | ChangeSet, | 4 | ChangeSet, |
@@ -108,7 +108,7 @@ export class XtextClient { | |||
108 | message: issue.description, | 108 | message: issue.description, |
109 | }); | 109 | }); |
110 | }); | 110 | }); |
111 | this.store.dispatch(setDiagnostics(this.store.state, diagnostics)); | 111 | this.store.updateDiagnostics(diagnostics); |
112 | } | 112 | } |
113 | 113 | ||
114 | private computeChangesSinceLastUpdate() { | 114 | private computeChangesSinceLastUpdate() { |