@finos/legend-application-studio 28.19.73 → 28.19.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/lib/components/editor/__test-utils__/EditorComponentTestUtils.d.ts.map +1 -1
  2. package/lib/components/editor/__test-utils__/EditorComponentTestUtils.js +4 -0
  3. package/lib/components/editor/__test-utils__/EditorComponentTestUtils.js.map +1 -1
  4. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.d.ts.map +1 -1
  5. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js +26 -338
  6. package/lib/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.js.map +1 -1
  7. package/lib/components/editor/panel-group/SQLPlaygroundPanel.d.ts.map +1 -1
  8. package/lib/components/editor/panel-group/SQLPlaygroundPanel.js +9 -298
  9. package/lib/components/editor/panel-group/SQLPlaygroundPanel.js.map +1 -1
  10. package/lib/components/editor/side-bar/Explorer.js +1 -1
  11. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  12. package/lib/index.css +2 -2
  13. package/lib/index.css.map +1 -1
  14. package/lib/package.json +1 -1
  15. package/lib/stores/editor/EditorGraphState.d.ts.map +1 -1
  16. package/lib/stores/editor/EditorGraphState.js +1 -7
  17. package/lib/stores/editor/EditorGraphState.js.map +1 -1
  18. package/lib/stores/editor/EditorStore.d.ts +2 -2
  19. package/lib/stores/editor/EditorStore.d.ts.map +1 -1
  20. package/lib/stores/editor/EditorStore.js +3 -3
  21. package/lib/stores/editor/EditorStore.js.map +1 -1
  22. package/lib/stores/editor/GraphEditFormModeState.js +1 -1
  23. package/lib/stores/editor/GraphEditFormModeState.js.map +1 -1
  24. package/lib/stores/editor/__test-utils__/EditorStoreTestUtils.d.ts.map +1 -1
  25. package/lib/stores/editor/__test-utils__/EditorStoreTestUtils.js +4 -0
  26. package/lib/stores/editor/__test-utils__/EditorStoreTestUtils.js.map +1 -1
  27. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.d.ts +0 -2
  28. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.d.ts.map +1 -1
  29. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js +0 -19
  30. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.js.map +1 -1
  31. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.d.ts +1 -16
  32. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.d.ts.map +1 -1
  33. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js +1 -112
  34. package/lib/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.js.map +1 -1
  35. package/lib/stores/editor/panel-group/{SQLPlaygroundPanelState.d.ts → StudioSQLPlaygroundPanelState.d.ts} +8 -15
  36. package/lib/stores/editor/panel-group/StudioSQLPlaygroundPanelState.d.ts.map +1 -0
  37. package/lib/stores/editor/panel-group/{SQLPlaygroundPanelState.js → StudioSQLPlaygroundPanelState.js} +29 -44
  38. package/lib/stores/editor/panel-group/StudioSQLPlaygroundPanelState.js.map +1 -0
  39. package/package.json +13 -13
  40. package/src/components/editor/__test-utils__/EditorComponentTestUtils.tsx +4 -0
  41. package/src/components/editor/editor-group/project-configuration-editor/ProjectDependencyEditor.tsx +53 -599
  42. package/src/components/editor/panel-group/SQLPlaygroundPanel.tsx +12 -576
  43. package/src/components/editor/side-bar/Explorer.tsx +1 -1
  44. package/src/stores/editor/EditorGraphState.ts +4 -11
  45. package/src/stores/editor/EditorStore.ts +3 -3
  46. package/src/stores/editor/GraphEditFormModeState.ts +1 -1
  47. package/src/stores/editor/__test-utils__/EditorStoreTestUtils.ts +4 -1
  48. package/src/stores/editor/editor-state/project-configuration-editor-state/ProjectConfigurationEditorState.ts +0 -26
  49. package/src/stores/editor/editor-state/project-configuration-editor-state/ProjectDependencyEditorState.ts +1 -178
  50. package/src/stores/editor/panel-group/{SQLPlaygroundPanelState.ts → StudioSQLPlaygroundPanelState.ts} +47 -60
  51. package/tsconfig.json +1 -1
  52. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.d.ts.map +0 -1
  53. package/lib/stores/editor/panel-group/SQLPlaygroundPanelState.js.map +0 -1
@@ -25,40 +25,21 @@ import {
25
25
  PURE_ConnectionIcon,
26
26
  BlankPanelPlaceholder,
27
27
  PanelDropZone,
28
- ResizablePanelSplitterLine,
29
- PlayIcon,
30
28
  PanelLoadingIndicator,
31
- BlankPanelContent,
32
29
  PURE_DatabaseIcon,
33
30
  SyncIcon,
34
- clsx,
35
- CheckSquareIcon,
36
- SquareIcon,
37
31
  } from '@finos/legend-art';
38
- import React, { useCallback, useEffect, useRef, useState } from 'react';
32
+ import { useCallback, useEffect, useRef } from 'react';
39
33
  import {
40
34
  useApplicationStore,
41
- useCommands,
42
35
  useConditionedApplicationNavigationContext,
43
36
  } from '@finos/legend-application';
44
37
  import { flowResult } from 'mobx';
45
- import {
46
- CODE_EDITOR_LANGUAGE,
47
- CODE_EDITOR_THEME,
48
- getBaseCodeEditorOptions,
49
- } from '@finos/legend-code-editor';
50
- import {
51
- editor as monacoEditorAPI,
52
- languages as monacoLanguagesAPI,
53
- type IDisposable,
54
- type IPosition,
55
- } from 'monaco-editor';
56
38
  import {
57
39
  PackageableConnection,
58
40
  RelationalDatabaseConnection,
59
41
  } from '@finos/legend-graph';
60
42
  import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../__lib__/LegendStudioApplicationNavigationContext.js';
61
- import { type SQLPlaygroundPanelState } from '../../../stores/editor/panel-group/SQLPlaygroundPanelState.js';
62
43
  import { useEditorStore } from '../EditorStoreProvider.js';
63
44
  import { PANEL_MODE } from '../../../stores/editor/EditorConfig.js';
64
45
  import { useDrag, useDrop } from 'react-dnd';
@@ -66,24 +47,6 @@ import {
66
47
  CORE_DND_TYPE,
67
48
  type ElementDragSource,
68
49
  } from '../../../stores/editor/utils/DnDUtils.js';
69
- import {
70
- DataGrid,
71
- type DataGridCellRendererParams,
72
- type DataGridColumnDefinition,
73
- type DataGridDefaultMenuItem,
74
- type DataGridGetContextMenuItemsParams,
75
- type DataGridMenuItemDef,
76
- } from '@finos/legend-lego/data-grid';
77
- import {
78
- at,
79
- isNonNullable,
80
- isNumber,
81
- isString,
82
- isValidURL,
83
- parseCSVString,
84
- prettyDuration,
85
- uniqBy,
86
- } from '@finos/legend-shared';
87
50
  import {
88
51
  DatabaseSchemaExplorer,
89
52
  DatabaseSchemaExplorerTreeNodeContainer,
@@ -94,6 +57,7 @@ import {
94
57
  buildRelationalDatabaseConnectionOption,
95
58
  type RelationalDatabaseConnectionOption,
96
59
  } from '../editor-group/connection-editor/RelationalDatabaseConnectionEditor.js';
60
+ import { SQLPlaygroundEditorResultPanel } from '@finos/legend-lego/sql-playground';
97
61
 
98
62
  const DATABASE_NODE_DND_TYPE = 'DATABASE_NODE_DND_TYPE';
99
63
  type DatabaseNodeDragType = { text: string };
@@ -121,449 +85,11 @@ const SQLPlaygroundDatabaseSchemaExplorerTreeNodeContainer = observer(
121
85
  },
122
86
  );
123
87
 
124
- // List of most popular SQL keywords
125
- // See https://www.w3schools.com/sql/sql_ref_keywords.asp
126
- const SQL_KEYWORDS = [
127
- 'AND',
128
- 'AS',
129
- 'ASC',
130
- 'BETWEEN',
131
- 'DESC',
132
- 'DISTINCT',
133
- 'EXEC',
134
- 'EXISTS',
135
- 'FROM',
136
- 'FULL OUTER JOIN',
137
- 'GROUP BY',
138
- 'HAVING',
139
- 'IN',
140
- 'INNER JOIN',
141
- 'IS NULL',
142
- 'IS NOT NULL',
143
- 'JOIN',
144
- 'LEFT JOIN',
145
- 'LIKE',
146
- 'LIMIT',
147
- 'NOT',
148
- 'NOT NULL',
149
- 'OR',
150
- 'ORDER BY',
151
- 'OUTER JOIN',
152
- 'RIGHT JOIN',
153
- 'SELECT',
154
- 'SELECT DISTINCT',
155
- 'SELECT INTO',
156
- 'SELECT TOP',
157
- 'TOP',
158
- 'UNION',
159
- 'UNION ALL',
160
- 'UNIQUE',
161
- 'WHERE',
162
- ];
163
-
164
- const getKeywordSuggestions = async (
165
- position: IPosition,
166
- model: monacoEditorAPI.ITextModel,
167
- ): Promise<monacoLanguagesAPI.CompletionItem[]> =>
168
- SQL_KEYWORDS.map(
169
- (keyword) =>
170
- ({
171
- label: keyword,
172
- kind: monacoLanguagesAPI.CompletionItemKind.Keyword,
173
- insertTextRules:
174
- monacoLanguagesAPI.CompletionItemInsertTextRule.InsertAsSnippet,
175
- insertText: `${keyword} `,
176
- }) as monacoLanguagesAPI.CompletionItem,
177
- );
178
-
179
- const getDatabaseSchemaEntities = async (
180
- position: IPosition,
181
- model: monacoEditorAPI.ITextModel,
182
- playgroundState: SQLPlaygroundPanelState,
183
- ): Promise<monacoLanguagesAPI.CompletionItem[]> => {
184
- if (playgroundState.schemaExplorerState?.treeData) {
185
- return uniqBy(
186
- Array.from(
187
- playgroundState.schemaExplorerState.treeData.nodes.values(),
188
- ).map(
189
- (value) =>
190
- ({
191
- label: value.label,
192
- kind: monacoLanguagesAPI.CompletionItemKind.Field,
193
- insertTextRules:
194
- monacoLanguagesAPI.CompletionItemInsertTextRule.InsertAsSnippet,
195
- insertText: `${value.label} `,
196
- }) as monacoLanguagesAPI.CompletionItem,
197
- ),
198
- (val) => val.label,
199
- );
200
- }
201
- return [];
202
- };
203
-
204
- const PlaygroundSQLCodeEditor = observer(() => {
205
- const editorStore = useEditorStore();
206
- const playgroundState = editorStore.sqlPlaygroundState;
207
- const applicationStore = useApplicationStore();
208
- const codeEditorRef = useRef<HTMLDivElement>(null);
209
- const [editor, setEditor] = useState<
210
- monacoEditorAPI.IStandaloneCodeEditor | undefined
211
- >();
212
- const sqlIdentifierSuggestionProviderDisposer = useRef<
213
- IDisposable | undefined
214
- >(undefined);
215
-
216
- useEffect(() => {
217
- if (!editor && codeEditorRef.current) {
218
- const element = codeEditorRef.current;
219
- const newEditor = monacoEditorAPI.create(element, {
220
- ...getBaseCodeEditorOptions(),
221
- theme: CODE_EDITOR_THEME.DEFAULT_DARK,
222
- language: CODE_EDITOR_LANGUAGE.SQL,
223
- padding: {
224
- top: 10,
225
- },
226
- });
227
-
228
- newEditor.onDidChangeModelContent(() => {
229
- const currentVal = newEditor.getValue();
230
- playgroundState.setSQLText(currentVal);
231
- });
232
-
233
- // Restore the editor model and view state
234
- newEditor.setModel(playgroundState.sqlEditorTextModel);
235
- if (playgroundState.sqlEditorViewState) {
236
- newEditor.restoreViewState(playgroundState.sqlEditorViewState);
237
- }
238
- newEditor.focus(); // focus on the editor initially
239
- playgroundState.setSQLEditor(newEditor);
240
- setEditor(newEditor);
241
- }
242
- }, [playgroundState, applicationStore, editor]);
243
-
244
- useCommands(playgroundState);
245
-
246
- if (editor) {
247
- sqlIdentifierSuggestionProviderDisposer.current?.dispose();
248
- sqlIdentifierSuggestionProviderDisposer.current =
249
- monacoLanguagesAPI.registerCompletionItemProvider(
250
- CODE_EDITOR_LANGUAGE.SQL,
251
- {
252
- triggerCharacters: [],
253
- provideCompletionItems: async (model, position, context) => {
254
- let suggestions: monacoLanguagesAPI.CompletionItem[] = [];
255
- if (
256
- context.triggerKind ===
257
- monacoLanguagesAPI.CompletionTriggerKind.Invoke
258
- ) {
259
- // keywords
260
- suggestions = suggestions.concat(
261
- await getKeywordSuggestions(position, model),
262
- );
263
-
264
- // database schema entities
265
- suggestions = suggestions.concat(
266
- await getDatabaseSchemaEntities(
267
- position,
268
- model,
269
- playgroundState,
270
- ),
271
- );
272
- }
273
-
274
- return { suggestions };
275
- },
276
- },
277
- );
278
- }
279
-
280
- // clean up
281
- useEffect(
282
- () => (): void => {
283
- if (editor) {
284
- // persist editor view state (cursor, scroll, etc.) to restore on re-open
285
- playgroundState.setSQLEditorViewState(
286
- editor.saveViewState() ?? undefined,
287
- );
288
- editor.dispose();
289
-
290
- // Dispose the providers properly to avoid ending up with duplicated suggestions
291
- sqlIdentifierSuggestionProviderDisposer.current?.dispose();
292
- }
293
- },
294
- [playgroundState, editor],
295
- );
296
-
297
- const handleDatabaseNodeDrop = useCallback(
298
- (item: DatabaseNodeDragType): void => {
299
- if (isString(item.text)) {
300
- if (playgroundState.sqlEditor) {
301
- const currentValue = playgroundState.sqlEditorTextModel.getValue();
302
- const lines = currentValue.split('\n');
303
- const position = playgroundState.sqlEditor.getPosition() ?? {
304
- lineNumber: lines.length,
305
- column: lines.at(-1)?.length ?? 0,
306
- };
307
- playgroundState.sqlEditor.executeEdits('', [
308
- {
309
- range: {
310
- startLineNumber: position.lineNumber,
311
- startColumn: position.column,
312
- endLineNumber: position.lineNumber,
313
- endColumn: position.column,
314
- },
315
- text: item.text,
316
- forceMoveMarkers: true,
317
- },
318
- ]);
319
- playgroundState.setSQLText(
320
- playgroundState.sqlEditorTextModel.getValue(),
321
- );
322
- }
323
- }
324
- },
325
- [playgroundState],
326
- );
327
- const [{ isDatabaseNodeDragOver }, dropConnector] = useDrop<
328
- DatabaseNodeDragType,
329
- void,
330
- { isDatabaseNodeDragOver: boolean }
331
- >(
332
- () => ({
333
- accept: DATABASE_NODE_DND_TYPE,
334
- drop: (item): void => handleDatabaseNodeDrop(item),
335
- collect: (monitor) => ({
336
- isDatabaseNodeDragOver: monitor.isOver({ shallow: true }),
337
- }),
338
- }),
339
- [handleDatabaseNodeDrop],
340
- );
341
-
342
- return (
343
- <div className="sql-playground__code-editor">
344
- <PanelDropZone
345
- className="sql-playground__code-editor__content"
346
- isDragOver={isDatabaseNodeDragOver}
347
- dropTargetConnector={dropConnector}
348
- >
349
- <div className="code-editor__container">
350
- <div className="code-editor__body" ref={codeEditorRef} />
351
- </div>
352
- </PanelDropZone>
353
- </div>
354
- );
355
- });
356
-
357
- const parseExecutionResultData = (
358
- data: string,
359
- ): { rowData: Record<string, string>[]; columns: string[] } | undefined => {
360
- const lines = data.split('\n').filter((line) => line.trim().length);
361
- if (lines.length) {
362
- const columns = parseCSVString(at(lines, 0)) ?? [];
363
- const rowData = lines
364
- .slice(1)
365
- .map((item) => {
366
- const rowItems = parseCSVString(item);
367
- if (!rowItems) {
368
- return undefined;
369
- }
370
- const row: Record<string, string> = {};
371
- columns.forEach((column, idx) => {
372
- row[column] = rowItems[idx] ?? '';
373
- });
374
- return row;
375
- })
376
- .filter(isNonNullable);
377
- return { rowData, columns };
378
- }
379
- return undefined;
380
- };
381
-
382
- const TDSResultCellRenderer = observer((params: DataGridCellRendererParams) => {
383
- const cellValue = params.value as string;
384
- const formattedCellValue = (): string => {
385
- if (isNumber(cellValue)) {
386
- return Intl.NumberFormat('en-US', {
387
- maximumFractionDigits: 4,
388
- }).format(Number(cellValue));
389
- }
390
- return cellValue;
391
- };
392
- const cellValueUrlLink =
393
- isString(cellValue) && isValidURL(cellValue) ? cellValue : undefined;
394
-
395
- return (
396
- <div className={clsx('query-builder__result__values__table__cell')}>
397
- {cellValueUrlLink ? (
398
- <a href={cellValueUrlLink} target="_blank" rel="noreferrer">
399
- {cellValueUrlLink}
400
- </a>
401
- ) : (
402
- <span>{formattedCellValue()}</span>
403
- )}
404
- </div>
405
- );
406
- });
407
-
408
- const PlayGroundSQLExecutionResultGrid = observer(
409
- (props: {
410
- result: string;
411
- useAdvancedGrid?: boolean;
412
- useLocalMode?: boolean;
413
- }) => {
414
- const { result, useAdvancedGrid, useLocalMode } = props;
415
- const data = parseExecutionResultData(result);
416
- const applicationStore = useApplicationStore();
417
- const darkMode =
418
- !applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled;
419
-
420
- if (!data) {
421
- return (
422
- <BlankPanelContent>{`Can't parse result, displaying raw form:\n${result}`}</BlankPanelContent>
423
- );
424
- }
425
- if (useAdvancedGrid) {
426
- if (useLocalMode) {
427
- const localcolDefs = data.columns.map(
428
- (colName) =>
429
- ({
430
- minWidth: 50,
431
- sortable: true,
432
- resizable: true,
433
- field: colName,
434
- flex: 1,
435
- enablePivot: true,
436
- enableRowGroup: true,
437
- enableValue: true,
438
- allowedAggFuncs: ['count'],
439
- }) as DataGridColumnDefinition,
440
- );
441
-
442
- return (
443
- <div
444
- className={clsx('sql-playground__result__grid', {
445
- 'ag-theme-balham': !darkMode,
446
- 'ag-theme-balham-dark': darkMode,
447
- })}
448
- >
449
- <DataGrid
450
- rowData={data.rowData}
451
- gridOptions={{
452
- suppressScrollOnNewData: true,
453
- rowSelection: {
454
- mode: 'multiRow',
455
- checkboxes: false,
456
- headerCheckbox: false,
457
- },
458
- pivotPanelShow: 'always',
459
- rowGroupPanelShow: 'always',
460
- cellSelection: true,
461
- }}
462
- // NOTE: when column definition changed, we need to force refresh the cell to make sure the cell renderer is updated
463
- // See https://stackoverflow.com/questions/56341073/how-to-refresh-an-ag-grid-when-a-change-occurs-inside-a-custom-cell-renderer-com
464
- onRowDataUpdated={(params) => {
465
- params.api.refreshCells({ force: true });
466
- }}
467
- suppressFieldDotNotation={true}
468
- suppressContextMenu={false}
469
- columnDefs={localcolDefs}
470
- sideBar={['columns', 'filters']}
471
- />
472
- </div>
473
- );
474
- }
475
- const colDefs = data.columns.map(
476
- (colName) =>
477
- ({
478
- minWidth: 50,
479
- sortable: true,
480
- resizable: true,
481
- field: colName,
482
- flex: 1,
483
- cellRenderer: TDSResultCellRenderer,
484
- filter: true,
485
- }) as DataGridColumnDefinition,
486
- );
487
- const getContextMenuItems = useCallback(
488
- (
489
- params: DataGridGetContextMenuItemsParams<{
490
- [key: string]: string;
491
- }>,
492
- ): (DataGridDefaultMenuItem | DataGridMenuItemDef)[] => [
493
- 'copy',
494
- 'copyWithHeaders',
495
- {
496
- name: 'Copy Row Value',
497
- action: () => {
498
- params.api.copySelectedRowsToClipboard();
499
- },
500
- },
501
- ],
502
- [],
503
- );
504
- return (
505
- <div
506
- className={clsx('sql-playground__result__grid', {
507
- 'ag-theme-balham': !darkMode,
508
- 'ag-theme-balham-dark': darkMode,
509
- })}
510
- >
511
- <DataGrid
512
- rowData={data.rowData}
513
- overlayNoRowsTemplate={`<div class="sql-playground__result__grid--empty">No results</div>`}
514
- gridOptions={{
515
- suppressScrollOnNewData: true,
516
- rowSelection: {
517
- mode: 'multiRow',
518
- checkboxes: false,
519
- headerCheckbox: false,
520
- },
521
- cellSelection: true,
522
- }}
523
- onRowDataUpdated={(params) => {
524
- params.api.refreshCells({ force: true });
525
- }}
526
- suppressFieldDotNotation={true}
527
- suppressClipboardPaste={false}
528
- suppressContextMenu={false}
529
- columnDefs={colDefs}
530
- getContextMenuItems={(params) => getContextMenuItems(params)}
531
- />
532
- </div>
533
- );
534
- }
535
-
536
- return (
537
- <div
538
- className={clsx('sql-playground__result__grid', {
539
- 'ag-theme-balham': !darkMode,
540
- 'ag-theme-balham-dark': darkMode,
541
- })}
542
- >
543
- <DataGrid
544
- rowData={data.rowData}
545
- overlayNoRowsTemplate={`<div class="sql-playground__result__grid--empty">No results</div>`}
546
- alwaysShowVerticalScroll={true}
547
- suppressFieldDotNotation={true}
548
- columnDefs={data.columns.map((column) => ({
549
- minWidth: 50,
550
- sortable: true,
551
- resizable: true,
552
- headerName: column,
553
- field: column,
554
- flex: 1,
555
- }))}
556
- />
557
- </div>
558
- );
559
- },
560
- );
561
-
562
88
  type SQLPlaygroundPanelDropTarget = ElementDragSource;
563
89
 
564
90
  export const SQLPlaygroundPanel = observer(() => {
565
91
  const editorStore = useEditorStore();
566
- const playgroundState = editorStore.sqlPlaygroundState;
92
+ const playgroundState = editorStore.studioSqlPlaygroundState;
567
93
  const applicationStore = useApplicationStore();
568
94
 
569
95
  // connection
@@ -640,26 +166,6 @@ export const SQLPlaygroundPanel = observer(() => {
640
166
  }
641
167
  };
642
168
 
643
- const executeRawSQL = (): void => {
644
- flowResult(playgroundState.executeRawSQL()).catch(
645
- applicationStore.alertUnhandledError,
646
- );
647
- };
648
- const advancedMode = Boolean(
649
- editorStore.applicationStore.config.options.queryBuilderConfig
650
- ?.TEMPORARY__enableGridEnterpriseMode,
651
- );
652
- const resultDescription = playgroundState.sqlExecutionResult
653
- ? `query ran in ${prettyDuration(
654
- playgroundState.sqlExecutionResult.sqlDuration,
655
- {
656
- ms: true,
657
- },
658
- )}`
659
- : undefined;
660
- const toggleocalMode = (): void => {
661
- playgroundState.toggleIsLocalModeEnabled();
662
- };
663
169
  useEffect(() => {
664
170
  if (playgroundState.schemaExplorerState) {
665
171
  flowResult(
@@ -668,6 +174,10 @@ export const SQLPlaygroundPanel = observer(() => {
668
174
  }
669
175
  }, [playgroundState, applicationStore, playgroundState.schemaExplorerState]);
670
176
 
177
+ useEffect(() => {
178
+ playgroundState.fetchSchemaMetaData();
179
+ }, [playgroundState]);
180
+
671
181
  useConditionedApplicationNavigationContext(
672
182
  LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.SQL_PLAYGROUND,
673
183
  editorStore.activePanelMode === PANEL_MODE.SQL_PLAYGROUND,
@@ -749,85 +259,11 @@ export const SQLPlaygroundPanel = observer(() => {
749
259
  <ResizablePanelSplitter />
750
260
  <ResizablePanel>
751
261
  <div className="panel sql-playground__sql-editor">
752
- <ResizablePanelGroup orientation="horizontal">
753
- <ResizablePanel>
754
- <PlaygroundSQLCodeEditor />
755
- </ResizablePanel>
756
- <ResizablePanelSplitter>
757
- <ResizablePanelSplitterLine color="var(--color-dark-grey-250)" />
758
- </ResizablePanelSplitter>
759
- <ResizablePanel size={300}>
760
- <div className="panel__header">
761
- <div className="panel__header__title">
762
- <div className="panel__header__title__label">
763
- result
764
- </div>
765
-
766
- {playgroundState.executeRawSQLState.isInProgress && (
767
- <div className="panel__header__title__label__status">
768
- Running SQL...
769
- </div>
770
- )}
771
-
772
- <div className="query-builder__result__analytics">
773
- {resultDescription ?? ''}
774
- </div>
775
- </div>
776
- <div className="panel__header__actions query-builder__result__header__actions">
777
- {advancedMode && (
778
- <div className="query-builder__result__advanced__mode">
779
- <div className="query-builder__result__advanced__mode__label">
780
- Local Mode
781
- </div>
782
- <button
783
- className={clsx(
784
- 'query-builder__result__advanced__mode__toggler__btn',
785
- {
786
- 'query-builder__result__advanced__mode__toggler__btn--toggled':
787
- playgroundState.isLocalModeEnabled,
788
- },
789
- )}
790
- onClick={toggleocalMode}
791
- tabIndex={-1}
792
- >
793
- {playgroundState.isLocalModeEnabled ? (
794
- <CheckSquareIcon />
795
- ) : (
796
- <SquareIcon />
797
- )}
798
- </button>
799
- </div>
800
- )}
801
-
802
- <div className="query-builder__result__execute-btn btn__dropdown-combo btn__dropdown-combo--primary">
803
- <button
804
- className="btn__dropdown-combo__label"
805
- onClick={executeRawSQL}
806
- disabled={
807
- playgroundState.executeRawSQLState.isInProgress
808
- }
809
- tabIndex={-1}
810
- >
811
- <PlayIcon className="btn__dropdown-combo__label__icon" />
812
- <div className="btn__dropdown-combo__label__title">
813
- Run Query
814
- </div>
815
- </button>
816
- </div>
817
- </div>
818
- </div>
819
- {playgroundState.sqlExecutionResult !== undefined && (
820
- <PlayGroundSQLExecutionResultGrid
821
- result={playgroundState.sqlExecutionResult.value}
822
- useAdvancedGrid={advancedMode}
823
- useLocalMode={playgroundState.isLocalModeEnabled}
824
- />
825
- )}
826
- {playgroundState.sqlExecutionResult === undefined && (
827
- <div />
828
- )}
829
- </ResizablePanel>
830
- </ResizablePanelGroup>
262
+ <SQLPlaygroundEditorResultPanel
263
+ playgroundState={playgroundState}
264
+ advancedMode={true}
265
+ enableDarkMode={true}
266
+ />
831
267
  </div>
832
268
  </ResizablePanel>
833
269
  </ResizablePanelGroup>
@@ -618,7 +618,7 @@ const ExplorerContextMenu = observer(
618
618
  if (isRelationalDatabaseConnection(node?.packageableElement)) {
619
619
  editorStore.panelGroupDisplayState.open();
620
620
  editorStore.setActivePanelMode(PANEL_MODE.SQL_PLAYGROUND);
621
- editorStore.sqlPlaygroundState.setConnection(
621
+ editorStore.studioSqlPlaygroundState.setConnection(
622
622
  guaranteeType(node?.packageableElement, PackageableConnection),
623
623
  );
624
624
  }
@@ -799,22 +799,15 @@ export class EditorGraphState {
799
799
  projectDependencies: ProjectDependency[],
800
800
  ): Promise<ProjectDependencyCoordinates[]> {
801
801
  return Promise.all(
802
- projectDependencies.map(async (dep) => {
803
- const exclusionCoordinates = (dep.exclusions ?? []).map(
804
- (exclusion) => ({
805
- groupId: guaranteeNonNullable(exclusion.groupId),
806
- artifactId: guaranteeNonNullable(exclusion.artifactId),
807
- }),
808
- );
809
- return Promise.resolve(
802
+ projectDependencies.map(async (dep) =>
803
+ Promise.resolve(
810
804
  new ProjectDependencyCoordinates(
811
805
  guaranteeNonNullable(dep.groupId),
812
806
  guaranteeNonNullable(dep.artifactId),
813
807
  dep.versionId,
814
- exclusionCoordinates.length > 0 ? exclusionCoordinates : undefined,
815
808
  ),
816
- );
817
- }),
809
+ ),
810
+ ),
818
811
  );
819
812
  }
820
813