@finos/legend-query-builder 0.3.1 → 0.4.0

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 (105) hide show
  1. package/lib/components/QueryBuilder.d.ts.map +1 -1
  2. package/lib/components/QueryBuilder.js +24 -20
  3. package/lib/components/QueryBuilder.js.map +1 -1
  4. package/lib/components/QueryBuilderParametersPanel.d.ts.map +1 -1
  5. package/lib/components/QueryBuilderParametersPanel.js +4 -8
  6. package/lib/components/QueryBuilderParametersPanel.js.map +1 -1
  7. package/lib/components/QueryBuilderPropertyExpressionEditor.d.ts.map +1 -1
  8. package/lib/components/QueryBuilderPropertyExpressionEditor.js +2 -2
  9. package/lib/components/QueryBuilderPropertyExpressionEditor.js.map +1 -1
  10. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  11. package/lib/components/QueryBuilderResultPanel.js +4 -2
  12. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  13. package/lib/components/QueryBuilderTextEditor.d.ts.map +1 -1
  14. package/lib/components/QueryBuilderTextEditor.js +4 -4
  15. package/lib/components/QueryBuilderTextEditor.js.map +1 -1
  16. package/lib/components/explorer/QueryBuilderExplorerPanel.d.ts.map +1 -1
  17. package/lib/components/explorer/QueryBuilderExplorerPanel.js +3 -3
  18. package/lib/components/explorer/QueryBuilderExplorerPanel.js.map +1 -1
  19. package/lib/components/explorer/QueryBuilderMilestoningEditor.d.ts.map +1 -1
  20. package/lib/components/explorer/QueryBuilderMilestoningEditor.js +6 -6
  21. package/lib/components/explorer/QueryBuilderMilestoningEditor.js.map +1 -1
  22. package/lib/components/fetch-structure/QueryBuilderOlapGroupByPanel.d.ts.map +1 -1
  23. package/lib/components/fetch-structure/QueryBuilderOlapGroupByPanel.js +6 -6
  24. package/lib/components/fetch-structure/QueryBuilderOlapGroupByPanel.js.map +1 -1
  25. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  26. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +3 -3
  27. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  28. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  29. package/lib/components/shared/LambdaEditor.js +3 -3
  30. package/lib/components/shared/LambdaEditor.js.map +1 -1
  31. package/lib/components/shared/LambdaParameterValuesEditor.d.ts.map +1 -1
  32. package/lib/components/shared/LambdaParameterValuesEditor.js +3 -3
  33. package/lib/components/shared/LambdaParameterValuesEditor.js.map +1 -1
  34. package/lib/components/watermark/QueryBuilderWatermark.d.ts +23 -0
  35. package/lib/components/watermark/QueryBuilderWatermark.d.ts.map +1 -0
  36. package/lib/components/watermark/QueryBuilderWatermark.js +67 -0
  37. package/lib/components/watermark/QueryBuilderWatermark.js.map +1 -0
  38. package/lib/graphManager/QueryBuilderHashUtils.d.ts +1 -0
  39. package/lib/graphManager/QueryBuilderHashUtils.d.ts.map +1 -1
  40. package/lib/graphManager/QueryBuilderHashUtils.js +2 -0
  41. package/lib/graphManager/QueryBuilderHashUtils.js.map +1 -1
  42. package/lib/graphManager/QueryBuilderSupportedFunctions.d.ts +1 -0
  43. package/lib/graphManager/QueryBuilderSupportedFunctions.d.ts.map +1 -1
  44. package/lib/graphManager/QueryBuilderSupportedFunctions.js +2 -0
  45. package/lib/graphManager/QueryBuilderSupportedFunctions.js.map +1 -1
  46. package/lib/graphManager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.d.ts.map +1 -1
  47. package/lib/graphManager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.js +4 -1
  48. package/lib/graphManager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.js.map +1 -1
  49. package/lib/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts +1 -0
  50. package/lib/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts.map +1 -1
  51. package/lib/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js +29 -2
  52. package/lib/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js.map +1 -1
  53. package/lib/index.css +2 -2
  54. package/lib/index.css.map +1 -1
  55. package/lib/package.json +1 -1
  56. package/lib/stores/QueryBuilderState.d.ts +4 -0
  57. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  58. package/lib/stores/QueryBuilderState.js +12 -0
  59. package/lib/stores/QueryBuilderState.js.map +1 -1
  60. package/lib/stores/QueryBuilderStateBuilder.d.ts.map +1 -1
  61. package/lib/stores/QueryBuilderStateBuilder.js +12 -1
  62. package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
  63. package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts.map +1 -1
  64. package/lib/stores/QueryBuilderValueSpecificationBuilder.js +7 -1
  65. package/lib/stores/QueryBuilderValueSpecificationBuilder.js.map +1 -1
  66. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts.map +1 -1
  67. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js +2 -1
  68. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js.map +1 -1
  69. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts +31 -0
  70. package/lib/stores/watermark/QueryBuilderWatermarkState.d.ts.map +1 -0
  71. package/lib/stores/watermark/QueryBuilderWatermarkState.js +69 -0
  72. package/lib/stores/watermark/QueryBuilderWatermarkState.js.map +1 -0
  73. package/lib/stores/watermark/QueryBuilderWatermarkStateBuilder.d.ts +19 -0
  74. package/lib/stores/watermark/QueryBuilderWatermarkStateBuilder.d.ts.map +1 -0
  75. package/lib/stores/watermark/QueryBuilderWatermarkStateBuilder.js +30 -0
  76. package/lib/stores/watermark/QueryBuilderWatermarkStateBuilder.js.map +1 -0
  77. package/lib/stores/watermark/QueryBuilderWatermarkValueSpecificationBuilder.d.ts +19 -0
  78. package/lib/stores/watermark/QueryBuilderWatermarkValueSpecificationBuilder.d.ts.map +1 -0
  79. package/lib/stores/watermark/QueryBuilderWatermarkValueSpecificationBuilder.js +30 -0
  80. package/lib/stores/watermark/QueryBuilderWatermarkValueSpecificationBuilder.js.map +1 -0
  81. package/package.json +4 -4
  82. package/src/components/QueryBuilder.tsx +141 -109
  83. package/src/components/QueryBuilderParametersPanel.tsx +27 -35
  84. package/src/components/QueryBuilderPropertyExpressionEditor.tsx +16 -11
  85. package/src/components/QueryBuilderResultPanel.tsx +18 -0
  86. package/src/components/QueryBuilderTextEditor.tsx +22 -17
  87. package/src/components/explorer/QueryBuilderExplorerPanel.tsx +16 -11
  88. package/src/components/explorer/QueryBuilderMilestoningEditor.tsx +27 -18
  89. package/src/components/fetch-structure/QueryBuilderOlapGroupByPanel.tsx +22 -18
  90. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +11 -9
  91. package/src/components/shared/LambdaEditor.tsx +20 -17
  92. package/src/components/shared/LambdaParameterValuesEditor.tsx +17 -10
  93. package/src/components/watermark/QueryBuilderWatermark.tsx +185 -0
  94. package/src/graphManager/QueryBuilderHashUtils.ts +3 -0
  95. package/src/graphManager/QueryBuilderSupportedFunctions.ts +2 -0
  96. package/src/graphManager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.ts +14 -0
  97. package/src/graphManager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts +76 -0
  98. package/src/stores/QueryBuilderState.ts +14 -0
  99. package/src/stores/QueryBuilderStateBuilder.ts +17 -1
  100. package/src/stores/QueryBuilderValueSpecificationBuilder.ts +11 -1
  101. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.ts +2 -1
  102. package/src/stores/watermark/QueryBuilderWatermarkState.ts +114 -0
  103. package/src/stores/watermark/QueryBuilderWatermarkStateBuilder.ts +50 -0
  104. package/src/stores/watermark/QueryBuilderWatermarkValueSpecificationBuilder.ts +46 -0
  105. package/tsconfig.json +4 -0
@@ -30,6 +30,7 @@ import {
30
30
  CheckIcon,
31
31
  CaretDownIcon,
32
32
  DiffIcon,
33
+ WaterDropIcon,
33
34
  } from '@finos/legend-art';
34
35
  import { QueryBuilderFilterPanel } from './filter/QueryBuilderFilterPanel.js';
35
36
  import { QueryBuilderExplorerPanel } from './explorer/QueryBuilderExplorerPanel.js';
@@ -54,6 +55,7 @@ import { QueryBuilderDiffViewPanel } from './QueryBuilderDiffPanel.js';
54
55
  import { guaranteeType } from '@finos/legend-shared';
55
56
  import { QueryBuilderGraphFetchTreeState } from '../stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js';
56
57
  import { QueryBuilderPostTDSPanel } from './fetch-structure/QueryBuilderPostTDSPanel.js';
58
+ import { QueryBuilderWatermarkEditor } from './watermark/QueryBuilderWatermark.js';
57
59
 
58
60
  export const QUERY_BUILDER_BACKDROP_CONTAINER_ID =
59
61
  'query-builder.backdrop-container';
@@ -200,6 +202,10 @@ export const QueryBuilder = observer(
200
202
  }
201
203
  };
202
204
 
205
+ const openWatermark = (): void => {
206
+ queryBuilderState.watermarkState.setIsEditingWatermark(true);
207
+ };
208
+
203
209
  useCommands(queryBuilderState);
204
210
  const toggleShowOlapGroupByPanel = (): void => {
205
211
  if (isTDSState) {
@@ -241,127 +247,153 @@ export const QueryBuilder = observer(
241
247
  <div className="query-builder__body">
242
248
  <div className="query-builder__content">
243
249
  <div className="query-builder__sub-header">
244
- <div className="query-builder__sub-header__actions">
245
- <DropdownMenu
246
- className="query-builder__sub-header__custom-action"
247
- title="Show Advanced Menu..."
248
- content={
249
- <MenuContent>
250
- <MenuContentItem
251
- onClick={toggleShowFunctionPanel}
252
- disabled={!queryBuilderState.isQuerySupported}
253
- >
254
- <MenuContentItemIcon>
255
- {queryBuilderState.showFunctionsExplorerPanel ? (
256
- <CheckIcon />
257
- ) : null}
258
- </MenuContentItemIcon>
259
- <MenuContentItemLabel className="query-builder__sub-header__menu-content">
260
- Show Function(s)
261
- </MenuContentItemLabel>
262
- </MenuContentItem>
263
- {/* TODO?: consider hiding this menu option when the fetch-structure is not TDS */}
264
- {!queryBuilderState.isParameterSupportDisabled && (
250
+ <div className="query-builder__sub-header__content__icons">
251
+ {queryBuilderState.watermarkState.value && (
252
+ <>
253
+ <button
254
+ className="panel__header__action"
255
+ onClick={openWatermark}
256
+ tabIndex={-1}
257
+ title="Edit Watermark"
258
+ >
259
+ <WaterDropIcon />
260
+ </button>
261
+ </>
262
+ )}
263
+ {queryBuilderState.watermarkState.isEditingWatermark && (
264
+ <QueryBuilderWatermarkEditor
265
+ queryBuilderState={queryBuilderState}
266
+ />
267
+ )}
268
+ </div>
269
+ <div className="query-builder__sub-header__content__actions">
270
+ <div className="query-builder__sub-header__actions">
271
+ <DropdownMenu
272
+ className="query-builder__sub-header__custom-action"
273
+ title="Show Advanced Menu..."
274
+ content={
275
+ <MenuContent>
276
+ <MenuContentItem
277
+ onClick={toggleShowFunctionPanel}
278
+ disabled={!queryBuilderState.isQuerySupported}
279
+ >
280
+ <MenuContentItemIcon>
281
+ {queryBuilderState.showFunctionsExplorerPanel ? (
282
+ <CheckIcon />
283
+ ) : null}
284
+ </MenuContentItemIcon>
285
+ <MenuContentItemLabel className="query-builder__sub-header__menu-content">
286
+ Show Function(s)
287
+ </MenuContentItemLabel>
288
+ </MenuContentItem>
289
+ {!queryBuilderState.isParameterSupportDisabled && (
290
+ <MenuContentItem
291
+ onClick={toggleShowParameterPanel}
292
+ disabled={
293
+ !queryBuilderState.isQuerySupported ||
294
+ queryBuilderState.parametersState.parameterStates
295
+ .length > 0
296
+ }
297
+ >
298
+ <MenuContentItemIcon>
299
+ {queryBuilderState.showParametersPanel ? (
300
+ <CheckIcon />
301
+ ) : null}
302
+ </MenuContentItemIcon>
303
+ <MenuContentItemLabel className="query-builder__sub-header__menu-content">
304
+ Show Parameter(s)
305
+ </MenuContentItemLabel>
306
+ </MenuContentItem>
307
+ )}
265
308
  <MenuContentItem
266
- onClick={toggleShowParameterPanel}
309
+ onClick={toggleShowFilterPanel}
267
310
  disabled={
268
311
  !queryBuilderState.isQuerySupported ||
269
- queryBuilderState.parametersState.parameterStates
270
- .length > 0
312
+ Array.from(
313
+ queryBuilderState.filterState.nodes.values(),
314
+ ).length > 0
271
315
  }
272
316
  >
273
317
  <MenuContentItemIcon>
274
- {queryBuilderState.showParametersPanel ? (
318
+ {queryBuilderState.filterState.showPanel ? (
275
319
  <CheckIcon />
276
320
  ) : null}
277
321
  </MenuContentItemIcon>
278
322
  <MenuContentItemLabel className="query-builder__sub-header__menu-content">
279
- Show Parameter(s)
323
+ Show Filter
280
324
  </MenuContentItemLabel>
281
325
  </MenuContentItem>
282
- )}
283
- <MenuContentItem
284
- onClick={toggleShowFilterPanel}
285
- disabled={
286
- !queryBuilderState.isQuerySupported ||
287
- Array.from(
288
- queryBuilderState.filterState.nodes.values(),
289
- ).length > 0
290
- }
291
- >
292
- <MenuContentItemIcon>
293
- {queryBuilderState.filterState.showPanel ? (
294
- <CheckIcon />
295
- ) : null}
296
- </MenuContentItemIcon>
297
- <MenuContentItemLabel className="query-builder__sub-header__menu-content">
298
- Show Filter
299
- </MenuContentItemLabel>
300
- </MenuContentItem>
301
- <MenuContentItem
302
- onClick={toggleShowOlapGroupByPanel}
303
- disabled={
304
- !queryBuilderState.isQuerySupported ||
305
- !(
306
- queryBuilderState.fetchStructureState
307
- .implementation instanceof QueryBuilderTDSState
308
- ) ||
309
- queryBuilderState.fetchStructureState.implementation
310
- .olapGroupByState.olapColumns.length > 0
311
- }
312
- >
313
- <MenuContentItemIcon>
314
- {isTDSState &&
315
- guaranteeType(
316
- queryBuilderState.fetchStructureState
317
- .implementation,
318
- QueryBuilderTDSState,
319
- ).showOlapGroupByPanel ? (
320
- <CheckIcon />
321
- ) : null}
322
- </MenuContentItemIcon>
323
- <MenuContentItemLabel className="query-builder__sub-header__menu-content">
324
- Show OLAP GroupBy
325
- </MenuContentItemLabel>
326
- </MenuContentItem>
327
- <MenuContentItem
328
- onClick={toggleShowPostFilterPanel}
329
- disabled={
330
- !queryBuilderState.isQuerySupported ||
331
- !(
332
- queryBuilderState.fetchStructureState
333
- .implementation instanceof QueryBuilderTDSState
334
- ) ||
335
- Array.from(
336
- queryBuilderState.fetchStructureState.implementation.postFilterState.nodes.values(),
337
- ).length > 0
338
- }
339
- >
340
- <MenuContentItemIcon>
341
- {queryBuilderState.fetchStructureState
342
- .implementation instanceof QueryBuilderTDSState &&
343
- queryBuilderState.fetchStructureState.implementation
344
- .showPostFilterPanel ? (
345
- <CheckIcon />
346
- ) : null}
347
- </MenuContentItemIcon>
348
- <MenuContentItemLabel className="query-builder__sub-header__menu-content">
349
- Show Post-Filter
350
- </MenuContentItemLabel>
351
- </MenuContentItem>
352
- </MenuContent>
353
- }
354
- menuProps={{
355
- anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
356
- transformOrigin: { vertical: 'top', horizontal: 'right' },
357
- elevation: 7,
358
- }}
359
- >
360
- <div className="query-builder__sub-header__custom-action__label">
361
- Advanced
362
- </div>
363
- <CaretDownIcon className="query-builder__sub-header__custom-action__icon" />
364
- </DropdownMenu>
326
+ <MenuContentItem
327
+ onClick={toggleShowOlapGroupByPanel}
328
+ disabled={
329
+ !queryBuilderState.isQuerySupported ||
330
+ !(
331
+ queryBuilderState.fetchStructureState
332
+ .implementation instanceof QueryBuilderTDSState
333
+ ) ||
334
+ queryBuilderState.fetchStructureState.implementation
335
+ .olapGroupByState.olapColumns.length > 0
336
+ }
337
+ >
338
+ <MenuContentItemIcon>
339
+ {isTDSState &&
340
+ guaranteeType(
341
+ queryBuilderState.fetchStructureState
342
+ .implementation,
343
+ QueryBuilderTDSState,
344
+ ).showOlapGroupByPanel ? (
345
+ <CheckIcon />
346
+ ) : null}
347
+ </MenuContentItemIcon>
348
+ <MenuContentItemLabel className="query-builder__sub-header__menu-content">
349
+ Show OLAP GroupBy
350
+ </MenuContentItemLabel>
351
+ </MenuContentItem>
352
+ <MenuContentItem
353
+ onClick={toggleShowPostFilterPanel}
354
+ disabled={
355
+ !queryBuilderState.isQuerySupported ||
356
+ !(
357
+ queryBuilderState.fetchStructureState
358
+ .implementation instanceof QueryBuilderTDSState
359
+ ) ||
360
+ Array.from(
361
+ queryBuilderState.fetchStructureState.implementation.postFilterState.nodes.values(),
362
+ ).length > 0
363
+ }
364
+ >
365
+ <MenuContentItemIcon>
366
+ {queryBuilderState.fetchStructureState
367
+ .implementation instanceof QueryBuilderTDSState &&
368
+ queryBuilderState.fetchStructureState.implementation
369
+ .showPostFilterPanel ? (
370
+ <CheckIcon />
371
+ ) : null}
372
+ </MenuContentItemIcon>
373
+ <MenuContentItemLabel className="query-builder__sub-header__menu-content">
374
+ Show Post-Filter
375
+ </MenuContentItemLabel>
376
+ </MenuContentItem>
377
+ <MenuContentItem onClick={openWatermark}>
378
+ <MenuContentItemIcon>{null}</MenuContentItemIcon>
379
+ <MenuContentItemLabel className="query-builder__sub-header__menu-content">
380
+ Edit Watermark
381
+ </MenuContentItemLabel>
382
+ </MenuContentItem>
383
+ </MenuContent>
384
+ }
385
+ menuProps={{
386
+ anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
387
+ transformOrigin: { vertical: 'top', horizontal: 'right' },
388
+ elevation: 7,
389
+ }}
390
+ >
391
+ <div className="query-builder__sub-header__custom-action__label">
392
+ Advanced
393
+ </div>
394
+ <CaretDownIcon className="query-builder__sub-header__custom-action__icon" />
395
+ </DropdownMenu>
396
+ </div>
365
397
  </div>
366
398
  </div>
367
399
  <div className="query-builder__main">
@@ -25,10 +25,14 @@ import {
25
25
  TimesIcon,
26
26
  DollarIcon,
27
27
  PlusIcon,
28
- InputWithInlineValidation,
29
28
  DragPreviewLayer,
30
29
  useDragPreviewLayer,
31
30
  BlankPanelPlaceholder,
31
+ Modal,
32
+ ModalBody,
33
+ ModalFooter,
34
+ ModalHeader,
35
+ PanelFormTextField,
32
36
  } from '@finos/legend-art';
33
37
  import {
34
38
  type QueryBuilderParameterDragSource,
@@ -81,13 +85,6 @@ const VariableExpressionEditor = observer(
81
85
  ? 'Parameter name already exists'
82
86
  : undefined;
83
87
 
84
- // variable
85
- const changeVariableName: React.ChangeEventHandler<HTMLInputElement> = (
86
- event,
87
- ) => {
88
- variableExpression_setName(varState, event.target.value);
89
- };
90
-
91
88
  // type
92
89
  const stringType =
93
90
  queryBuilderState.graphManagerState.graph.getPrimitiveType(
@@ -164,30 +161,25 @@ const VariableExpressionEditor = observer(
164
161
  paper: 'editor-modal__content',
165
162
  }}
166
163
  >
167
- <div className="modal modal--dark editor-modal query-builder__parameters__modal">
168
- <div className="modal__header">
169
- <div className="modal__title">
170
- {`${isCreating ? 'Create ' : 'Update '}`}Parameter
171
- </div>
172
- </div>
173
- <div className="modal__body query-builder__parameters__modal__body">
164
+ <Modal
165
+ darkMode={true}
166
+ className="editor-modal query-builder__parameters__modal"
167
+ >
168
+ <ModalHeader
169
+ title={`${isCreating ? 'Create Parameter' : 'Update Parameter'}`}
170
+ />
171
+ <ModalBody className="query-builder__parameters__modal__body">
174
172
  <div className="panel__content__form__section">
175
- <div className="panel__content__form__section__header__label">
176
- Parameter Name
177
- </div>
178
- <div className="panel__content__form__section__header__prompt">
179
- Name of the parameter. Should be descriptive of its purpose.
180
- </div>
181
- <div className="query-builder__parameters__parameter__name">
182
- <InputWithInlineValidation
183
- className="query-builder__parameters__parameter__name__input input-group__input"
184
- spellCheck={false}
185
- value={varState.name}
186
- onChange={changeVariableName}
187
- placeholder="Parameter name"
188
- validationErrorMessage={validationMessage}
189
- />
190
- </div>
173
+ <PanelFormTextField
174
+ name="Parameter Name"
175
+ prompt="Name of the parameter. Should be descriptive of its purpose."
176
+ update={(value: string | undefined): void =>
177
+ variableExpression_setName(varState, value ?? '')
178
+ }
179
+ value={varState.name}
180
+ errorMessage={validationMessage}
181
+ isReadOnly={false}
182
+ />
191
183
  </div>
192
184
  <div className="panel__content__form__section">
193
185
  <div className="panel__content__form__section__header__label">
@@ -230,8 +222,8 @@ const VariableExpressionEditor = observer(
230
222
  onChange={changeUpperBound}
231
223
  />
232
224
  </div>
233
- </div>
234
- <div className="modal__footer">
225
+ </ModalBody>
226
+ <ModalFooter>
235
227
  {isCreating && (
236
228
  <button
237
229
  className="btn modal__footer__close-btn btn--dark"
@@ -244,8 +236,8 @@ const VariableExpressionEditor = observer(
244
236
  <button className="btn modal__footer__close-btn" onClick={close}>
245
237
  Close
246
238
  </button>
247
- </div>
248
- </div>
239
+ </ModalFooter>
240
+ </Modal>
249
241
  </Dialog>
250
242
  );
251
243
  },
@@ -21,6 +21,10 @@ import {
21
21
  PanelDropZone,
22
22
  InfoCircleIcon,
23
23
  PanelEntryDropZonePlaceholder,
24
+ Modal,
25
+ ModalHeader,
26
+ ModalBody,
27
+ ModalFooter,
24
28
  } from '@finos/legend-art';
25
29
  import { observer } from 'mobx-react-lite';
26
30
  import {
@@ -218,11 +222,12 @@ export const QueryBuilderPropertyExpressionEditor = observer(
218
222
  paper: 'editor-modal__content',
219
223
  }}
220
224
  >
221
- <div className="modal modal--dark editor-modal query-builder-property-editor">
222
- <div className="modal__header">
223
- <div className="modal__title">Derived Property</div>
224
- </div>
225
- <div className="modal__body query-builder-property-editor__content">
225
+ <Modal
226
+ darkMode={true}
227
+ className="editor-modal query-builder-property-editor"
228
+ >
229
+ <ModalHeader title="Derived Property" />
230
+ <ModalBody className="query-builder-property-editor__content">
226
231
  {propertyExpressionState.derivedPropertyExpressionStates.map(
227
232
  (pe) => (
228
233
  <DerivedPropertyExpressionEditor
@@ -231,7 +236,7 @@ export const QueryBuilderPropertyExpressionEditor = observer(
231
236
  />
232
237
  ),
233
238
  )}
234
- <div className="modal__body query-builder__parameters__modal__body">
239
+ <ModalBody className="query-builder__parameters__modal__body">
235
240
  <div className="panel__content__form__section__header__label">
236
241
  List of available parameters
237
242
  </div>
@@ -250,17 +255,17 @@ export const QueryBuilderPropertyExpressionEditor = observer(
250
255
  ),
251
256
  )}
252
257
  </div>
253
- </div>
254
- </div>
255
- <div className="modal__footer">
258
+ </ModalBody>
259
+ </ModalBody>
260
+ <ModalFooter>
256
261
  <button
257
262
  className="btn modal__footer__close-btn"
258
263
  onClick={handleClose}
259
264
  >
260
265
  Done
261
266
  </button>
262
- </div>
263
- </div>
267
+ </ModalFooter>
268
+ </Modal>
264
269
  </Dialog>
265
270
  );
266
271
  },
@@ -28,6 +28,7 @@ import {
28
28
  PauseCircleIcon,
29
29
  ExclamationTriangleIcon,
30
30
  PanelContent,
31
+ MenuContentDivider,
31
32
  } from '@finos/legend-art';
32
33
  import { observer } from 'mobx-react-lite';
33
34
  import { flowResult } from 'mobx';
@@ -272,6 +273,16 @@ const QueryBuilderGridResultContextMenu = observer(
272
273
  );
273
274
  };
274
275
 
276
+ const handleCopyCellValue = applicationStore.guardUnhandledError(() =>
277
+ applicationStore.copyTextToClipboard(event?.value),
278
+ );
279
+
280
+ const handleCopyRowValue = applicationStore.guardUnhandledError(() =>
281
+ applicationStore.copyTextToClipboard(
282
+ Object.values(event?.data).toString(),
283
+ ),
284
+ );
285
+
275
286
  return (
276
287
  <MenuContent ref={ref}>
277
288
  <MenuContentItem
@@ -288,6 +299,13 @@ const QueryBuilderGridResultContextMenu = observer(
288
299
  >
289
300
  Filter Out
290
301
  </MenuContentItem>
302
+ <MenuContentDivider />
303
+ <MenuContentItem onClick={handleCopyCellValue}>
304
+ Copy Cell Value
305
+ </MenuContentItem>
306
+ <MenuContentItem onClick={handleCopyRowValue}>
307
+ Copy Row Value
308
+ </MenuContentItem>
291
309
  </MenuContent>
292
310
  );
293
311
  }),
@@ -16,7 +16,14 @@
16
16
 
17
17
  import { useEffect } from 'react';
18
18
  import { observer } from 'mobx-react-lite';
19
- import { clsx, Dialog } from '@finos/legend-art';
19
+ import {
20
+ clsx,
21
+ Dialog,
22
+ Modal,
23
+ ModalBody,
24
+ ModalFooter,
25
+ ModalHeader,
26
+ } from '@finos/legend-art';
20
27
  import type { QueryBuilderState } from '../stores/QueryBuilderState.js';
21
28
  import { QueryBuilderTextEditorMode } from '../stores/QueryBuilderTextEditorState.js';
22
29
  import { flowResult } from 'mobx';
@@ -57,25 +64,23 @@ export const QueryBuilderTextEditor = observer(
57
64
  paper: 'editor-modal__content',
58
65
  }}
59
66
  >
60
- <div
61
- className={clsx(
62
- 'modal modal--dark editor-modal query-builder-text-mode__modal',
63
- {
64
- 'query-builder-text-mode__modal--has-error': Boolean(
65
- queryTextEditorState.parserError,
66
- ),
67
- },
68
- )}
67
+ <Modal
68
+ darkMode={true}
69
+ className={clsx('editor-modal query-builder-text-mode__modal', {
70
+ 'query-builder-text-mode__modal--has-error': Boolean(
71
+ queryTextEditorState.parserError,
72
+ ),
73
+ })}
69
74
  >
70
- <div className="modal__header">
75
+ <ModalHeader>
71
76
  <div className="modal__title">Query</div>
72
77
  {queryTextEditorState.parserError && (
73
78
  <div className="modal__title__error-badge">
74
79
  Failed to parse query
75
80
  </div>
76
81
  )}
77
- </div>
78
- <div className="modal__body">
82
+ </ModalHeader>
83
+ <ModalBody>
79
84
  <div
80
85
  className={clsx('query-builder-text-mode__modal__content', {
81
86
  backdrop__element: Boolean(queryTextEditorState.parserError),
@@ -101,8 +106,8 @@ export const QueryBuilderTextEditor = observer(
101
106
  />
102
107
  )}
103
108
  </div>
104
- </div>
105
- <div className="modal__footer">
109
+ </ModalBody>
110
+ <ModalFooter>
106
111
  {mode === QueryBuilderTextEditorMode.TEXT && (
107
112
  <button
108
113
  className="btn btn--dark btn--caution"
@@ -118,8 +123,8 @@ export const QueryBuilderTextEditor = observer(
118
123
  >
119
124
  Close
120
125
  </button>
121
- </div>
122
- </div>
126
+ </ModalFooter>
127
+ </Modal>
123
128
  </Dialog>
124
129
  );
125
130
  },
@@ -48,6 +48,10 @@ import {
48
48
  PanelLoadingIndicator,
49
49
  DragPreviewLayer,
50
50
  useDragPreviewLayer,
51
+ Modal,
52
+ ModalBody,
53
+ ModalFooter,
54
+ ModalHeader,
51
55
  } from '@finos/legend-art';
52
56
  import {
53
57
  type QueryBuilderExplorerTreeDragSource,
@@ -208,13 +212,14 @@ const QueryBuilderExplorerPreviewDataModal = observer(
208
212
  paper: 'editor-modal__content',
209
213
  }}
210
214
  >
211
- <div className="modal modal--dark editor-modal query-builder__explorer__preview-data-modal">
212
- <div className="modal__header">
213
- <div className="modal__title">
214
- {prettyPropertyName(previewDataState.propertyName)}
215
- </div>
216
- </div>
217
- <div className="modal__body query-builder__explorer__preview-data-modal__body">
215
+ <Modal
216
+ darkMode={true}
217
+ className="editor-modal query-builder__explorer__preview-data-modal"
218
+ >
219
+ <ModalHeader
220
+ title={prettyPropertyName(previewDataState.propertyName)}
221
+ />
222
+ <ModalBody className="query-builder__explorer__preview-data-modal__body">
218
223
  {previewDataState.previewData && (
219
224
  <table className="table">
220
225
  <thead>
@@ -242,13 +247,13 @@ const QueryBuilderExplorerPreviewDataModal = observer(
242
247
  </tbody>
243
248
  </table>
244
249
  )}
245
- </div>
246
- <div className="modal__footer">
250
+ </ModalBody>
251
+ <ModalFooter>
247
252
  <button className="btn modal__footer__close-btn" onClick={close}>
248
253
  Close
249
254
  </button>
250
- </div>
251
- </div>
255
+ </ModalFooter>
256
+ </Modal>
252
257
  </Dialog>
253
258
  );
254
259
  },