aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/editor
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-12 21:59:50 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-12 21:59:50 +0200
commita2a4696fdbd6440269d576aeba7b25b2ea40d9bf (patch)
tree5cbdf981a51a09fbe162e7748555d213ca518ff4 /subprojects/frontend/src/editor
parentfix: avoid GLOP error message on stderr (diff)
downloadrefinery-a2a4696fdbd6440269d576aeba7b25b2ea40d9bf.tar.gz
refinery-a2a4696fdbd6440269d576aeba7b25b2ea40d9bf.tar.zst
refinery-a2a4696fdbd6440269d576aeba7b25b2ea40d9bf.zip
feat: connect model generator to UI
Diffstat (limited to 'subprojects/frontend/src/editor')
-rw-r--r--subprojects/frontend/src/editor/EditorStore.ts85
-rw-r--r--subprojects/frontend/src/editor/GenerateButton.tsx20
-rw-r--r--subprojects/frontend/src/editor/GeneratedModelStore.ts50
3 files changed, 153 insertions, 2 deletions
diff --git a/subprojects/frontend/src/editor/EditorStore.ts b/subprojects/frontend/src/editor/EditorStore.ts
index b5989ad1..f9a9a7da 100644
--- a/subprojects/frontend/src/editor/EditorStore.ts
+++ b/subprojects/frontend/src/editor/EditorStore.ts
@@ -32,6 +32,7 @@ import type XtextClient from '../xtext/XtextClient';
32import type { SemanticsSuccessResult } from '../xtext/xtextServiceResults'; 32import type { SemanticsSuccessResult } from '../xtext/xtextServiceResults';
33 33
34import EditorErrors from './EditorErrors'; 34import EditorErrors from './EditorErrors';
35import GeneratedModelStore from './GeneratedModelStore';
35import LintPanelStore from './LintPanelStore'; 36import LintPanelStore from './LintPanelStore';
36import SearchPanelStore from './SearchPanelStore'; 37import SearchPanelStore from './SearchPanelStore';
37import createEditorState from './createEditorState'; 38import createEditorState from './createEditorState';
@@ -69,6 +70,10 @@ export default class EditorStore {
69 70
70 graph: GraphStore; 71 graph: GraphStore;
71 72
73 generatedModels = new Map<string, GeneratedModelStore>();
74
75 selectedGeneratedModel: string | undefined;
76
72 constructor(initialValue: string, pwaStore: PWAStore) { 77 constructor(initialValue: string, pwaStore: PWAStore) {
73 this.id = nanoid(); 78 this.id = nanoid();
74 this.state = createEditorState(initialValue, this); 79 this.state = createEditorState(initialValue, this);
@@ -307,4 +312,84 @@ export default class EditorStore {
307 this.delayedErrors.dispose(); 312 this.delayedErrors.dispose();
308 this.disposed = true; 313 this.disposed = true;
309 } 314 }
315
316 startModelGeneration(): void {
317 this.client
318 ?.startModelGeneration()
319 ?.catch((error) => log.error('Could not start model generation', error));
320 }
321
322 addGeneratedModel(uuid: string): void {
323 this.generatedModels.set(uuid, new GeneratedModelStore());
324 this.selectGeneratedModel(uuid);
325 }
326
327 cancelModelGeneration(): void {
328 this.client
329 ?.cancelModelGeneration()
330 ?.catch((error) => log.error('Could not start model generation', error));
331 }
332
333 selectGeneratedModel(uuid: string | undefined): void {
334 if (uuid === undefined) {
335 this.selectedGeneratedModel = uuid;
336 return;
337 }
338 if (this.generatedModels.has(uuid)) {
339 this.selectedGeneratedModel = uuid;
340 return;
341 }
342 this.selectedGeneratedModel = undefined;
343 }
344
345 deleteGeneratedModel(uuid: string | undefined): void {
346 if (uuid === undefined) {
347 return;
348 }
349 if (this.selectedGeneratedModel === uuid) {
350 let previous: string | undefined;
351 let found: string | undefined;
352 this.generatedModels.forEach((_value, key) => {
353 if (key === uuid) {
354 found = previous;
355 }
356 previous = key;
357 });
358 this.selectGeneratedModel(found);
359 }
360 const generatedModel = this.generatedModels.get(uuid);
361 if (generatedModel !== undefined && generatedModel.running) {
362 this.cancelModelGeneration();
363 }
364 this.generatedModels.delete(uuid);
365 }
366
367 modelGenerationCancelled(): void {
368 this.generatedModels.forEach((value) =>
369 value.setError('Model generation cancelled'),
370 );
371 }
372
373 setGeneratedModelMessage(uuid: string, message: string): void {
374 this.generatedModels.get(uuid)?.setMessage(message);
375 }
376
377 setGeneratedModelError(uuid: string, message: string): void {
378 this.generatedModels.get(uuid)?.setError(message);
379 }
380
381 setGeneratedModelSemantics(
382 uuid: string,
383 semantics: SemanticsSuccessResult,
384 ): void {
385 this.generatedModels.get(uuid)?.setSemantics(semantics);
386 }
387
388 get generating(): boolean {
389 let generating = false;
390 this.generatedModels.forEach((value) => {
391 generating = generating || value.running;
392 });
393 return generating;
394 }
310} 395}
diff --git a/subprojects/frontend/src/editor/GenerateButton.tsx b/subprojects/frontend/src/editor/GenerateButton.tsx
index 5bac0464..b8dcd531 100644
--- a/subprojects/frontend/src/editor/GenerateButton.tsx
+++ b/subprojects/frontend/src/editor/GenerateButton.tsx
@@ -5,6 +5,7 @@
5 */ 5 */
6 6
7import CancelIcon from '@mui/icons-material/Cancel'; 7import CancelIcon from '@mui/icons-material/Cancel';
8import CloseIcon from '@mui/icons-material/Close';
8import PlayArrowIcon from '@mui/icons-material/PlayArrow'; 9import PlayArrowIcon from '@mui/icons-material/PlayArrow';
9import { observer } from 'mobx-react-lite'; 10import { observer } from 'mobx-react-lite';
10 11
@@ -28,8 +29,10 @@ const GenerateButton = observer(function GenerateButton({
28 ); 29 );
29 } 30 }
30 31
31 const { analyzing, errorCount, warningCount, semanticsError } = 32 const {
32 editorStore.delayedErrors; 33 delayedErrors: { analyzing, errorCount, warningCount, semanticsError },
34 generating,
35 } = editorStore;
33 36
34 if (analyzing) { 37 if (analyzing) {
35 return ( 38 return (
@@ -39,6 +42,18 @@ const GenerateButton = observer(function GenerateButton({
39 ); 42 );
40 } 43 }
41 44
45 if (generating) {
46 return (
47 <AnimatedButton
48 color="inherit"
49 onClick={() => editorStore.cancelModelGeneration()}
50 startIcon={<CloseIcon />}
51 >
52 Cancel
53 </AnimatedButton>
54 );
55 }
56
42 if (semanticsError !== undefined && editorStore.opened) { 57 if (semanticsError !== undefined && editorStore.opened) {
43 return ( 58 return (
44 <AnimatedButton 59 <AnimatedButton
@@ -83,6 +98,7 @@ const GenerateButton = observer(function GenerateButton({
83 disabled={!editorStore.opened} 98 disabled={!editorStore.opened}
84 color={warningCount > 0 ? 'warning' : 'primary'} 99 color={warningCount > 0 ? 'warning' : 'primary'}
85 startIcon={<PlayArrowIcon />} 100 startIcon={<PlayArrowIcon />}
101 onClick={() => editorStore.startModelGeneration()}
86 > 102 >
87 {summary === '' ? GENERATE_LABEL : `${GENERATE_LABEL} (${summary})`} 103 {summary === '' ? GENERATE_LABEL : `${GENERATE_LABEL} (${summary})`}
88 </AnimatedButton> 104 </AnimatedButton>
diff --git a/subprojects/frontend/src/editor/GeneratedModelStore.ts b/subprojects/frontend/src/editor/GeneratedModelStore.ts
new file mode 100644
index 00000000..d0181eed
--- /dev/null
+++ b/subprojects/frontend/src/editor/GeneratedModelStore.ts
@@ -0,0 +1,50 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6
7import { makeAutoObservable } from 'mobx';
8
9import GraphStore from '../graph/GraphStore';
10import type { SemanticsSuccessResult } from '../xtext/xtextServiceResults';
11
12export default class GeneratedModelStore {
13 title: string;
14
15 message = 'Waiting for server';
16
17 error = false;
18
19 graph: GraphStore | undefined;
20
21 constructor() {
22 const time = new Date().toLocaleTimeString(undefined, { hour12: false });
23 this.title = `Generated at ${time}`;
24 makeAutoObservable(this);
25 }
26
27 get running(): boolean {
28 return !this.error && this.graph === undefined;
29 }
30
31 setMessage(message: string): void {
32 if (this.running) {
33 this.message = message;
34 }
35 }
36
37 setError(message: string): void {
38 if (this.running) {
39 this.error = true;
40 this.message = message;
41 }
42 }
43
44 setSemantics(semantics: SemanticsSuccessResult): void {
45 if (this.running) {
46 this.graph = new GraphStore();
47 this.graph.setSemantics(semantics);
48 }
49 }
50}