@finos/legend-application-repl 0.0.2

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 (116) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +3 -0
  3. package/lib/Const.d.ts +25 -0
  4. package/lib/Const.d.ts.map +1 -0
  5. package/lib/Const.js +26 -0
  6. package/lib/Const.js.map +1 -0
  7. package/lib/application/LegendREPLGridClient.d.ts +27 -0
  8. package/lib/application/LegendREPLGridClient.d.ts.map +1 -0
  9. package/lib/application/LegendREPLGridClient.js +40 -0
  10. package/lib/application/LegendREPLGridClient.js.map +1 -0
  11. package/lib/application/LegendREPLGridClientApplicationConfig.d.ts +29 -0
  12. package/lib/application/LegendREPLGridClientApplicationConfig.d.ts.map +1 -0
  13. package/lib/application/LegendREPLGridClientApplicationConfig.js +33 -0
  14. package/lib/application/LegendREPLGridClientApplicationConfig.js.map +1 -0
  15. package/lib/application/LegendREPLGridClientPluginManager.d.ts +32 -0
  16. package/lib/application/LegendREPLGridClientPluginManager.d.ts.map +1 -0
  17. package/lib/application/LegendREPLGridClientPluginManager.js +46 -0
  18. package/lib/application/LegendREPLGridClientPluginManager.js.map +1 -0
  19. package/lib/components/AgGrid.d.ts +22 -0
  20. package/lib/components/AgGrid.d.ts.map +1 -0
  21. package/lib/components/AgGrid.js +43 -0
  22. package/lib/components/AgGrid.js.map +1 -0
  23. package/lib/components/Core_LegendREPLGridClientApplicationPlugin.d.ts +23 -0
  24. package/lib/components/Core_LegendREPLGridClientApplicationPlugin.d.ts.map +1 -0
  25. package/lib/components/Core_LegendREPLGridClientApplicationPlugin.js +35 -0
  26. package/lib/components/Core_LegendREPLGridClientApplicationPlugin.js.map +1 -0
  27. package/lib/components/LegendREPLGridClientApplication.d.ts +24 -0
  28. package/lib/components/LegendREPLGridClientApplication.d.ts.map +1 -0
  29. package/lib/components/LegendREPLGridClientApplication.js +32 -0
  30. package/lib/components/LegendREPLGridClientApplication.js.map +1 -0
  31. package/lib/components/LegendREPLGridClientFrameworkProvider.d.ts +22 -0
  32. package/lib/components/LegendREPLGridClientFrameworkProvider.d.ts.map +1 -0
  33. package/lib/components/LegendREPLGridClientFrameworkProvider.js +29 -0
  34. package/lib/components/LegendREPLGridClientFrameworkProvider.js.map +1 -0
  35. package/lib/components/REPLGridClient.d.ts +18 -0
  36. package/lib/components/REPLGridClient.d.ts.map +1 -0
  37. package/lib/components/REPLGridClient.js +56 -0
  38. package/lib/components/REPLGridClient.js.map +1 -0
  39. package/lib/components/REPLGridClientStoreProvider.d.ts +22 -0
  40. package/lib/components/REPLGridClientStoreProvider.d.ts.map +1 -0
  41. package/lib/components/REPLGridClientStoreProvider.js +32 -0
  42. package/lib/components/REPLGridClientStoreProvider.js.map +1 -0
  43. package/lib/components/grid/GridUtils.d.ts +29 -0
  44. package/lib/components/grid/GridUtils.d.ts.map +1 -0
  45. package/lib/components/grid/GridUtils.js +152 -0
  46. package/lib/components/grid/GridUtils.js.map +1 -0
  47. package/lib/components/grid/REPLGridServerResult.d.ts +22 -0
  48. package/lib/components/grid/REPLGridServerResult.d.ts.map +1 -0
  49. package/lib/components/grid/REPLGridServerResult.js +26 -0
  50. package/lib/components/grid/REPLGridServerResult.js.map +1 -0
  51. package/lib/components/grid/ServerSideDataSource.d.ts +32 -0
  52. package/lib/components/grid/ServerSideDataSource.d.ts.map +1 -0
  53. package/lib/components/grid/ServerSideDataSource.js +107 -0
  54. package/lib/components/grid/ServerSideDataSource.js.map +1 -0
  55. package/lib/components/grid/TDSLambdaBuilder.d.ts +19 -0
  56. package/lib/components/grid/TDSLambdaBuilder.d.ts.map +1 -0
  57. package/lib/components/grid/TDSLambdaBuilder.js +277 -0
  58. package/lib/components/grid/TDSLambdaBuilder.js.map +1 -0
  59. package/lib/components/grid/TDSRequest.d.ts +90 -0
  60. package/lib/components/grid/TDSRequest.d.ts.map +1 -0
  61. package/lib/components/grid/TDSRequest.js +120 -0
  62. package/lib/components/grid/TDSRequest.js.map +1 -0
  63. package/lib/grid.css +17 -0
  64. package/lib/grid.css.map +1 -0
  65. package/lib/index.css +17 -0
  66. package/lib/index.css.map +1 -0
  67. package/lib/index.d.ts +22 -0
  68. package/lib/index.d.ts.map +1 -0
  69. package/lib/index.js +37 -0
  70. package/lib/index.js.map +1 -0
  71. package/lib/package.json +88 -0
  72. package/lib/repl.css +17 -0
  73. package/lib/repl.css.map +1 -0
  74. package/lib/server/REPLServerClient.d.ts +28 -0
  75. package/lib/server/REPLServerClient.d.ts.map +1 -0
  76. package/lib/server/REPLServerClient.js +30 -0
  77. package/lib/server/REPLServerClient.js.map +1 -0
  78. package/lib/stores/LegendREPLGridClientApplicationPlugin.d.ts +26 -0
  79. package/lib/stores/LegendREPLGridClientApplicationPlugin.d.ts.map +1 -0
  80. package/lib/stores/LegendREPLGridClientApplicationPlugin.js +27 -0
  81. package/lib/stores/LegendREPLGridClientApplicationPlugin.js.map +1 -0
  82. package/lib/stores/LegendREPLGridClientBaseStore.d.ts +25 -0
  83. package/lib/stores/LegendREPLGridClientBaseStore.d.ts.map +1 -0
  84. package/lib/stores/LegendREPLGridClientBaseStore.js +24 -0
  85. package/lib/stores/LegendREPLGridClientBaseStore.js.map +1 -0
  86. package/lib/stores/REPLGridClientStore.d.ts +31 -0
  87. package/lib/stores/REPLGridClientStore.d.ts.map +1 -0
  88. package/lib/stores/REPLGridClientStore.js +101 -0
  89. package/lib/stores/REPLGridClientStore.js.map +1 -0
  90. package/lib/stores/REPLGridState.d.ts +38 -0
  91. package/lib/stores/REPLGridState.d.ts.map +1 -0
  92. package/lib/stores/REPLGridState.js +81 -0
  93. package/lib/stores/REPLGridState.js.map +1 -0
  94. package/package.json +88 -0
  95. package/src/Const.ts +27 -0
  96. package/src/application/LegendREPLGridClient.tsx +66 -0
  97. package/src/application/LegendREPLGridClientApplicationConfig.ts +64 -0
  98. package/src/application/LegendREPLGridClientPluginManager.ts +67 -0
  99. package/src/components/AgGrid.tsx +65 -0
  100. package/src/components/Core_LegendREPLGridClientApplicationPlugin.tsx +42 -0
  101. package/src/components/LegendREPLGridClientApplication.tsx +61 -0
  102. package/src/components/LegendREPLGridClientFrameworkProvider.tsx +63 -0
  103. package/src/components/REPLGridClient.tsx +157 -0
  104. package/src/components/REPLGridClientStoreProvider.tsx +61 -0
  105. package/src/components/grid/GridUtils.ts +190 -0
  106. package/src/components/grid/REPLGridServerResult.ts +30 -0
  107. package/src/components/grid/ServerSideDataSource.ts +184 -0
  108. package/src/components/grid/TDSLambdaBuilder.ts +413 -0
  109. package/src/components/grid/TDSRequest.ts +153 -0
  110. package/src/index.tsx +40 -0
  111. package/src/server/REPLServerClient.ts +74 -0
  112. package/src/stores/LegendREPLGridClientApplicationPlugin.ts +30 -0
  113. package/src/stores/LegendREPLGridClientBaseStore.ts +34 -0
  114. package/src/stores/REPLGridClientStore.ts +153 -0
  115. package/src/stores/REPLGridState.ts +102 -0
  116. package/tsconfig.json +66 -0
@@ -0,0 +1,157 @@
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 { observer } from 'mobx-react-lite';
18
+ import {
19
+ useREPLGridClientStore,
20
+ withEditorStore,
21
+ } from './REPLGridClientStoreProvider.js';
22
+ import { AgGridComponent } from './AgGrid.js';
23
+ import { useEffect } from 'react';
24
+ import { flowResult } from 'mobx';
25
+ import { getTDSRowData } from '../components/grid/GridUtils.js';
26
+ import { ServerSideDataSource } from '../components/grid/ServerSideDataSource.js';
27
+ import { LEGEND_APPLICATION_COLOR_THEME } from '@finos/legend-application';
28
+ import {
29
+ CODE_EDITOR_LANGUAGE,
30
+ CODE_EDITOR_THEME,
31
+ CodeDiffView,
32
+ CodeEditor,
33
+ } from '@finos/legend-lego/code-editor';
34
+
35
+ export const Editor = withEditorStore(
36
+ observer(() => {
37
+ const editorStore = useREPLGridClientStore();
38
+ const selectDarkTheme = (): void => {
39
+ editorStore.applicationStore.layoutService.setColorTheme(
40
+ LEGEND_APPLICATION_COLOR_THEME.DEFAULT_DARK,
41
+ { persist: true },
42
+ );
43
+ };
44
+ const title = `Current Query <-> Current Row Group Sub Query`;
45
+ const selectLightTheme = (): void => {
46
+ editorStore.applicationStore.layoutService.setColorTheme(
47
+ LEGEND_APPLICATION_COLOR_THEME.LEGACY_LIGHT,
48
+ { persist: true },
49
+ );
50
+ };
51
+ const isLightTheme =
52
+ editorStore.applicationStore.layoutService
53
+ .TEMPORARY__isLightColorThemeEnabled;
54
+
55
+ useEffect(() => {
56
+ flowResult(editorStore.getInitialREPLGridServerResult()).catch(
57
+ editorStore.applicationStore.alertUnhandledError,
58
+ );
59
+ }, [editorStore]);
60
+
61
+ return (
62
+ <div className="repl">
63
+ <div className="repl__header">
64
+ <div className="repl__header__content">
65
+ <div className="repl__header__content__title">REPL Grid</div>
66
+ <div className="repl__header__actions">
67
+ <button
68
+ className={
69
+ isLightTheme
70
+ ? 'repl__header__action'
71
+ : 'repl__header__action repl__header__action--toggled'
72
+ }
73
+ onClick={selectDarkTheme}
74
+ >
75
+ Dark
76
+ </button>
77
+ <button
78
+ className={
79
+ isLightTheme
80
+ ? 'repl__header__action repl__header__action--toggled'
81
+ : 'repl__header__action'
82
+ }
83
+ onClick={selectLightTheme}
84
+ >
85
+ Light
86
+ </button>
87
+ </div>
88
+ </div>
89
+ </div>
90
+ {editorStore.replGridState.initialResult &&
91
+ editorStore.replGridState.columns && (
92
+ <div className="repl__content">
93
+ {editorStore.replGridState.currentSubQuery !== undefined && (
94
+ <>
95
+ <div className="repl__query__label">{title}</div>
96
+ <div className="repl__query__content">
97
+ <CodeDiffView
98
+ language={CODE_EDITOR_LANGUAGE.PURE}
99
+ from={editorStore.replGridState.currentQuery}
100
+ to={editorStore.replGridState.currentSubQuery}
101
+ />
102
+ </div>
103
+ </>
104
+ )}
105
+ {editorStore.replGridState.currentSubQuery === undefined && (
106
+ <div className="repl__query">
107
+ <div className="repl__query__editor">
108
+ <div className="repl__query__label">Curent Query</div>
109
+ <div className="repl__query__content">
110
+ <CodeEditor
111
+ lightTheme={
112
+ isLightTheme
113
+ ? CODE_EDITOR_THEME.BUILT_IN__VSCODE_HC_LIGHT
114
+ : CODE_EDITOR_THEME.BUILT_IN__VSCODE_HC_BLACK
115
+ }
116
+ language={CODE_EDITOR_LANGUAGE.PURE}
117
+ inputValue={
118
+ editorStore.replGridState.currentQuery ?? ''
119
+ }
120
+ hideActionBar={true}
121
+ isReadOnly={true}
122
+ />
123
+ </div>
124
+ </div>
125
+ </div>
126
+ )}
127
+ <div className="repl__query__label">Result</div>
128
+ <AgGridComponent
129
+ className={
130
+ editorStore.applicationStore.layoutService
131
+ .TEMPORARY__isLightColorThemeEnabled
132
+ ? 'ag-theme-balham'
133
+ : 'ag-theme-balham-dark'
134
+ }
135
+ gridOptions={
136
+ editorStore.replGridState.licenseKey
137
+ ? {
138
+ serverSideDatasource: new ServerSideDataSource(
139
+ getTDSRowData(
140
+ editorStore.replGridState.initialResult.result,
141
+ ),
142
+ editorStore.replGridState.initialResult.builder.columns,
143
+ editorStore,
144
+ ),
145
+ }
146
+ : {}
147
+ }
148
+ licenseKey={editorStore.replGridState.licenseKey ?? ''}
149
+ rowData={editorStore.replGridState.rowData}
150
+ columnDefs={editorStore.replGridState.columnDefs}
151
+ />
152
+ </div>
153
+ )}
154
+ </div>
155
+ );
156
+ }),
157
+ );
@@ -0,0 +1,61 @@
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 { createContext, useContext } from 'react';
18
+ import { useLocalObservable } from 'mobx-react-lite';
19
+ import { REPLGridClientStore } from '../stores/REPLGridClientStore.js';
20
+ import { guaranteeNonNullable } from '@finos/legend-shared';
21
+ import { useApplicationStore } from '@finos/legend-application';
22
+ import type { LegendREPLGridClientApplicationConfig } from '../application/LegendREPLGridClientApplicationConfig.js';
23
+ import type { LegendREPLGridClientPluginManager } from '../application/LegendREPLGridClientPluginManager.js';
24
+
25
+ const EditorStoreContext = createContext<REPLGridClientStore | undefined>(
26
+ undefined,
27
+ );
28
+
29
+ export const REPLGridClientStoreProvider = ({
30
+ children,
31
+ }: {
32
+ children: React.ReactNode;
33
+ }): React.ReactElement => {
34
+ const applicationStore = useApplicationStore<
35
+ LegendREPLGridClientApplicationConfig,
36
+ LegendREPLGridClientPluginManager
37
+ >();
38
+ const store = useLocalObservable(
39
+ () => new REPLGridClientStore(applicationStore),
40
+ );
41
+ return (
42
+ <EditorStoreContext.Provider value={store}>
43
+ {children}
44
+ </EditorStoreContext.Provider>
45
+ );
46
+ };
47
+
48
+ export const useREPLGridClientStore = (): REPLGridClientStore =>
49
+ guaranteeNonNullable(
50
+ useContext(EditorStoreContext),
51
+ `Can't find editor store in context`,
52
+ );
53
+
54
+ export const withEditorStore = (WrappedComponent: React.FC): React.FC =>
55
+ function WithEditorStore() {
56
+ return (
57
+ <REPLGridClientStoreProvider>
58
+ <WrappedComponent />
59
+ </REPLGridClientStoreProvider>
60
+ );
61
+ };
@@ -0,0 +1,190 @@
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 {
18
+ TDS_AGGREGATION_FUNCTION,
19
+ TDS_FILTER_OPERATION,
20
+ TDS_SORT_ORDER,
21
+ } from './TDSRequest.js';
22
+ import {
23
+ type TDSExecutionResult,
24
+ type TabularDataSet,
25
+ PRIMITIVE_TYPE,
26
+ } from '@finos/legend-graph';
27
+ import { isBoolean } from '@finos/legend-shared';
28
+
29
+ export type TDSResultCellDataType =
30
+ | string
31
+ | number
32
+ | boolean
33
+ | null
34
+ | undefined;
35
+
36
+ export interface TDSRowDataType {
37
+ [key: string]: TDSResultCellDataType;
38
+ }
39
+
40
+ export const getTDSSortOrder = (sortOrder: string): TDS_SORT_ORDER => {
41
+ switch (sortOrder) {
42
+ case 'asc':
43
+ return TDS_SORT_ORDER.ASCENDING;
44
+ case 'desc':
45
+ return TDS_SORT_ORDER.DESCENDING;
46
+ default:
47
+ throw new Error(`Unsupported tds sort order ${sortOrder}`);
48
+ }
49
+ };
50
+
51
+ export const getAggregationFunction = (
52
+ aggFunc: string,
53
+ ): TDS_AGGREGATION_FUNCTION => {
54
+ switch (aggFunc) {
55
+ case 'sum':
56
+ return TDS_AGGREGATION_FUNCTION.SUM;
57
+ case 'min':
58
+ return TDS_AGGREGATION_FUNCTION.MIN;
59
+ case 'max':
60
+ return TDS_AGGREGATION_FUNCTION.MAX;
61
+ case 'count':
62
+ return TDS_AGGREGATION_FUNCTION.COUNT;
63
+ default:
64
+ throw new Error(`Unsupported aggregation function ${aggFunc}`);
65
+ }
66
+ };
67
+
68
+ export const getTDSFilterOperation = (
69
+ filterOperation: string,
70
+ ): TDS_FILTER_OPERATION => {
71
+ switch (filterOperation) {
72
+ case 'equals':
73
+ return TDS_FILTER_OPERATION.EQUALS;
74
+ case 'notEqual':
75
+ return TDS_FILTER_OPERATION.NOT_EQUAL;
76
+ case 'greaterThan':
77
+ return TDS_FILTER_OPERATION.GREATER_THAN;
78
+ case 'greaterThanOrEqual':
79
+ return TDS_FILTER_OPERATION.GREATER_THAN_OR_EQUAL;
80
+ case 'lessThan':
81
+ return TDS_FILTER_OPERATION.LESS_THAN;
82
+ case 'lessThanOrEqual':
83
+ return TDS_FILTER_OPERATION.LESS_THAN_OR_EQUAL;
84
+ case 'blank':
85
+ return TDS_FILTER_OPERATION.BLANK;
86
+ case 'notBlank':
87
+ return TDS_FILTER_OPERATION.NOT_BLANK;
88
+ case 'contains':
89
+ return TDS_FILTER_OPERATION.CONTAINS;
90
+ case 'notContains':
91
+ return TDS_FILTER_OPERATION.NOT_CONTAINS;
92
+ case 'startsWith':
93
+ return TDS_FILTER_OPERATION.STARTS_WITH;
94
+ case 'endsWith':
95
+ return TDS_FILTER_OPERATION.ENDS_WITH;
96
+ default:
97
+ throw new Error(`Unsupported filter operation ${filterOperation}`);
98
+ }
99
+ };
100
+
101
+ export const getFilterColumnType = (type: string): PRIMITIVE_TYPE => {
102
+ switch (type) {
103
+ case 'text':
104
+ return PRIMITIVE_TYPE.STRING;
105
+ case 'number':
106
+ return PRIMITIVE_TYPE.NUMBER;
107
+ case 'boolean':
108
+ return PRIMITIVE_TYPE.BOOLEAN;
109
+ case 'date':
110
+ return PRIMITIVE_TYPE.DATE;
111
+ default:
112
+ throw new Error(`Unsupported filter type ${type}`);
113
+ }
114
+ };
115
+
116
+ export const getAggregationTDSColumnCustomizations = (
117
+ isAgGridLicenseEnabled: boolean,
118
+ result: TDSExecutionResult,
119
+ columnName: string,
120
+ ): object => {
121
+ if (!isAgGridLicenseEnabled) {
122
+ return {};
123
+ }
124
+ const columnType = result.builder.columns.find(
125
+ (col) => col.name === columnName,
126
+ )?.type;
127
+ switch (columnType) {
128
+ case PRIMITIVE_TYPE.STRING:
129
+ return {
130
+ filter: 'agTextColumnFilter',
131
+ allowedAggFuncs: ['count'],
132
+ };
133
+ case PRIMITIVE_TYPE.DATE:
134
+ case PRIMITIVE_TYPE.DATETIME:
135
+ case PRIMITIVE_TYPE.STRICTDATE:
136
+ return {
137
+ filter: 'agDateColumnFilter',
138
+ allowedAggFuncs: ['count'],
139
+ };
140
+ case PRIMITIVE_TYPE.DECIMAL:
141
+ case PRIMITIVE_TYPE.INTEGER:
142
+ case PRIMITIVE_TYPE.FLOAT:
143
+ return {
144
+ filter: 'agNumberColumnFilter',
145
+ allowedAggFuncs: ['count', 'sum', 'max', 'min', 'avg'],
146
+ };
147
+ default:
148
+ return {
149
+ allowedAggFuncs: ['count'],
150
+ };
151
+ }
152
+ };
153
+
154
+ export const getDefaultColumnDefintions = (
155
+ isAgGridLicenseEnabled: boolean,
156
+ ): object => {
157
+ if (isAgGridLicenseEnabled) {
158
+ return {
159
+ minWidth: 50,
160
+ sortable: true,
161
+ flex: 1,
162
+ resizable: true,
163
+ enableRowGroup: true,
164
+ allowedAggFuncs: ['count', 'sum', 'max', 'min', 'avg'],
165
+ enableValue: true,
166
+ menuTabs: ['filterMenuTab', 'generalMenuTab', 'columnsMenuTab'],
167
+ };
168
+ } else {
169
+ return {
170
+ minWidth: 50,
171
+ sortable: true,
172
+ flex: 1,
173
+ resizable: true,
174
+ menuTabs: ['filterMenuTab', 'generalMenuTab', 'columnsMenuTab'],
175
+ };
176
+ }
177
+ };
178
+
179
+ export const getTDSRowData = (tds: TabularDataSet): TDSRowDataType[] =>
180
+ tds.rows.map((_row, rowIdx) => {
181
+ const row: TDSRowDataType = {};
182
+ const cols = tds.columns;
183
+ _row.values.forEach((value, colIdx) => {
184
+ // `ag-grid` shows `false` value as empty string so we have
185
+ // call `.toString()` to avoid this behavior.
186
+ row[cols[colIdx] as string] = isBoolean(value) ? String(value) : value;
187
+ });
188
+ row.rowNumber = rowIdx;
189
+ return row;
190
+ });
@@ -0,0 +1,30 @@
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 { createModelSchema, primitive } from 'serializr';
18
+ import { SerializationFactory } from '@finos/legend-shared';
19
+
20
+ export class REPLGridServerResult {
21
+ currentQuery!: string;
22
+ result!: string;
23
+
24
+ static readonly serialization = new SerializationFactory(
25
+ createModelSchema(REPLGridServerResult, {
26
+ currentQuery: primitive(),
27
+ result: primitive(),
28
+ }),
29
+ );
30
+ }
@@ -0,0 +1,184 @@
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 type {
18
+ IServerSideDatasource,
19
+ IServerSideGetRowsParams,
20
+ } from '@ag-grid-community/core';
21
+ import {
22
+ TDSGroupby,
23
+ TDSAggregation,
24
+ TDSFilter,
25
+ TDSRequest,
26
+ TDSSort,
27
+ TDSFilterCondition,
28
+ TDS_FILTER_GROUP,
29
+ } from './TDSRequest.js';
30
+ import {
31
+ guaranteeNonNullable,
32
+ type GeneratorFn,
33
+ assertErrorThrown,
34
+ LogEvent,
35
+ } from '@finos/legend-shared';
36
+ import { LEGEND_REPL_EVENT } from '../../Const.js';
37
+ import {
38
+ type TDSRowDataType,
39
+ getTDSRowData,
40
+ getTDSSortOrder,
41
+ getTDSFilterOperation,
42
+ getAggregationFunction,
43
+ getFilterColumnType,
44
+ } from './GridUtils.js';
45
+ import type { REPLGridClientStore } from '../../stores/REPLGridClientStore.js';
46
+ import { flow, flowResult, makeObservable } from 'mobx';
47
+ import type { INTERNAL__TDSColumn, PRIMITIVE_TYPE } from '@finos/legend-graph';
48
+
49
+ export class ServerSideDataSource implements IServerSideDatasource {
50
+ executions = 0;
51
+ rowData: TDSRowDataType[] = [];
52
+ columns: INTERNAL__TDSColumn[] = [];
53
+ editorStore?: REPLGridClientStore | undefined;
54
+
55
+ constructor(
56
+ rowData?: TDSRowDataType[] | undefined,
57
+ columns?: INTERNAL__TDSColumn[] | undefined,
58
+ editorStore?: REPLGridClientStore | undefined,
59
+ ) {
60
+ makeObservable(this, {
61
+ fetchRows: flow,
62
+ });
63
+ this.rowData = rowData ?? [];
64
+ this.columns = columns ?? [];
65
+ this.editorStore = editorStore;
66
+ }
67
+
68
+ *fetchRows(
69
+ params: IServerSideGetRowsParams<unknown, unknown>,
70
+ ): GeneratorFn<void> {
71
+ try {
72
+ if (this.executions > 0) {
73
+ if (this.editorStore) {
74
+ const request = this.extractRequest(params);
75
+ if (request) {
76
+ yield flowResult(this.editorStore.getREPLGridServerResult(request));
77
+ const result = this.editorStore.replGridState.currentResult;
78
+ const rowData = getTDSRowData(guaranteeNonNullable(result).result);
79
+ params.success({ rowData: rowData });
80
+ } else {
81
+ params.fail();
82
+ }
83
+ }
84
+ } else {
85
+ params.success({ rowData: this.rowData });
86
+ }
87
+ this.executions++;
88
+ } catch (error) {
89
+ assertErrorThrown(error);
90
+ this.editorStore?.applicationStore.notificationService.notifyError(error);
91
+ this.editorStore?.applicationStore.logService.error(
92
+ LogEvent.create(LEGEND_REPL_EVENT.FETCH_TDS_FAILURE),
93
+ error,
94
+ );
95
+ }
96
+ }
97
+
98
+ getRows(params: IServerSideGetRowsParams<unknown, unknown>): void {
99
+ this.fetchRows(params);
100
+ }
101
+
102
+ extractRequest(
103
+ params: IServerSideGetRowsParams<unknown, unknown>,
104
+ ): TDSRequest | undefined {
105
+ try {
106
+ const request = params.request;
107
+ const startRow = request.startRow;
108
+ const endRow = request.endRow;
109
+ const columns = params.columnApi.getColumns()?.map((c) => c.getColId());
110
+ const sort = request.sortModel.map(
111
+ (i) => new TDSSort(i.colId, getTDSSortOrder(i.sort)),
112
+ );
113
+ const aggregations = request.valueCols.map((v) => {
114
+ const colType = this.columns.find((c) => c.name === v.field)?.type;
115
+ return new TDSAggregation(
116
+ guaranteeNonNullable(v.field),
117
+ colType as PRIMITIVE_TYPE,
118
+ getAggregationFunction(guaranteeNonNullable(v.aggFunc)),
119
+ );
120
+ });
121
+ const groupBy = new TDSGroupby(
122
+ request.rowGroupCols.map((r) => r.id),
123
+ request.groupKeys,
124
+ aggregations,
125
+ );
126
+ const filter: TDSFilter[] = [];
127
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
128
+ const filterModel = request.filterModel;
129
+ if (filterModel) {
130
+ Object.keys(filterModel).forEach((key) => {
131
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
132
+ const item = filterModel[key];
133
+ const conditions: TDSFilterCondition[] = [];
134
+ const colType = getFilterColumnType(item.filterType);
135
+ if (item.filter === undefined && item.conditions) {
136
+ item.conditions.forEach(
137
+ (condition: { type: string; filter: unknown }) =>
138
+ conditions.push(
139
+ new TDSFilterCondition(
140
+ getTDSFilterOperation(condition.type),
141
+ condition.filter,
142
+ ),
143
+ ),
144
+ );
145
+ } else {
146
+ conditions.push(
147
+ new TDSFilterCondition(
148
+ getTDSFilterOperation(item.type),
149
+ item.filter,
150
+ ),
151
+ );
152
+ }
153
+ filter.push(
154
+ new TDSFilter(
155
+ key,
156
+ colType as PRIMITIVE_TYPE,
157
+ conditions,
158
+ item.operator === 'OR'
159
+ ? TDS_FILTER_GROUP.OR
160
+ : TDS_FILTER_GROUP.AND,
161
+ ),
162
+ );
163
+ });
164
+ }
165
+ const tdsRequest = new TDSRequest(
166
+ columns ?? [],
167
+ filter,
168
+ sort,
169
+ groupBy,
170
+ startRow,
171
+ endRow,
172
+ );
173
+ return tdsRequest;
174
+ } catch (error) {
175
+ assertErrorThrown(error);
176
+ this.editorStore?.applicationStore.notificationService.notifyError(error);
177
+ this.editorStore?.applicationStore.logService.error(
178
+ LogEvent.create(LEGEND_REPL_EVENT.BUILD_TDS_EQUEST_FAILURE),
179
+ error,
180
+ );
181
+ return undefined;
182
+ }
183
+ }
184
+ }