@finos/legend-query-builder 4.0.11 → 4.0.12

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.
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-query-builder",
3
- "version": "4.0.11",
3
+ "version": "4.0.12",
4
4
  "description": "Legend query builder core",
5
5
  "keywords": [
6
6
  "legend",
@@ -62,7 +62,7 @@
62
62
  "react-dnd": "16.0.1",
63
63
  "react-dom": "18.2.0",
64
64
  "serializr": "3.0.2",
65
- "sql-formatter": "12.2.2"
65
+ "sql-formatter": "12.2.3"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@finos/legend-dev-utils": "workspace:*",
@@ -72,7 +72,7 @@
72
72
  "jest": "29.5.0",
73
73
  "npm-run-all": "4.1.5",
74
74
  "rimraf": "5.0.1",
75
- "sass": "1.63.3",
75
+ "sass": "1.63.4",
76
76
  "typescript": "5.1.3"
77
77
  },
78
78
  "peerDependencies": {
@@ -200,7 +200,7 @@ export class QueryBuilderResultState {
200
200
  }
201
201
  }
202
202
  catch (error) {
203
- // When user cancels the query by calling the cancelQuery api, it will throw an exeuction failure error.
203
+ // When user cancels the query by calling the cancelQuery api, it will throw an execution failure error.
204
204
  // For now, we don't want to notify users about this failure. Therefore we check to ensure the promise is still the same one.
205
205
  // When cancelled the query, we set the queryRunPromise as undefined.
206
206
  if (this.queryRunPromise === promise) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-query-builder",
3
- "version": "4.0.11",
3
+ "version": "4.0.12",
4
4
  "description": "Legend query builder core",
5
5
  "keywords": [
6
6
  "legend",
@@ -42,13 +42,13 @@
42
42
  "test:watch": "jest --watch"
43
43
  },
44
44
  "dependencies": {
45
- "@finos/legend-application": "15.0.22",
46
- "@finos/legend-art": "7.0.22",
47
- "@finos/legend-graph": "30.0.7",
48
- "@finos/legend-lego": "1.0.20",
49
- "@finos/legend-server-depot": "6.0.14",
50
- "@finos/legend-shared": "10.0.13",
51
- "@finos/legend-storage": "3.0.63",
45
+ "@finos/legend-application": "15.0.23",
46
+ "@finos/legend-art": "7.0.23",
47
+ "@finos/legend-graph": "30.0.8",
48
+ "@finos/legend-lego": "1.0.21",
49
+ "@finos/legend-server-depot": "6.0.15",
50
+ "@finos/legend-shared": "10.0.14",
51
+ "@finos/legend-storage": "3.0.64",
52
52
  "@testing-library/react": "14.0.0",
53
53
  "@types/react": "18.2.12",
54
54
  "@types/react-dom": "18.2.5",
@@ -62,17 +62,17 @@
62
62
  "react-dnd": "16.0.1",
63
63
  "react-dom": "18.2.0",
64
64
  "serializr": "3.0.2",
65
- "sql-formatter": "12.2.2"
65
+ "sql-formatter": "12.2.3"
66
66
  },
67
67
  "devDependencies": {
68
- "@finos/legend-dev-utils": "2.0.67",
68
+ "@finos/legend-dev-utils": "2.0.68",
69
69
  "@jest/globals": "29.5.0",
70
70
  "cross-env": "7.0.3",
71
71
  "eslint": "8.42.0",
72
72
  "jest": "29.5.0",
73
73
  "npm-run-all": "4.1.5",
74
74
  "rimraf": "5.0.1",
75
- "sass": "1.63.3",
75
+ "sass": "1.63.4",
76
76
  "typescript": "5.1.3"
77
77
  },
78
78
  "peerDependencies": {
@@ -126,11 +126,11 @@ const QueryBuilderGridResultContextMenu = observer(
126
126
  forwardRef<
127
127
  HTMLDivElement,
128
128
  {
129
- event: QueryBuilderTDSResultCellData | null;
129
+ data: QueryBuilderTDSResultCellData | null;
130
130
  tdsState: QueryBuilderTDSState;
131
131
  }
132
132
  >(function QueryBuilderResultContextMenu(props, ref) {
133
- const { event, tdsState } = props;
133
+ const { data, tdsState } = props;
134
134
  const applicationStore = useApplicationStore();
135
135
  const postFilterEqualOperator = new QueryBuilderPostFilterOperator_Equal();
136
136
  const postFilterInOperator = new QueryBuilderPostFilterOperator_In();
@@ -145,10 +145,10 @@ const QueryBuilderGridResultContextMenu = observer(
145
145
  const postFilterState = tdsState.postFilterState;
146
146
 
147
147
  const projectionColumnState = tdsState.projectionColumns
148
- .filter((c) => c.columnName === event?.columnName)
148
+ .filter((c) => c.columnName === data?.columnName)
149
149
  .concat(
150
150
  tdsState.aggregationState.columns
151
- .filter((c) => c.columnName === event?.columnName)
151
+ .filter((c) => c.columnName === data?.columnName)
152
152
  .map((ag) => ag.projectionColumnState),
153
153
  )[0];
154
154
  const getExistingPostFilterNode = (
@@ -319,7 +319,7 @@ const QueryBuilderGridResultContextMenu = observer(
319
319
  : (v as InstanceValue).values,
320
320
  )
321
321
  .flat()
322
- .includes(cellData.value ?? event?.value);
322
+ .includes(cellData.value ?? data?.value);
323
323
 
324
324
  if (!doesValueAlreadyExist) {
325
325
  const newValueSpecification = (
@@ -399,7 +399,7 @@ const QueryBuilderGridResultContextMenu = observer(
399
399
 
400
400
  const handleCopyCellValue = applicationStore.guardUnhandledError(() =>
401
401
  applicationStore.clipboardService.copyTextToClipboard(
402
- event?.value?.toString() ?? '',
402
+ data?.value?.toString() ?? '',
403
403
  ),
404
404
  );
405
405
 
@@ -597,7 +597,7 @@ const QueryResultCellRenderer = observer(
597
597
  // NOTE: we only support this functionality for grid result with a projection fetch-structure
598
598
  fetchStructureImplementation instanceof QueryBuilderTDSState ? (
599
599
  <QueryBuilderGridResultContextMenu
600
- event={resultState.mousedOverCell}
600
+ data={resultState.mousedOverCell}
601
601
  tdsState={fetchStructureImplementation}
602
602
  />
603
603
  ) : null
@@ -960,70 +960,73 @@ export const QueryBuilderResultPanel = observer(
960
960
  />
961
961
  </div>
962
962
  )}
963
- {resultState.isRunningQuery ? (
964
- <button
965
- className="query-builder__result__stop-btn"
966
- onClick={cancelQuery}
967
- tabIndex={-1}
968
- disabled={!isQueryValid}
969
- >
970
- <div className="btn--dark btn--caution query-builder__result__stop-btn__label">
971
- <PauseCircleIcon className="query-builder__result__stop-btn__label__icon" />
972
- <div className="query-builder__result__stop-btn__label__title">
973
- Stop
974
- </div>
975
- </div>
976
- </button>
977
- ) : (
978
- <div className="query-builder__result__execute-btn">
963
+
964
+ <div className="query-builder__result__execute-btn btn__dropdown-combo btn__dropdown-combo--primary">
965
+ {resultState.isRunningQuery ? (
979
966
  <button
980
- className="query-builder__result__execute-btn__label"
981
- onClick={runQuery}
967
+ className="btn__dropdown-combo__canceler"
968
+ onClick={cancelQuery}
982
969
  tabIndex={-1}
983
- title={
984
- allValidationIssues.length
985
- ? `Query is not valid:\n${allValidationIssues
986
- .map((issue) => `\u2022 ${issue}`)
987
- .join('\n')}`
988
- : undefined
989
- }
990
- disabled={isRunQueryDisabled}
970
+ disabled={!isQueryValid}
991
971
  >
992
- <PlayIcon className="query-builder__result__execute-btn__label__icon" />
993
- <div className="query-builder__result__execute-btn__label__title">
994
- Run Query
972
+ <div className="btn--dark btn--caution btn__dropdown-combo__canceler__label">
973
+ <PauseCircleIcon className="btn__dropdown-combo__canceler__label__icon" />
974
+ <div className="btn__dropdown-combo__canceler__label__title">
975
+ Stop
976
+ </div>
995
977
  </div>
996
978
  </button>
997
- <DropdownMenu
998
- className="query-builder__result__execute-btn__dropdown-btn"
999
- disabled={isRunQueryDisabled}
1000
- content={
1001
- <MenuContent>
1002
- <MenuContentItem
1003
- className="query-builder__result__execute-btn__option"
1004
- onClick={generatePlan}
1005
- disabled={isRunQueryDisabled}
1006
- >
1007
- Generate Plan
1008
- </MenuContentItem>
1009
- <MenuContentItem
1010
- className="query-builder__result__execute-btn__option"
1011
- onClick={debugPlanGeneration}
1012
- disabled={isRunQueryDisabled}
1013
- >
1014
- Debug
1015
- </MenuContentItem>
1016
- </MenuContent>
1017
- }
1018
- menuProps={{
1019
- anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
1020
- transformOrigin: { vertical: 'top', horizontal: 'right' },
1021
- }}
1022
- >
1023
- <CaretDownIcon />
1024
- </DropdownMenu>
1025
- </div>
1026
- )}
979
+ ) : (
980
+ <>
981
+ <button
982
+ className="btn__dropdown-combo__label"
983
+ onClick={runQuery}
984
+ tabIndex={-1}
985
+ title={
986
+ allValidationIssues.length
987
+ ? `Query is not valid:\n${allValidationIssues
988
+ .map((issue) => `\u2022 ${issue}`)
989
+ .join('\n')}`
990
+ : undefined
991
+ }
992
+ disabled={isRunQueryDisabled}
993
+ >
994
+ <PlayIcon className="btn__dropdown-combo__label__icon" />
995
+ <div className="btn__dropdown-combo__label__title">
996
+ Run Query
997
+ </div>
998
+ </button>
999
+ <DropdownMenu
1000
+ className="btn__dropdown-combo__dropdown-btn"
1001
+ disabled={isRunQueryDisabled}
1002
+ content={
1003
+ <MenuContent>
1004
+ <MenuContentItem
1005
+ className="btn__dropdown-combo__option"
1006
+ onClick={generatePlan}
1007
+ disabled={isRunQueryDisabled}
1008
+ >
1009
+ Generate Plan
1010
+ </MenuContentItem>
1011
+ <MenuContentItem
1012
+ className="btn__dropdown-combo__option"
1013
+ onClick={debugPlanGeneration}
1014
+ disabled={isRunQueryDisabled}
1015
+ >
1016
+ Debug
1017
+ </MenuContentItem>
1018
+ </MenuContent>
1019
+ }
1020
+ menuProps={{
1021
+ anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
1022
+ transformOrigin: { vertical: 'top', horizontal: 'right' },
1023
+ }}
1024
+ >
1025
+ <CaretDownIcon />
1026
+ </DropdownMenu>
1027
+ </>
1028
+ )}
1029
+ </div>
1027
1030
  <DropdownMenu
1028
1031
  className="query-builder__result__export__dropdown"
1029
1032
  title="Export"
@@ -72,6 +72,17 @@ const DataAccessOverviewChart = observer(
72
72
  <RefreshIcon />
73
73
  </button>
74
74
  </div>
75
+ {Boolean(
76
+ dataAccessState.datasets.find(
77
+ (dataset) =>
78
+ dataset.entitlementReport instanceof
79
+ DatasetEntitlementUnsupportedReport,
80
+ ),
81
+ ) && (
82
+ <div className="data-access-overview__chart__warning">
83
+ Use case is not fully supported!
84
+ </div>
85
+ )}
75
86
  <div className="data-access-overview__chart__container">
76
87
  <Doughnut
77
88
  data={{
@@ -109,7 +120,7 @@ const DataAccessOverviewChart = observer(
109
120
  />
110
121
  <div className="data-access-overview__chart__stats">
111
122
  <div className="data-access-overview__chart__stats__percentage">
112
- {accessGrantedPercentage}%
123
+ {total === 0 ? 0 : accessGrantedPercentage}%
113
124
  </div>
114
125
  <div className="data-access-overview__chart__stats__tally">
115
126
  {total === 0 ? 0 : accessGrantedCount}/{total}
@@ -285,7 +296,10 @@ export const DataAccessOverview = observer(
285
296
  const applicationStore = useApplicationStore();
286
297
 
287
298
  useEffect(() => {
288
- dataAccessState.intialize().catch(applicationStore.alertUnhandledError);
299
+ // NOTE: @YannanGao-gs - force refresh for now, let's investigate why the data is empty
300
+ // when we fetched it from cache
301
+ dataAccessState.refresh().catch(applicationStore.alertUnhandledError);
302
+ // dataAccessState.intialize().catch(applicationStore.alertUnhandledError);
289
303
  }, [applicationStore, dataAccessState]);
290
304
 
291
305
  return (
@@ -28,6 +28,10 @@ import {
28
28
  PanelContent,
29
29
  } from '@finos/legend-art';
30
30
  import { tryToFormatSql } from '../QueryBuilderResultPanel.js';
31
+ import {
32
+ CodeEditor,
33
+ CODE_EDITOR_LANGUAGE,
34
+ } from '@finos/legend-lego/code-editor';
31
35
 
32
36
  /**
33
37
  * TODO: Create a new `AbstractPlugin` for this, called `ExecutionPlanViewerPlugin`
@@ -81,9 +85,12 @@ export const SQLExecutionNodeViewer: React.FC<{
81
85
  </div>
82
86
  </PanelListItem>
83
87
  </div>
84
- <PanelListItem className="query-builder__sql__container__item">
85
- <pre>{tryToFormatSql(query)} </pre>
86
- </PanelListItem>
88
+ <div className="query-builder__sql__container__code-editor">
89
+ <CodeEditor
90
+ inputValue={tryToFormatSql(query)}
91
+ language={CODE_EDITOR_LANGUAGE.SQL}
92
+ />
93
+ </div>
87
94
  <PanelDivider />
88
95
  </div>
89
96
  </div>
@@ -1075,8 +1075,7 @@ const QueryBuilderPostFilterPanelContent = observer(
1075
1075
  <QueryBuilderPostFilterTree tdsState={tdsState} />
1076
1076
  </>
1077
1077
  )}
1078
-
1079
- {showDroppableSuggestion && (
1078
+ {showDroppableSuggestion && !postFilterState.isEmpty && (
1080
1079
  <div
1081
1080
  ref={dropTargetConnector}
1082
1081
  className={clsx(
@@ -345,7 +345,7 @@ export class QueryBuilderResultState {
345
345
  );
346
346
  }
347
347
  } catch (error) {
348
- // When user cancels the query by calling the cancelQuery api, it will throw an exeuction failure error.
348
+ // When user cancels the query by calling the cancelQuery api, it will throw an execution failure error.
349
349
  // For now, we don't want to notify users about this failure. Therefore we check to ensure the promise is still the same one.
350
350
  // When cancelled the query, we set the queryRunPromise as undefined.
351
351
  if (this.queryRunPromise === promise) {