@finos/legend-query-builder 4.14.21 → 4.14.23

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/__lib__/QueryBuilderTesting.d.ts +1 -0
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +1 -0
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
  6. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js +2 -1
  7. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  9. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +1 -1
  10. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  11. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.d.ts.map +1 -1
  12. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js +132 -67
  13. package/lib/components/fetch-structure/QueryBuilderTDSWindowPanel.js.map +1 -1
  14. package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
  15. package/lib/components/result/QueryBuilderResultPanel.js +1 -0
  16. package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
  17. package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
  18. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +1 -0
  19. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  20. package/lib/index.css +16 -0
  21. package/lib/package.json +1 -1
  22. package/lib/stores/QueryBuilderResultState.d.ts +2 -0
  23. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  24. package/lib/stores/QueryBuilderResultState.js +11 -4
  25. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  26. package/lib/stores/QueryBuilderStateHashUtils.d.ts +1 -1
  27. package/lib/stores/QueryBuilderStateHashUtils.d.ts.map +1 -1
  28. package/lib/stores/QueryBuilderStateHashUtils.js +1 -1
  29. package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
  30. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +1 -0
  31. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
  32. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  33. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +6 -3
  34. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  35. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.d.ts +7 -2
  36. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.d.ts.map +1 -1
  37. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.js +46 -29
  38. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowState.js.map +1 -1
  39. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowValueSpecificationBuilder.js +1 -1
  40. package/lib/stores/fetch-structure/tds/window/QueryBuilderWindowValueSpecificationBuilder.js.map +1 -1
  41. package/package.json +6 -6
  42. package/src/__lib__/QueryBuilderTesting.ts +1 -0
  43. package/src/components/fetch-structure/QueryBuilderFetchStructurePanel.tsx +2 -1
  44. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +1 -0
  45. package/src/components/fetch-structure/QueryBuilderTDSWindowPanel.tsx +232 -140
  46. package/src/components/result/QueryBuilderResultPanel.tsx +1 -0
  47. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +1 -0
  48. package/src/stores/QueryBuilderResultState.ts +13 -4
  49. package/src/stores/QueryBuilderStateHashUtils.ts +1 -1
  50. package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +1 -0
  51. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +16 -3
  52. package/src/stores/fetch-structure/tds/window/QueryBuilderWindowState.ts +70 -38
  53. package/src/stores/fetch-structure/tds/window/QueryBuilderWindowValueSpecificationBuilder.ts +1 -1
@@ -49,7 +49,12 @@ import {
49
49
  PanelHeaderActions,
50
50
  Panel,
51
51
  } from '@finos/legend-art';
52
- import { assertErrorThrown, guaranteeNonNullable } from '@finos/legend-shared';
52
+ import {
53
+ assertErrorThrown,
54
+ clone,
55
+ deleteEntry,
56
+ guaranteeNonNullable,
57
+ } from '@finos/legend-shared';
53
58
  import { observer } from 'mobx-react-lite';
54
59
  import { forwardRef, useCallback, useRef, useState } from 'react';
55
60
  import { type DropTargetMonitor, useDrag, useDrop } from 'react-dnd';
@@ -62,6 +67,7 @@ import {
62
67
  QueryBuilderTDS_WindowRankOperatorState,
63
68
  QueryBuilderTDS_WindowAggreationOperatorState,
64
69
  QUERY_BUILDER_WINDOW_COLUMN_DND_TYPE,
70
+ WindowGroupByColumnSortByState,
65
71
  } from '../../stores/fetch-structure/tds/window/QueryBuilderWindowState.js';
66
72
  import { QUERY_BUILDER_PROJECTION_COLUMN_DND_TYPE } from '../../stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js';
67
73
  import type { QueryBuilderTDSColumnState } from '../../stores/fetch-structure/tds/QueryBuilderTDSColumnState.js';
@@ -83,6 +89,13 @@ const createWindowColumnState = (
83
89
  const nonColoperator = guaranteeNonNullable(
84
90
  tdsState.windowState.operators.filter((o) => !o.isColumnAggregator())[0],
85
91
  );
92
+ const columnName = operator
93
+ ? operator.isColumnAggregator()
94
+ ? `${operator.getLabel()} of ${columnState.columnName}`
95
+ : columnState.columnName
96
+ : nonColoperator.isColumnAggregator()
97
+ ? `${nonColoperator.getLabel()} of ${columnState.columnName}`
98
+ : columnState.columnName;
86
99
  if (operator) {
87
100
  const opState = new QueryBuilderTDS_WindowAggreationOperatorState(
88
101
  tdsState.windowState,
@@ -94,7 +107,7 @@ const createWindowColumnState = (
94
107
  [],
95
108
  undefined,
96
109
  opState,
97
- `${operator.getLabel()} ${columnState.columnName}`,
110
+ columnName,
98
111
  );
99
112
  } else {
100
113
  return new QueryBuilderWindowColumnState(
@@ -105,7 +118,7 @@ const createWindowColumnState = (
105
118
  tdsState.windowState,
106
119
  nonColoperator,
107
120
  ),
108
- `${nonColoperator.getLabel()} ${columnState.columnName}`,
121
+ columnName,
109
122
  );
110
123
  }
111
124
  };
@@ -188,85 +201,177 @@ const QueryBuilderWindowColumnModalEditor = observer(
188
201
  windowState: QueryBuilderWindowState;
189
202
  windowColumnState: QueryBuilderWindowColumnState;
190
203
  }) => {
204
+ // Read state
191
205
  const { windowState, windowColumnState } = props;
192
- const createNewWindow =
206
+ const isNewWindowFunction =
193
207
  !windowState.windowColumns.includes(windowColumnState);
194
208
  const tdsState = windowState.tdsState;
195
209
  const applicationStore = useApplicationStore();
196
- const close = (): void => {
197
- windowState.setEditColumn(undefined);
198
- };
199
- const isDuplicatedColumnName = !windowState.windowColumns.includes(
200
- windowColumnState,
201
- )
202
- ? windowState.tdsState.tdsColumns
203
- .map((c) => c.columnName)
204
- .includes(windowColumnState.columnName)
205
- : windowState.tdsState.isDuplicateColumn(windowColumnState);
206
- const windowOptions = createNewWindow
207
- ? tdsState.tdsColumns
208
- : windowColumnState.possibleReferencedColumns;
209
- const windowOptionsLabels = windowOptions.map((w) => ({
210
- label: w.columnName,
211
- value: w,
212
- }));
213
- // column Name
210
+
211
+ // Column name
212
+ const [selectedColumnName, setSelectedColumnName] = useState(
213
+ windowColumnState.columnName,
214
+ );
214
215
  const changeColumnName: React.ChangeEventHandler<HTMLInputElement> = (
215
216
  event,
216
- ) => windowColumnState.setColumnName(event.target.value);
217
- // operator
217
+ ) => setSelectedColumnName(event.target.value);
218
+ const isDuplicatedColumnName = isNewWindowFunction
219
+ ? windowState.tdsState.tdsColumns
220
+ .map((c) => c.columnName)
221
+ .filter((name) => name === selectedColumnName).length > 0
222
+ : windowState.tdsState.tdsColumns
223
+ .map((c) => c.columnName)
224
+ .filter((name) => name === selectedColumnName).length > 0 &&
225
+ selectedColumnName !== windowColumnState.columnName;
226
+
227
+ // Window operator
218
228
  const operators = windowState.operators;
219
- const operationState = windowColumnState.operationState;
220
- const windowOpColumn =
221
- operationState instanceof QueryBuilderTDS_WindowAggreationOperatorState
222
- ? operationState.columnState
229
+ const operatorState = windowColumnState.operatorState;
230
+ const [selectedOperatorState, setSelectedOperatorState] = useState(() => {
231
+ if (
232
+ operatorState instanceof QueryBuilderTDS_WindowAggreationOperatorState
233
+ ) {
234
+ return new QueryBuilderTDS_WindowAggreationOperatorState(
235
+ operatorState.windowState,
236
+ operatorState.operator,
237
+ operatorState.columnState,
238
+ );
239
+ }
240
+ return new QueryBuilderTDS_WindowRankOperatorState(
241
+ operatorState.windowState,
242
+ operatorState.operator,
243
+ );
244
+ });
245
+ const windowOperatorColumn =
246
+ selectedOperatorState instanceof
247
+ QueryBuilderTDS_WindowAggreationOperatorState
248
+ ? selectedOperatorState.columnState
223
249
  : undefined;
224
- const changeOperatorCol = (
250
+ const changeWindowOperatorColumn = (
225
251
  val: { label: string; value: QueryBuilderTDSColumnState } | null,
226
252
  ): void => {
227
253
  if (
228
- operationState instanceof QueryBuilderTDS_WindowAggreationOperatorState
254
+ selectedOperatorState instanceof
255
+ QueryBuilderTDS_WindowAggreationOperatorState &&
256
+ val !== null
229
257
  ) {
230
- if (val !== null) {
231
- operationState.setColumnState(val.value);
232
- }
258
+ const newOpertorState = clone(selectedOperatorState);
259
+ const newColumnName = newOpertorState.operator.isColumnAggregator()
260
+ ? `${newOpertorState.operator.getLabel()} of ${val.value.columnName}`
261
+ : val.value.columnName;
262
+ newOpertorState.setColumnState(val.value);
263
+ setSelectedOperatorState(newOpertorState);
264
+ setSelectedColumnName(newColumnName);
233
265
  }
234
266
  };
235
267
  const changeOperator =
236
- (olapOp: QueryBuilderTDS_WindowOperator) => (): void => {
237
- windowColumnState.changeOperator(olapOp);
268
+ (newOperator: QueryBuilderTDS_WindowOperator) => (): void => {
269
+ const stateAndName =
270
+ windowColumnState.getChangeOperatorStateAndColumnName(
271
+ selectedOperatorState.operator,
272
+ windowOperatorColumn,
273
+ newOperator,
274
+ );
275
+ if (stateAndName) {
276
+ setSelectedOperatorState(stateAndName.operatorState);
277
+ setSelectedColumnName(stateAndName.columnName);
278
+ }
238
279
  };
239
- // window
240
- const addOptions = windowOptions.filter(
241
- (e) => !windowColumnState.windowColumns.includes(e),
280
+ const allColumns = isNewWindowFunction
281
+ ? tdsState.tdsColumns
282
+ : windowColumnState.possibleReferencedColumns;
283
+ const allColumnsOptions = allColumns.map((w) => ({
284
+ label: w.columnName,
285
+ value: w,
286
+ }));
287
+
288
+ // Window columns
289
+ const [selectedWindowColumns, setSelectedWindowColumns] = useState([
290
+ ...windowColumnState.windowColumns,
291
+ ]);
292
+ const availableColumns = allColumns.filter(
293
+ (e) => !selectedWindowColumns.includes(e),
242
294
  );
243
- const create = (): void => {
244
- windowState.addWindowColumn(windowColumnState);
245
- close();
246
- };
247
- const addWindowValue = (): void => {
248
- if (addOptions.length > 0) {
249
- windowColumnState.addWindow(guaranteeNonNullable(addOptions[0]));
295
+ const addWindowColumn = (): void => {
296
+ if (availableColumns.length > 0) {
297
+ setSelectedWindowColumns([
298
+ ...selectedWindowColumns,
299
+ guaranteeNonNullable(availableColumns[0]),
300
+ ]);
250
301
  }
251
302
  };
252
- // sortby
253
- const sortByState = windowColumnState.sortByState;
303
+ const updateWindowColumn = (
304
+ idx: number,
305
+ column: QueryBuilderTDSColumnState,
306
+ ): void => {
307
+ const newWindowColumns = clone(selectedWindowColumns);
308
+ newWindowColumns[idx] = column;
309
+ setSelectedWindowColumns(newWindowColumns);
310
+ };
311
+ const deleteWindowColumn = (column: QueryBuilderTDSColumnState): void => {
312
+ const newWindowColumns = clone(selectedWindowColumns);
313
+ deleteEntry(newWindowColumns, column);
314
+ setSelectedWindowColumns(newWindowColumns);
315
+ };
316
+
317
+ // Sort by
318
+ const [selectedSortBy, setSelectedSortBy] = useState(() => {
319
+ const sortBy = windowColumnState.sortByState;
320
+ if (sortBy) {
321
+ return new WindowGroupByColumnSortByState(
322
+ sortBy.columnState,
323
+ sortBy.sortType,
324
+ );
325
+ }
326
+ return undefined;
327
+ });
254
328
  const changeSortBy = (sortOp: COLUMN_SORT_TYPE | undefined) => (): void => {
255
- windowColumnState.changeSortBy(sortOp);
329
+ if (selectedSortBy?.sortType !== sortOp) {
330
+ if (sortOp) {
331
+ const newSortByState = new WindowGroupByColumnSortByState(
332
+ selectedSortBy?.columnState
333
+ ? selectedSortBy.columnState
334
+ : guaranteeNonNullable(
335
+ windowColumnState.possibleReferencedColumns[0],
336
+ ),
337
+ sortOp,
338
+ );
339
+ setSelectedSortBy(newSortByState);
340
+ } else {
341
+ setSelectedSortBy(undefined);
342
+ }
343
+ }
256
344
  };
257
345
  const changeSortCol = (
258
346
  val: { label: string; value: QueryBuilderTDSColumnState } | null,
259
347
  ): void => {
260
- if (sortByState) {
261
- if (val !== null) {
262
- sortByState.setColumnState(val.value);
263
- }
348
+ if (selectedSortBy && val !== null) {
349
+ const newSortByState = new WindowGroupByColumnSortByState(
350
+ val.value,
351
+ selectedSortBy.sortType,
352
+ );
353
+ setSelectedSortBy(newSortByState);
264
354
  }
265
355
  };
356
+
357
+ // Modal lifecycle actions
358
+ const handleCancel = (): void => {
359
+ windowState.setEditColumn(undefined);
360
+ };
361
+
362
+ const handleApply = (): void => {
363
+ windowColumnState.setColumnName(selectedColumnName);
364
+ windowColumnState.setOperatorState(selectedOperatorState);
365
+ windowColumnState.setWindows(selectedWindowColumns);
366
+ windowColumnState.setSortBy(selectedSortBy);
367
+ windowState.addWindowColumn(windowColumnState);
368
+ handleCancel();
369
+ };
370
+
266
371
  return (
267
372
  <Dialog
268
373
  open={Boolean(windowState.editColumn)}
269
- onClose={close}
374
+ onClose={handleCancel}
270
375
  classes={{
271
376
  root: 'editor-modal__root-container',
272
377
  container: 'editor-modal__container',
@@ -288,7 +393,7 @@ const QueryBuilderWindowColumnModalEditor = observer(
288
393
  >
289
394
  <ModalHeader
290
395
  title={
291
- createNewWindow
396
+ isNewWindowFunction
292
397
  ? 'Create Window Function Column'
293
398
  : 'Update Window Function Column'
294
399
  }
@@ -305,27 +410,16 @@ const QueryBuilderWindowColumnModalEditor = observer(
305
410
  <div className="panel__content__form__section__list">
306
411
  <div className="panel__content__form__section__list__items">
307
412
  <div className="query-builder__olap__column__operation__operator">
308
- <div
309
- className={clsx(
310
- 'query-builder__olap__column__operation__operator__label',
311
- {
312
- 'query-builder__olap__column__operation__operator__label__agg':
313
- !windowOpColumn,
314
- },
315
- )}
316
- >
317
- {operationState.operator.getLabel()}
318
- </div>
319
- {windowOpColumn && (
413
+ {windowOperatorColumn && (
320
414
  <div className="panel__content__form__section__list__item query-builder__olap__tds__column__options">
321
415
  <CustomSelectorInput
322
416
  className="query-builder__olap__tds__column__dropdown"
323
- options={windowOptionsLabels}
324
- disabled={windowOptionsLabels.length < 1}
325
- onChange={changeOperatorCol}
417
+ options={allColumnsOptions}
418
+ disabled={allColumnsOptions.length < 1}
419
+ onChange={changeWindowOperatorColumn}
326
420
  value={{
327
- value: windowOpColumn,
328
- label: windowOpColumn.columnName,
421
+ value: windowOperatorColumn,
422
+ label: windowOperatorColumn.columnName,
329
423
  }}
330
424
  darkMode={
331
425
  !applicationStore.layoutService
@@ -334,8 +428,20 @@ const QueryBuilderWindowColumnModalEditor = observer(
334
428
  />
335
429
  </div>
336
430
  )}
431
+ <div
432
+ className={clsx(
433
+ 'query-builder__olap__column__operation__operator__label',
434
+ {
435
+ 'query-builder__olap__column__operation__operator__label__agg':
436
+ !windowOperatorColumn,
437
+ },
438
+ )}
439
+ >
440
+ {selectedOperatorState.operator.getLabel()}
441
+ </div>
337
442
  <DropdownMenu
338
443
  className="query-builder__olap__column__operation__operator__dropdown"
444
+ title="Choose Window Function Operator..."
339
445
  disabled={!operators.length}
340
446
  content={
341
447
  <MenuContent>
@@ -362,16 +468,10 @@ const QueryBuilderWindowColumnModalEditor = observer(
362
468
  elevation: 7,
363
469
  }}
364
470
  >
365
- <div
366
- className="query-builder__olap__column__operation__operator__badge"
367
- title="Choose Window Function Operator..."
368
- >
471
+ <div className="query-builder__olap__column__operation__operator__badge">
369
472
  <SigmaIcon />
370
473
  </div>
371
- <div
372
- className="query-builder__olap__column__operation__operator__dropdown__trigger"
373
- title="Choose Window Function Operator..."
374
- >
474
+ <div className="query-builder__olap__column__operation__operator__dropdown__trigger">
375
475
  <CaretDownIcon />
376
476
  </div>
377
477
  </DropdownMenu>
@@ -385,29 +485,29 @@ const QueryBuilderWindowColumnModalEditor = observer(
385
485
  </div>
386
486
  <div className="panel__content__form__section__header__prompt">
387
487
  Represents the window of columns that will partition the rows
388
- for which to apply the aggragte function
488
+ for which to apply the aggregate function
389
489
  </div>
390
490
  <div className="panel__content__form__section__list">
391
491
  <div className="panel__content__form__section__list__items">
392
- {windowColumnState.windowColumns.map((value, idx) => (
492
+ {selectedWindowColumns.map((value, idx) => (
393
493
  <TDSColumnSelectorEditor
394
494
  key={value.uuid}
395
495
  colValue={value}
396
496
  setColumn={(v: QueryBuilderTDSColumnState) =>
397
- windowColumnState.changeWindow(v, idx)
497
+ updateWindowColumn(idx, v)
398
498
  }
399
- deleteColumn={(v: QueryBuilderTDSColumnState): void =>
400
- windowColumnState.deleteWindow(v)
499
+ deleteColumn={(v: QueryBuilderTDSColumnState) =>
500
+ deleteWindowColumn(v)
401
501
  }
402
- tdsColOptions={windowOptions}
502
+ tdsColOptions={availableColumns}
403
503
  />
404
504
  ))}
405
505
  </div>
406
506
  <div className="panel__content__form__section__list__new-item__add">
407
507
  <button
408
508
  className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
409
- disabled={!addOptions.length}
410
- onClick={addWindowValue}
509
+ disabled={!availableColumns.length}
510
+ onClick={addWindowColumn}
411
511
  tabIndex={-1}
412
512
  >
413
513
  Add Value
@@ -425,21 +525,16 @@ const QueryBuilderWindowColumnModalEditor = observer(
425
525
  <div className="panel__content__form__section__header__prompt"></div>
426
526
  <div className="panel__content__form__section__list">
427
527
  <div className="query-builder__olap__column__sortby__operator">
428
- {sortByState && (
429
- <div className="query-builder__olap__column__sortby__operator__label">
430
- {sortByState.sortType.toLowerCase()}
431
- </div>
432
- )}
433
- {sortByState && (
528
+ {selectedSortBy && (
434
529
  <div className="panel__content__form__section__list__item query-builder__olap__tds__column__options">
435
530
  <CustomSelectorInput
436
531
  className="query-builder__olap__tds__column__dropdown"
437
- options={windowOptionsLabels}
438
- disabled={windowOptionsLabels.length < 1}
532
+ options={allColumnsOptions}
533
+ disabled={allColumnsOptions.length < 1}
439
534
  onChange={changeSortCol}
440
535
  value={{
441
- value: sortByState.columnState,
442
- label: sortByState.columnState.columnName,
536
+ value: selectedSortBy.columnState,
537
+ label: selectedSortBy.columnState.columnName,
443
538
  }}
444
539
  darkMode={
445
540
  !applicationStore.layoutService
@@ -448,13 +543,19 @@ const QueryBuilderWindowColumnModalEditor = observer(
448
543
  />
449
544
  </div>
450
545
  )}
451
- {!sortByState && (
546
+ {!selectedSortBy && (
452
547
  <div className="query-builder__olap__column__sortby__none">
453
548
  (none)
454
549
  </div>
455
550
  )}
551
+ {selectedSortBy && (
552
+ <div className="query-builder__olap__column__sortby__operator__label">
553
+ {selectedSortBy.sortType.toLowerCase()}
554
+ </div>
555
+ )}
456
556
  <DropdownMenu
457
557
  className="query-builder__olap__column__sortby__operator__dropdown"
558
+ title="Choose Window Function SortBy Operator..."
458
559
  content={
459
560
  <MenuContent>
460
561
  <MenuContentItem
@@ -487,18 +588,16 @@ const QueryBuilderWindowColumnModalEditor = observer(
487
588
  'query-builder__olap__column__sortby__operator__badge',
488
589
  {
489
590
  'query-builder__olap__column__sortby__operator__badge--activated':
490
- Boolean(sortByState),
591
+ Boolean(selectedSortBy),
491
592
  },
492
593
  )}
493
594
  tabIndex={-1}
494
- title="Choose Window Function SortBy Operator..."
495
595
  >
496
596
  <SortIcon />
497
597
  </div>
498
598
  <div
499
599
  className="query-builder__olap__column__sortby__operator__dropdown__trigger"
500
600
  tabIndex={-1}
501
- title="Choose Window Function SortBy Operator..."
502
601
  >
503
602
  <CaretDownIcon />
504
603
  </div>
@@ -517,22 +616,23 @@ const QueryBuilderWindowColumnModalEditor = observer(
517
616
  <InputWithInlineValidation
518
617
  className="query-builder__olap__column__name__input input-group__input"
519
618
  spellCheck={false}
520
- value={windowColumnState.columnName}
619
+ value={selectedColumnName}
521
620
  onChange={changeColumnName}
522
621
  error={isDuplicatedColumnName ? 'Duplicated column' : undefined}
523
622
  />
524
623
  </PanelFormSection>
525
624
  </div>
526
625
  <ModalFooter>
527
- {createNewWindow ? (
528
- <ModalFooterButton text="Create" onClick={create} />
529
- ) : (
530
- <ModalFooterButton
531
- text="Close"
532
- onClick={close}
533
- type="secondary"
534
- />
535
- )}
626
+ <ModalFooterButton
627
+ text={isNewWindowFunction ? 'Create' : 'Apply'}
628
+ onClick={handleApply}
629
+ disabled={isDuplicatedColumnName}
630
+ />
631
+ <ModalFooterButton
632
+ text="Cancel"
633
+ onClick={handleCancel}
634
+ type="secondary"
635
+ />
536
636
  </ModalFooter>
537
637
  </Modal>
538
638
  </Dialog>
@@ -718,7 +818,7 @@ const QueryBuilderWindowColumnEditor = observer(
718
818
  };
719
819
 
720
820
  // operator
721
- const operationState = windowColumnState.operationState;
821
+ const operationState = windowColumnState.operatorState;
722
822
  const aggregateColumn =
723
823
  operationState instanceof QueryBuilderTDS_WindowAggreationOperatorState
724
824
  ? operationState.columnState
@@ -887,6 +987,15 @@ const QueryBuilderWindowColumnEditor = observer(
887
987
  />
888
988
  <div className="query-builder__olap__column__operation">
889
989
  <div className="query-builder__olap__column__operation__operator">
990
+ {aggregateColumn && (
991
+ <TDSColumnReferenceEditor
992
+ tdsColumn={aggregateColumn}
993
+ handleChange={handleOpDrop}
994
+ selectionEditor={{
995
+ options: windowColumnState.possibleReferencedColumns,
996
+ }}
997
+ />
998
+ )}
890
999
  <div
891
1000
  className={clsx(
892
1001
  'query-builder__olap__column__operation__operator__label',
@@ -898,18 +1007,10 @@ const QueryBuilderWindowColumnEditor = observer(
898
1007
  >
899
1008
  {operationState.operator.getLabel()}
900
1009
  </div>
901
- {aggregateColumn && (
902
- <TDSColumnReferenceEditor
903
- tdsColumn={aggregateColumn}
904
- handleChange={handleOpDrop}
905
- selectionEditor={{
906
- options: windowColumnState.possibleReferencedColumns,
907
- }}
908
- />
909
- )}
910
1010
  <DropdownMenu
911
1011
  className="query-builder__olap__column__operation__operator__dropdown"
912
1012
  disabled={!operators.length}
1013
+ title="Choose Window Function Operator..."
913
1014
  content={
914
1015
  <MenuContent>
915
1016
  {operators.map((op) => (
@@ -929,16 +1030,10 @@ const QueryBuilderWindowColumnEditor = observer(
929
1030
  elevation: 7,
930
1031
  }}
931
1032
  >
932
- <div
933
- className="query-builder__olap__column__operation__operator__badge"
934
- title="Choose Window Function Operator..."
935
- >
1033
+ <div className="query-builder__olap__column__operation__operator__badge">
936
1034
  <SigmaIcon />
937
1035
  </div>
938
- <div
939
- className="query-builder__olap__column__operation__operator__dropdown__trigger"
940
- title="Choose Window Function Operator..."
941
- >
1036
+ <div className="query-builder__olap__column__operation__operator__dropdown__trigger">
942
1037
  <CaretDownIcon />
943
1038
  </div>
944
1039
  </DropdownMenu>
@@ -998,7 +1093,7 @@ const QueryBuilderWindowColumnEditor = observer(
998
1093
  deleteColumn={(v: QueryBuilderTDSColumnState): void =>
999
1094
  windowColumnState.deleteWindow(v)
1000
1095
  }
1001
- tdsColOptions={windowOptions}
1096
+ tdsColOptions={addWindowOptions}
1002
1097
  />
1003
1098
  ))}
1004
1099
  </div>
@@ -1018,11 +1113,6 @@ const QueryBuilderWindowColumnEditor = observer(
1018
1113
  </div>
1019
1114
  <div className="query-builder__olap__column__sortby">
1020
1115
  <div className="query-builder__olap__column__sortby__operator">
1021
- {sortByState && (
1022
- <div className="query-builder__olap__column__sortby__operator__label">
1023
- {sortByState.sortType.toLowerCase()}
1024
- </div>
1025
- )}
1026
1116
  {sortByState && (
1027
1117
  <TDSColumnReferenceEditor
1028
1118
  tdsColumn={sortByState.columnState}
@@ -1037,8 +1127,14 @@ const QueryBuilderWindowColumnEditor = observer(
1037
1127
  (none)
1038
1128
  </div>
1039
1129
  )}
1130
+ {sortByState && (
1131
+ <div className="query-builder__olap__column__sortby__operator__label">
1132
+ {sortByState.sortType.toLowerCase()}
1133
+ </div>
1134
+ )}
1040
1135
  <DropdownMenu
1041
1136
  className="query-builder__olap__column__sortby__operator__dropdown"
1137
+ title="Choose Window Function SortBy Operator..."
1042
1138
  content={
1043
1139
  <MenuContent>
1044
1140
  <MenuContentItem
@@ -1074,14 +1170,10 @@ const QueryBuilderWindowColumnEditor = observer(
1074
1170
  Boolean(sortByState),
1075
1171
  },
1076
1172
  )}
1077
- title="Choose Window Function SortBy Operator..."
1078
1173
  >
1079
1174
  <SortIcon />
1080
1175
  </div>
1081
- <div
1082
- className="query-builder__olap__column__sortby__operator__dropdown__trigger"
1083
- title="Choose Window Function SortBy Operator..."
1084
- >
1176
+ <div className="query-builder__olap__column__sortby__operator__dropdown__trigger">
1085
1177
  <CaretDownIcon />
1086
1178
  </div>
1087
1179
  </DropdownMenu>
@@ -288,6 +288,7 @@ export const QueryBuilderResultPanel = observer(
288
288
  } else {
289
289
  queryBuilderState.resultState.setPreviewLimit(previewLimitValue);
290
290
  }
291
+ queryBuilderState.resultState.updatePreviewLimitInConfig();
291
292
  };
292
293
 
293
294
  const onKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
@@ -241,6 +241,7 @@ export const QueryBuilderTDSGridResult = observer(
241
241
  columns: columnAPi.getColumnState(),
242
242
  isPivotModeEnabled: columnAPi.isPivotMode(),
243
243
  isLocalModeEnabled: true,
244
+ previewLimit: resultState.previewLimit,
244
245
  });
245
246
  };
246
247
 
@@ -82,6 +82,7 @@ type QueryBuilderDataGridConfig = {
82
82
  columns: DataGridColumnState[];
83
83
  isPivotModeEnabled: boolean | undefined;
84
84
  isLocalModeEnabled: boolean | undefined;
85
+ previewLimit?: number | undefined;
85
86
  };
86
87
 
87
88
  export class QueryBuilderResultState {
@@ -131,6 +132,7 @@ export class QueryBuilderResultState {
131
132
  setQueryRunPromise: action,
132
133
  setIsQueryUsageViewerOpened: action,
133
134
  handlePreConfiguredGridConfig: action,
135
+ updatePreviewLimitInConfig: action,
134
136
  exportData: flow,
135
137
  runQuery: flow,
136
138
  cancelQuery: flow,
@@ -191,21 +193,28 @@ export class QueryBuilderResultState {
191
193
  this.isQueryUsageViewerOpened = val;
192
194
  }
193
195
 
196
+ updatePreviewLimitInConfig(): void {
197
+ if (this.gridConfig) {
198
+ this.gridConfig.previewLimit = this.previewLimit;
199
+ }
200
+ }
201
+
194
202
  handlePreConfiguredGridConfig(config: QueryGridConfig): void {
195
203
  const newConfig = {
204
+ ...config,
196
205
  columns: config.columns as DataGridColumnState[],
197
- isPivotModeEnabled: Boolean(config.isPivotModeEnabled),
198
- isLocalModeEnabled: Boolean(config.isLocalModeEnabled),
199
206
  };
207
+ if (config.previewLimit) {
208
+ this.setPreviewLimit(config.previewLimit);
209
+ }
200
210
  this.setGridConfig(newConfig);
201
211
  }
202
212
 
203
213
  getQueryGridConfig(): QueryGridConfig | undefined {
204
214
  if (this.gridConfig) {
205
215
  return {
216
+ ...this.gridConfig,
206
217
  columns: this.gridConfig.columns as object[],
207
- isPivotModeEnabled: Boolean(this.gridConfig.isPivotModeEnabled),
208
- isLocalModeEnabled: Boolean(this.gridConfig.isLocalModeEnabled),
209
218
  };
210
219
  }
211
220
  return undefined;