@finos/legend-query-builder 3.2.0 → 3.2.1

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 (69) hide show
  1. package/lib/__lib__/QueryBuilderColorTheme.d.ts +23 -0
  2. package/lib/__lib__/QueryBuilderColorTheme.d.ts.map +1 -0
  3. package/lib/__lib__/QueryBuilderColorTheme.js +24 -0
  4. package/lib/__lib__/QueryBuilderColorTheme.js.map +1 -0
  5. package/lib/components/QueryBuilder.d.ts.map +1 -1
  6. package/lib/components/QueryBuilder.js +17 -15
  7. package/lib/components/QueryBuilder.js.map +1 -1
  8. package/lib/components/QueryBuilder_LegendApplicationPlugin.d.ts.map +1 -1
  9. package/lib/components/QueryBuilder_LegendApplicationPlugin.js +3 -0
  10. package/lib/components/QueryBuilder_LegendApplicationPlugin.js.map +1 -1
  11. package/lib/components/QueryLoader.d.ts.map +1 -1
  12. package/lib/components/QueryLoader.js +6 -2
  13. package/lib/components/QueryLoader.js.map +1 -1
  14. package/lib/components/data-access/DataAccessOverview.d.ts +23 -0
  15. package/lib/components/data-access/DataAccessOverview.d.ts.map +1 -0
  16. package/lib/components/data-access/DataAccessOverview.js +146 -0
  17. package/lib/components/data-access/DataAccessOverview.js.map +1 -0
  18. package/lib/components/execution-plan/ExecutionPlanViewer.d.ts.map +1 -1
  19. package/lib/components/execution-plan/ExecutionPlanViewer.js +3 -3
  20. package/lib/components/execution-plan/ExecutionPlanViewer.js.map +1 -1
  21. package/lib/components/execution-plan/SQLExecutionNodeViewer.js +1 -1
  22. package/lib/components/execution-plan/SQLExecutionNodeViewer.js.map +1 -1
  23. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js +1 -1
  24. package/lib/components/explorer/QueryBuilderPropertySearchPanel.js.map +1 -1
  25. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts +0 -18
  26. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  27. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +34 -36
  28. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  29. package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
  30. package/lib/components/shared/LambdaEditor.js +7 -19
  31. package/lib/components/shared/LambdaEditor.js.map +1 -1
  32. package/lib/index.css +1 -17
  33. package/lib/index.css.map +1 -1
  34. package/lib/index.d.ts +2 -0
  35. package/lib/index.d.ts.map +1 -1
  36. package/lib/index.js +2 -0
  37. package/lib/index.js.map +1 -1
  38. package/lib/package.json +4 -2
  39. package/lib/stores/QueryBuilderState.d.ts +3 -3
  40. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  41. package/lib/stores/QueryBuilderState.js +34 -18
  42. package/lib/stores/QueryBuilderState.js.map +1 -1
  43. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts +9 -0
  44. package/lib/stores/QueryBuilder_LegendApplicationPlugin_Extension.d.ts.map +1 -1
  45. package/lib/stores/data-access/DataAccessState.d.ts +56 -0
  46. package/lib/stores/data-access/DataAccessState.d.ts.map +1 -0
  47. package/lib/stores/data-access/DataAccessState.js +212 -0
  48. package/lib/stores/data-access/DataAccessState.js.map +1 -0
  49. package/lib/stores/entitlements/QueryBuilderCheckEntitlementsState.d.ts +4 -2
  50. package/lib/stores/entitlements/QueryBuilderCheckEntitlementsState.d.ts.map +1 -1
  51. package/lib/stores/entitlements/QueryBuilderCheckEntitlementsState.js +20 -6
  52. package/lib/stores/entitlements/QueryBuilderCheckEntitlementsState.js.map +1 -1
  53. package/package.json +12 -10
  54. package/src/__lib__/QueryBuilderColorTheme.ts +23 -0
  55. package/src/components/QueryBuilder.tsx +63 -47
  56. package/src/components/QueryBuilder_LegendApplicationPlugin.ts +4 -0
  57. package/src/components/QueryLoader.tsx +4 -1
  58. package/src/components/data-access/DataAccessOverview.tsx +308 -0
  59. package/src/components/execution-plan/ExecutionPlanViewer.tsx +1 -3
  60. package/src/components/execution-plan/SQLExecutionNodeViewer.tsx +1 -1
  61. package/src/components/explorer/QueryBuilderPropertySearchPanel.tsx +1 -1
  62. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +99 -102
  63. package/src/components/shared/LambdaEditor.tsx +4 -21
  64. package/src/index.ts +4 -0
  65. package/src/stores/QueryBuilderState.ts +65 -19
  66. package/src/stores/QueryBuilder_LegendApplicationPlugin_Extension.ts +10 -0
  67. package/src/stores/data-access/DataAccessState.ts +322 -0
  68. package/src/stores/entitlements/QueryBuilderCheckEntitlementsState.ts +53 -6
  69. package/tsconfig.json +3 -0
@@ -0,0 +1,308 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { useEffect } from 'react';
18
+ import { observer } from 'mobx-react-lite';
19
+ import { useApplicationStore } from '@finos/legend-application';
20
+ import type {
21
+ DataAccessState,
22
+ DatasetAccessInfo,
23
+ } from '../../stores/data-access/DataAccessState.js';
24
+ import {
25
+ CheckCircleIcon,
26
+ ExclamationCircleIcon,
27
+ MinusCircleIcon,
28
+ PanelLoadingIndicator,
29
+ RefreshIcon,
30
+ TimesCircleIcon,
31
+ clsx,
32
+ } from '@finos/legend-art';
33
+ import {
34
+ DataGrid,
35
+ type DataGridCellRendererParams,
36
+ } from '@finos/legend-lego/data-grid';
37
+ import {
38
+ DatasetEntitlementAccessApprovedReport,
39
+ DatasetEntitlementAccessGrantedReport,
40
+ DatasetEntitlementAccessNotGrantedReport,
41
+ DatasetEntitlementAccessRequestedReport,
42
+ DatasetEntitlementUnsupportedReport,
43
+ } from '@finos/legend-graph';
44
+ import { Doughnut } from 'react-chartjs-2';
45
+ import { getNullableFirstEntry } from '@finos/legend-shared';
46
+ import type { QueryBuilder_LegendApplicationPlugin_Extension } from '../../stores/QueryBuilder_LegendApplicationPlugin_Extension.js';
47
+
48
+ const DataAccessOverviewChart = observer(
49
+ (props: { dataAccessState: DataAccessState }) => {
50
+ const { dataAccessState } = props;
51
+ const applicationStore = useApplicationStore();
52
+ const entitlementCheckInfo = dataAccessState.entitlementCheckInfo;
53
+ const total = entitlementCheckInfo.total;
54
+ const accessGrantedCount =
55
+ getNullableFirstEntry(entitlementCheckInfo.data)?.count ?? 0;
56
+ const accessGrantedPercentage =
57
+ getNullableFirstEntry(entitlementCheckInfo.data)?.percentage ?? 0;
58
+
59
+ return (
60
+ <div className="data-access-overview__chart">
61
+ <div className="data-access-overview__chart__actions">
62
+ <button
63
+ className="data-access-overview__chart__actions__refresh-btn btn--dark"
64
+ tabIndex={-1}
65
+ title="Refresh"
66
+ onClick={() => {
67
+ dataAccessState
68
+ .refresh()
69
+ .catch(applicationStore.alertUnhandledError);
70
+ }}
71
+ >
72
+ <RefreshIcon />
73
+ </button>
74
+ </div>
75
+ <div className="data-access-overview__chart__container">
76
+ <Doughnut
77
+ data={{
78
+ labels: entitlementCheckInfo.data.map((item) => item.label),
79
+ datasets: [
80
+ {
81
+ data: entitlementCheckInfo.data.map((item) => item.count),
82
+ backgroundColor: entitlementCheckInfo.data.map(
83
+ (item) => item.color,
84
+ ),
85
+ hoverBorderWidth: 0,
86
+ borderWidth: 0,
87
+ },
88
+ ],
89
+ }}
90
+ options={{
91
+ responsive: true,
92
+ resizeDelay: 0,
93
+ maintainAspectRatio: false,
94
+ cutout: '75%',
95
+ plugins: {
96
+ tooltip: {
97
+ enabled: total !== 0,
98
+ usePointStyle: false,
99
+ boxPadding: 5,
100
+ callbacks: {
101
+ labelPointStyle: () => ({
102
+ pointStyle: 'rectRounded',
103
+ rotation: 0,
104
+ }),
105
+ },
106
+ },
107
+ },
108
+ }}
109
+ />
110
+ <div className="data-access-overview__chart__stats">
111
+ <div className="data-access-overview__chart__stats__percentage">
112
+ {accessGrantedPercentage}%
113
+ </div>
114
+ <div className="data-access-overview__chart__stats__tally">
115
+ {total === 0 ? 0 : accessGrantedCount}/{total}
116
+ </div>
117
+ </div>
118
+ </div>
119
+ </div>
120
+ );
121
+ },
122
+ );
123
+
124
+ const AccessStatusCellRenderer = observer(
125
+ (
126
+ params: DataGridCellRendererParams<DatasetAccessInfo> & {
127
+ dataAccessState: DataAccessState;
128
+ },
129
+ ) => {
130
+ const { data } = params;
131
+ const applicationStore = useApplicationStore();
132
+
133
+ if (!data) {
134
+ return null;
135
+ }
136
+
137
+ if (
138
+ data.entitlementReport instanceof DatasetEntitlementAccessGrantedReport
139
+ ) {
140
+ return (
141
+ <div className="data-access-overview__grid__access-status-cell">
142
+ <div className="data-access-overview__grid__access-status-cell__content">
143
+ <div className="data-access-overview__grid__access-status-cell__icon data-access-overview__grid__access-status-cell__icon--access-granted">
144
+ <CheckCircleIcon />
145
+ </div>
146
+ <div className="data-access-overview__grid__access-status-cell__text">
147
+ Access Granted
148
+ </div>
149
+ </div>
150
+ </div>
151
+ );
152
+ } else if (
153
+ data.entitlementReport instanceof DatasetEntitlementAccessApprovedReport
154
+ ) {
155
+ return (
156
+ <div className="data-access-overview__grid__access-status-cell">
157
+ <div className="data-access-overview__grid__access-status-cell__content">
158
+ <div className="data-access-overview__grid__access-status-cell__icon data-access-overview__grid__access-status-cell__icon--access-approved">
159
+ <MinusCircleIcon />
160
+ </div>
161
+ <div className="data-access-overview__grid__access-status-cell__text">
162
+ Access Approved
163
+ </div>
164
+ </div>
165
+ </div>
166
+ );
167
+ } else if (
168
+ data.entitlementReport instanceof DatasetEntitlementAccessRequestedReport
169
+ ) {
170
+ return (
171
+ <div className="data-access-overview__grid__access-status-cell">
172
+ <div className="data-access-overview__grid__access-status-cell__content">
173
+ <div className="data-access-overview__grid__access-status-cell__icon data-access-overview__grid__access-status-cell__icon--access-requested">
174
+ <ExclamationCircleIcon />
175
+ </div>
176
+ <div className="data-access-overview__grid__access-status-cell__text">
177
+ Access Requested
178
+ </div>
179
+ </div>
180
+ </div>
181
+ );
182
+ } else if (
183
+ data.entitlementReport instanceof DatasetEntitlementAccessNotGrantedReport
184
+ ) {
185
+ const plugins = applicationStore.pluginManager
186
+ .getApplicationPlugins()
187
+ .flatMap(
188
+ (plugin) =>
189
+ (
190
+ plugin as QueryBuilder_LegendApplicationPlugin_Extension
191
+ ).getExtraDatasetEntitlementAccessNotGrantedReportActionConfigurations?.() ??
192
+ [],
193
+ );
194
+ let action: React.ReactNode | undefined;
195
+ for (const plugin of plugins) {
196
+ action = plugin.renderer(data);
197
+ if (action) {
198
+ break;
199
+ }
200
+ }
201
+ return (
202
+ <div className="data-access-overview__grid__access-status-cell">
203
+ <div className="data-access-overview__grid__access-status-cell__content">
204
+ <div className="data-access-overview__grid__access-status-cell__icon data-access-overview__grid__access-status-cell__icon--access-not-granted">
205
+ <TimesCircleIcon />
206
+ </div>
207
+ <div className="data-access-overview__grid__access-status-cell__text">
208
+ Access Not Granted
209
+ </div>
210
+ </div>
211
+ {action && (
212
+ <div className="data-access-overview__grid__access-status-cell__action">
213
+ {action}
214
+ </div>
215
+ )}
216
+ </div>
217
+ );
218
+ } else if (
219
+ data.entitlementReport instanceof DatasetEntitlementUnsupportedReport
220
+ ) {
221
+ return (
222
+ <div className="data-access-overview__grid__empty-cell">
223
+ (unsupported)
224
+ </div>
225
+ );
226
+ }
227
+
228
+ return null;
229
+ },
230
+ );
231
+
232
+ const DataAccessOverviewGrid = observer(
233
+ (props: { dataAccessState: DataAccessState }) => {
234
+ const { dataAccessState } = props;
235
+
236
+ return (
237
+ <div className="data-access-overview__grid ag-theme-balham-dark">
238
+ <DataGrid
239
+ rowData={dataAccessState.datasets}
240
+ gridOptions={{
241
+ suppressScrollOnNewData: true,
242
+ getRowId: (rowData) => rowData.data.uuid,
243
+ }}
244
+ columnDefs={[
245
+ {
246
+ minWidth: 50,
247
+ sortable: true,
248
+ resizable: true,
249
+ field: 'specification.name',
250
+ headerName: 'Dataset',
251
+ flex: 1,
252
+ },
253
+ {
254
+ minWidth: 50,
255
+ sortable: true,
256
+ resizable: true,
257
+ field: 'specification.type',
258
+ headerName: 'Type',
259
+ flex: 1,
260
+ },
261
+ {
262
+ minWidth: 50,
263
+ sortable: true,
264
+ resizable: true,
265
+ headerName: 'Access Status',
266
+ cellRendererParams: {
267
+ dataAccessState,
268
+ },
269
+ cellRenderer: AccessStatusCellRenderer,
270
+ flex: 1,
271
+ },
272
+ ]}
273
+ />
274
+ </div>
275
+ );
276
+ },
277
+ );
278
+
279
+ export const DataAccessOverview = observer(
280
+ (props: {
281
+ dataAccessState: DataAccessState;
282
+ compact?: boolean | undefined;
283
+ }) => {
284
+ const { dataAccessState, compact } = props;
285
+ const applicationStore = useApplicationStore();
286
+
287
+ useEffect(() => {
288
+ dataAccessState.intialize().catch(applicationStore.alertUnhandledError);
289
+ }, [applicationStore, dataAccessState]);
290
+
291
+ return (
292
+ <div
293
+ className={clsx('data-access-overview', {
294
+ 'data-access-overview--compact': Boolean(compact),
295
+ })}
296
+ >
297
+ <PanelLoadingIndicator
298
+ isLoading={
299
+ dataAccessState.surveyDatasetsState.isInProgress ||
300
+ dataAccessState.checkEntitlementsState.isInProgress
301
+ }
302
+ />
303
+ <DataAccessOverviewChart dataAccessState={dataAccessState} />
304
+ <DataAccessOverviewGrid dataAccessState={dataAccessState} />
305
+ </div>
306
+ );
307
+ },
308
+ );
@@ -380,7 +380,7 @@ const ExecutionPlanViewPanel = observer(
380
380
  inputValue={displayData}
381
381
  isReadOnly={true}
382
382
  language={CODE_EDITOR_LANGUAGE.JSON}
383
- showMiniMap={false}
383
+ hideMinimap={true}
384
384
  />
385
385
  )}
386
386
  {executionPlanState.viewMode ===
@@ -462,7 +462,6 @@ const ExecutionPlanViewerContent = observer(
462
462
  inputValue={JSON.stringify(rawPlan, undefined, DEFAULT_TAB_SIZE)}
463
463
  isReadOnly={true}
464
464
  language={CODE_EDITOR_LANGUAGE.JSON}
465
- showMiniMap={true}
466
465
  />
467
466
  )}
468
467
  </div>
@@ -523,7 +522,6 @@ export const ExecutionPlanViewer = observer(
523
522
  inputValue={executionPlanState.debugText}
524
523
  isReadOnly={true}
525
524
  language={CODE_EDITOR_LANGUAGE.TEXT}
526
- showMiniMap={true}
527
525
  />
528
526
  </PanelContent>
529
527
  </div>
@@ -42,7 +42,7 @@ export const SQLExecutionNodeViewer: React.FC<{
42
42
  inputValue={formatSQL(query)}
43
43
  isReadOnly={true}
44
44
  language={CODE_EDITOR_LANGUAGE.SQL}
45
- showMiniMap={false}
45
+ hideMinimap={true}
46
46
  />
47
47
  );
48
48
  });
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import React, { useMemo, useRef, useState } from 'react';
17
+ import { useMemo, useRef, useState } from 'react';
18
18
  import {
19
19
  clsx,
20
20
  CheckSquareIcon,
@@ -39,8 +39,8 @@ import {
39
39
  CalendarIcon,
40
40
  CalendarClockIcon,
41
41
  CustomSelectorInput,
42
- PURE_FunctionIcon,
43
42
  PanelEntryDropZonePlaceholder,
43
+ FunctionIcon,
44
44
  } from '@finos/legend-art';
45
45
  import {
46
46
  type QueryBuilderExplorerTreeDragSource,
@@ -102,62 +102,6 @@ import { getPropertyChainName } from '../../stores/QueryBuilderPropertyEditorSta
102
102
  import { generateDefaultValueForPrimitiveType } from '../../stores/QueryBuilderValueSpecificationHelper.js';
103
103
  import { QUERY_BUILDER_CALENDAR_TYPE } from '../../graph-manager/QueryBuilderConst.js';
104
104
 
105
- export type CalendarFunctionOption = {
106
- label: string | React.ReactNode;
107
- value: QueryBuilderAggregateCalendarFunction;
108
- };
109
-
110
- export const buildCalendarFunctionOption = (
111
- calendarFunction: QueryBuilderAggregateCalendarFunction,
112
- ): CalendarFunctionOption => ({
113
- label: (
114
- <div
115
- className="query-builder__projection__calendar__function__label"
116
- title={calendarFunction.getLabel()}
117
- >
118
- <PURE_FunctionIcon />
119
- <div className="query-builder__projection__calendar__function__label__title">
120
- {calendarFunction.getLabel()}
121
- </div>
122
- </div>
123
- ),
124
- value: calendarFunction,
125
- });
126
-
127
- export type CalendarFunctionDateColumnOption = {
128
- label: string;
129
- value: AbstractPropertyExpression;
130
- };
131
-
132
- export const buildCalendarFunctionDateColumnOption = (
133
- dateColumn: Property | AbstractPropertyExpression,
134
- parameter: VariableExpression,
135
- humanizeLabel: boolean,
136
- ): CalendarFunctionDateColumnOption => {
137
- if (dateColumn instanceof Property) {
138
- const propertyExpression = new AbstractPropertyExpression('');
139
- propertyExpression_setFunc(
140
- propertyExpression,
141
- PropertyExplicitReference.create(guaranteeNonNullable(dateColumn)),
142
- );
143
- propertyExpression.parametersValues = [parameter];
144
- return {
145
- label: getPropertyChainName(propertyExpression, humanizeLabel),
146
- value: propertyExpression,
147
- };
148
- } else {
149
- return {
150
- label: getPropertyChainName(dateColumn, humanizeLabel),
151
- value: dateColumn,
152
- };
153
- }
154
- };
155
-
156
- export type CalendarTypeOption = {
157
- label: string;
158
- value: QUERY_BUILDER_CALENDAR_TYPE;
159
- };
160
-
161
105
  const QueryBuilderProjectionColumnContextMenu = observer(
162
106
  forwardRef<
163
107
  HTMLDivElement,
@@ -304,6 +248,76 @@ const QueryBuilderDerivationProjectionColumnEditor = observer(
304
248
  },
305
249
  );
306
250
 
251
+ type CalendarFunctionOption = {
252
+ label: string | React.ReactNode;
253
+ value: QueryBuilderAggregateCalendarFunction;
254
+ };
255
+
256
+ const buildCalendarFunctionOption = (
257
+ calendarFunction: QueryBuilderAggregateCalendarFunction,
258
+ ): CalendarFunctionOption => ({
259
+ label: (
260
+ <div
261
+ className="query-builder__projection__calendar__function__label"
262
+ title={calendarFunction.getLabel()}
263
+ >
264
+ <FunctionIcon className="query-builder__projection__calendar__function__label__icon" />
265
+ <div className="query-builder__projection__calendar__function__label__title">
266
+ {calendarFunction.getLabel()}
267
+ </div>
268
+ </div>
269
+ ),
270
+ value: calendarFunction,
271
+ });
272
+
273
+ type CalendarFunctionDateColumnOption = {
274
+ label: React.ReactNode;
275
+ value: AbstractPropertyExpression;
276
+ };
277
+
278
+ const buildCalendarFunctionDateColumnOption = (
279
+ dateColumn: Property | AbstractPropertyExpression,
280
+ parameter: VariableExpression,
281
+ humanizeLabel: boolean,
282
+ ): CalendarFunctionDateColumnOption => {
283
+ if (dateColumn instanceof Property) {
284
+ const propertyExpression = new AbstractPropertyExpression('');
285
+ propertyExpression_setFunc(
286
+ propertyExpression,
287
+ PropertyExplicitReference.create(guaranteeNonNullable(dateColumn)),
288
+ );
289
+ propertyExpression.parametersValues = [parameter];
290
+ return {
291
+ label: getPropertyChainName(propertyExpression, humanizeLabel),
292
+ value: propertyExpression,
293
+ };
294
+ } else {
295
+ return {
296
+ label: getPropertyChainName(dateColumn, humanizeLabel),
297
+ value: dateColumn,
298
+ };
299
+ }
300
+ };
301
+
302
+ type CalendarTypeOption = {
303
+ label: React.ReactNode;
304
+ value: QUERY_BUILDER_CALENDAR_TYPE;
305
+ };
306
+
307
+ const buildCalendarTypeOption = (
308
+ val: QUERY_BUILDER_CALENDAR_TYPE,
309
+ ): CalendarTypeOption => ({
310
+ label: (
311
+ <div className="query-builder__projection__calendar__type__option">
312
+ <CalendarIcon className="query-builder__projection__calendar__type__option__icon" />
313
+ <div className="query-builder__projection__calendar__type__option__title">
314
+ {val}
315
+ </div>
316
+ </div>
317
+ ),
318
+ value: val,
319
+ });
320
+
307
321
  const QueryBuilderProjectionColumnEditor = observer(
308
322
  (props: { projectionColumnState: QueryBuilderProjectionColumnState }) => {
309
323
  const handleRef = useRef<HTMLDivElement>(null);
@@ -369,31 +383,13 @@ const QueryBuilderProjectionColumnEditor = observer(
369
383
  ),
370
384
  );
371
385
  const calendarTypeOptions = Object.values(QUERY_BUILDER_CALENDAR_TYPE).map(
372
- (ct) => ({
373
- label: (
374
- <div className="query-builder__projection__calendar__type__option">
375
- <CalendarIcon />
376
- <div className="query-builder__projection__calendar__type__option__title">
377
- {ct}
378
- </div>
379
- </div>
380
- ),
381
- value: ct,
382
- }),
386
+ buildCalendarTypeOption,
383
387
  );
384
388
  const selectedCalendarTypeOption = aggregateColumnState?.calendarFunction
385
389
  ?.calendarType
386
- ? {
387
- label: (
388
- <div className="query-builder__projection__calendar__type__option">
389
- <CalendarIcon />
390
- <div className="query-builder__projection__calendar__type__option__title">
391
- {aggregateColumnState.calendarFunction.calendarType}
392
- </div>
393
- </div>
394
- ),
395
- value: aggregateColumnState.calendarFunction.calendarType,
396
- }
390
+ ? buildCalendarTypeOption(
391
+ aggregateColumnState.calendarFunction.calendarType,
392
+ )
397
393
  : null;
398
394
  const onCalendarTypeOptionChange = (option: CalendarTypeOption): void => {
399
395
  if (
@@ -661,13 +657,15 @@ const QueryBuilderProjectionColumnEditor = observer(
661
657
  aggregateColumnState &&
662
658
  aggregateCalendarFunctions.length > 0 && (
663
659
  <div
664
- className={
665
- aggregateColumnState.hideCalendarColumnState
666
- ? 'query-builder__projection__column__aggregate__calendar--clock--icon__hidden'
667
- : 'query-builder__projection__column__aggregate__calendar--clock--icon'
668
- }
660
+ className={clsx(
661
+ 'query-builder__projection__column__aggregate__calendar__toggler',
662
+ {
663
+ 'query-builder__projection__column__aggregate__calendar__toggler--active':
664
+ !aggregateColumnState.hideCalendarColumnState,
665
+ },
666
+ )}
669
667
  onClick={toggleHideCalendarColumnState}
670
- title="Click to select calendar function"
668
+ title="Toggle calendar aggregation"
671
669
  >
672
670
  <CalendarClockIcon />
673
671
  </div>
@@ -749,21 +747,19 @@ const QueryBuilderProjectionColumnEditor = observer(
749
747
  },
750
748
  )}
751
749
  >
752
- <div data-testid="test">
753
- <CustomSelectorInput
754
- className="query-builder__projection__calendar__function"
755
- options={calendarFunctionOptions}
756
- onChange={onCalendarFunctionOptionChange}
757
- value={selectedCalendarFunctionOption}
758
- placeholder={'Select Calendar Function'}
759
- isClearable={true}
760
- escapeClearsValue={true}
761
- darkMode={
762
- !applicationStore.layoutService
763
- .TEMPORARY__isLightColorThemeEnabled
764
- }
765
- />
766
- </div>
750
+ <CustomSelectorInput
751
+ className="query-builder__projection__calendar__function"
752
+ options={calendarFunctionOptions}
753
+ onChange={onCalendarFunctionOptionChange}
754
+ value={selectedCalendarFunctionOption}
755
+ placeholder="Select Calendar Function"
756
+ isClearable={true}
757
+ escapeClearsValue={true}
758
+ darkMode={
759
+ !applicationStore.layoutService
760
+ .TEMPORARY__isLightColorThemeEnabled
761
+ }
762
+ />
767
763
  <div className="query-builder__projection__calendar__value">
768
764
  <BasicValueSpecificationEditor
769
765
  valueSpecification={
@@ -807,7 +803,7 @@ const QueryBuilderProjectionColumnEditor = observer(
807
803
  </div>
808
804
  </div>
809
805
  ) : (
810
- <div className="query-builder__projection__calendar__date__column__dnd__placeholder">
806
+ <div className="query-builder__projection__calendar__date__column__placeholder">
811
807
  Drag and drop date column here
812
808
  </div>
813
809
  )}
@@ -818,7 +814,8 @@ const QueryBuilderProjectionColumnEditor = observer(
818
814
  options={calendarTypeOptions}
819
815
  onChange={onCalendarTypeOptionChange}
820
816
  value={selectedCalendarTypeOption ?? calendarTypeOptions[0]}
821
- placeholder={'Select calendar type'}
817
+ placeholder="Select calendar type"
818
+ disabled={!aggregateColumnState.calendarFunction}
822
819
  darkMode={
823
820
  !applicationStore.layoutService
824
821
  .TEMPORARY__isLightColorThemeEnabled
@@ -23,7 +23,6 @@ import {
23
23
  LongArrowAltDownIcon,
24
24
  LongArrowAltUpIcon,
25
25
  Dialog,
26
- useResizeDetector,
27
26
  Modal,
28
27
  ModalBody,
29
28
  ModalFooter,
@@ -154,13 +153,6 @@ const LambdaEditorInline = observer(
154
153
  }
155
154
  };
156
155
 
157
- const { ref, width, height } = useResizeDetector<HTMLDivElement>();
158
- useEffect(() => {
159
- if (width !== undefined && height !== undefined) {
160
- editor?.layout({ width, height });
161
- }
162
- }, [editor, width, height]);
163
-
164
156
  useEffect(() => {
165
157
  if (!editor && textInputRef.current) {
166
158
  const element = textInputRef.current;
@@ -187,8 +179,8 @@ const LambdaEditorInline = observer(
187
179
  language: CODE_EDITOR_LANGUAGE.PURE,
188
180
  theme: applicationStore.layoutService
189
181
  .TEMPORARY__isLightColorThemeEnabled
190
- ? CODE_EDITOR_THEME.TEMPORARY__VSCODE_LIGHT
191
- : CODE_EDITOR_THEME.LEGEND,
182
+ ? CODE_EDITOR_THEME.BUILT_IN__VSCODE_LIGHT
183
+ : CODE_EDITOR_THEME.DEFAULT_DARK,
192
184
  ...lambdaEditorOptions,
193
185
  });
194
186
  setEditor(_editor);
@@ -341,7 +333,6 @@ const LambdaEditorInline = observer(
341
333
  })}
342
334
  >
343
335
  <div
344
- ref={ref}
345
336
  data-testid={QUERY_BUILDER_TEST_ID.LAMBDA_EDITOR__EDITOR_INPUT}
346
337
  className="lambda-editor__editor__input"
347
338
  >
@@ -451,13 +442,6 @@ const LambdaEditorPopUp = observer(
451
442
  transformLambdaToString(true),
452
443
  );
453
444
 
454
- const { ref, width, height } = useResizeDetector<HTMLDivElement>();
455
- useEffect(() => {
456
- if (width !== undefined && height !== undefined) {
457
- editor?.layout({ width, height });
458
- }
459
- }, [editor, width, height]);
460
-
461
445
  const onEnter = (): void => {
462
446
  if (!editor && textInputRef.current) {
463
447
  const element = textInputRef.current;
@@ -466,8 +450,8 @@ const LambdaEditorPopUp = observer(
466
450
  language: CODE_EDITOR_LANGUAGE.PURE,
467
451
  theme: applicationStore.layoutService
468
452
  .TEMPORARY__isLightColorThemeEnabled
469
- ? CODE_EDITOR_THEME.TEMPORARY__VSCODE_LIGHT
470
- : CODE_EDITOR_THEME.LEGEND,
453
+ ? CODE_EDITOR_THEME.BUILT_IN__VSCODE_LIGHT
454
+ : CODE_EDITOR_THEME.DEFAULT_DARK,
471
455
  });
472
456
  setEditor(_editor);
473
457
  }
@@ -613,7 +597,6 @@ const LambdaEditorPopUp = observer(
613
597
  <ModalBody>
614
598
  <div className={clsx('lambda-editor__popup__content', className)}>
615
599
  <div
616
- ref={ref}
617
600
  data-testid={QUERY_BUILDER_TEST_ID.LAMBDA_EDITOR__EDITOR_INPUT}
618
601
  className="lambda-editor__editor__input"
619
602
  >
package/src/index.ts CHANGED
@@ -70,6 +70,10 @@ export * from './stores/shared/ValueSpecificationEditorHelper.js';
70
70
 
71
71
  export * from './components/execution-plan/ExecutionPlanViewer.js';
72
72
  export * from './stores/execution-plan/ExecutionPlanState.js';
73
+
73
74
  export * from './components/QueryLoader.js';
74
75
  export * from './stores/QueryLoaderState.js';
75
76
  export * from './stores/QueryBuilder_LegendApplicationPlugin_Extension.js';
77
+
78
+ export * from './stores/data-access/DataAccessState.js';
79
+ export * from './components/data-access/DataAccessOverview.js';