@quillsql/react 2.12.40 → 2.12.41
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/dist/cjs/Chart.js +1 -1
- package/dist/cjs/ChartBuilder.d.ts +1 -1
- package/dist/cjs/ChartBuilder.d.ts.map +1 -1
- package/dist/cjs/ChartBuilder.js +6 -6
- package/dist/cjs/Dashboard.js +5 -5
- package/dist/cjs/ReportBuilder.d.ts +1 -1
- package/dist/cjs/ReportBuilder.d.ts.map +1 -1
- package/dist/cjs/ReportBuilder.js +111 -1588
- package/dist/cjs/components/Chart/BarChart.d.ts.map +1 -1
- package/dist/cjs/components/Chart/BarChart.js +0 -9
- package/dist/cjs/components/Chart/LineChart.d.ts.map +1 -1
- package/dist/cjs/components/Chart/LineChart.js +1 -11
- package/dist/cjs/components/Dashboard/DataLoader.js +1 -1
- package/dist/cjs/components/ReportBuilder/FilterModal.js +32 -32
- package/dist/cjs/components/ReportBuilder/convert.d.ts +5 -31
- package/dist/cjs/components/ReportBuilder/convert.d.ts.map +1 -1
- package/dist/cjs/components/ReportBuilder/convert.js +1 -1
- package/dist/cjs/hooks/useAskQuill.d.ts +27 -0
- package/dist/cjs/hooks/useAskQuill.d.ts.map +1 -0
- package/dist/cjs/hooks/useAskQuill.js +177 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/internals/ReportBuilder/PivotForm.d.ts +3 -3
- package/dist/cjs/internals/ReportBuilder/PivotForm.d.ts.map +1 -1
- package/dist/cjs/internals/ReportBuilder/PivotForm.js +4 -2
- package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts +1 -15
- package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
- package/dist/cjs/internals/ReportBuilder/PivotModal.js +24 -24
- package/dist/cjs/models/Filter.d.ts +25 -19
- package/dist/cjs/models/Filter.d.ts.map +1 -1
- package/dist/cjs/models/Filter.js +2 -2
- package/dist/cjs/{components/ReportBuilder/pivot.d.ts → models/Pivot.d.ts} +13 -4
- package/dist/cjs/models/Pivot.d.ts.map +1 -0
- package/dist/cjs/models/Report.d.ts +1 -1
- package/dist/cjs/models/Report.d.ts.map +1 -1
- package/dist/cjs/models/Tables.d.ts +16 -0
- package/dist/cjs/models/Tables.d.ts.map +1 -1
- package/dist/cjs/utils/astFilterProcessing.js +27 -27
- package/dist/cjs/utils/astProcessing.d.ts +42 -0
- package/dist/cjs/utils/astProcessing.d.ts.map +1 -1
- package/dist/cjs/utils/astProcessing.js +210 -1
- package/dist/cjs/utils/constants.d.ts +1 -0
- package/dist/cjs/utils/constants.d.ts.map +1 -1
- package/dist/cjs/utils/constants.js +2 -1
- package/dist/cjs/utils/dataFetcher.d.ts +4 -0
- package/dist/cjs/utils/dataFetcher.d.ts.map +1 -1
- package/dist/cjs/utils/dataFetcher.js +24 -1
- package/dist/cjs/utils/dates.d.ts +1 -1
- package/dist/cjs/utils/filterProcessing.d.ts +2 -2
- package/dist/cjs/utils/filterProcessing.d.ts.map +1 -1
- package/dist/cjs/utils/filterProcessing.js +6 -6
- package/dist/cjs/utils/pivotConstructor.d.ts +1 -1
- package/dist/cjs/utils/pivotConstructor.d.ts.map +1 -1
- package/dist/cjs/utils/pivotConstructor.js +7 -4
- package/dist/cjs/utils/pivotProcessing.d.ts +4 -4
- package/dist/cjs/utils/pivotProcessing.d.ts.map +1 -1
- package/dist/cjs/utils/pivotProcessing.js +21 -2
- package/dist/cjs/utils/queryConstructor.d.ts +1 -1
- package/dist/cjs/utils/queryConstructor.d.ts.map +1 -1
- package/dist/cjs/utils/queryConstructor.js +3 -3
- package/dist/cjs/utils/report.d.ts +25 -0
- package/dist/cjs/utils/report.d.ts.map +1 -1
- package/dist/cjs/utils/report.js +114 -2
- package/dist/cjs/utils/schema.d.ts.map +1 -1
- package/dist/cjs/utils/schema.js +1 -1
- package/dist/cjs/utils/tableProcessing.d.ts +18 -0
- package/dist/cjs/utils/tableProcessing.d.ts.map +1 -1
- package/dist/cjs/utils/tableProcessing.js +94 -1
- package/dist/esm/Chart.js +1 -1
- package/dist/esm/ChartBuilder.d.ts +1 -1
- package/dist/esm/ChartBuilder.d.ts.map +1 -1
- package/dist/esm/ChartBuilder.js +6 -6
- package/dist/esm/Dashboard.js +5 -5
- package/dist/esm/ReportBuilder.d.ts +1 -1
- package/dist/esm/ReportBuilder.d.ts.map +1 -1
- package/dist/esm/ReportBuilder.js +121 -1598
- package/dist/esm/components/Chart/BarChart.d.ts.map +1 -1
- package/dist/esm/components/Chart/BarChart.js +0 -9
- package/dist/esm/components/Chart/LineChart.d.ts.map +1 -1
- package/dist/esm/components/Chart/LineChart.js +1 -11
- package/dist/esm/components/Dashboard/DataLoader.js +1 -1
- package/dist/esm/components/ReportBuilder/FilterModal.js +32 -32
- package/dist/esm/components/ReportBuilder/convert.d.ts +5 -31
- package/dist/esm/components/ReportBuilder/convert.d.ts.map +1 -1
- package/dist/esm/components/ReportBuilder/convert.js +1 -1
- package/dist/esm/hooks/useAskQuill.d.ts +27 -0
- package/dist/esm/hooks/useAskQuill.d.ts.map +1 -0
- package/dist/esm/hooks/useAskQuill.js +173 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/internals/ReportBuilder/PivotForm.d.ts +3 -3
- package/dist/esm/internals/ReportBuilder/PivotForm.d.ts.map +1 -1
- package/dist/esm/internals/ReportBuilder/PivotForm.js +4 -2
- package/dist/esm/internals/ReportBuilder/PivotModal.d.ts +1 -15
- package/dist/esm/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
- package/dist/esm/internals/ReportBuilder/PivotModal.js +24 -24
- package/dist/esm/models/Filter.d.ts +25 -19
- package/dist/esm/models/Filter.d.ts.map +1 -1
- package/dist/esm/models/Filter.js +2 -2
- package/dist/esm/{components/ReportBuilder/pivot.d.ts → models/Pivot.d.ts} +13 -4
- package/dist/esm/models/Pivot.d.ts.map +1 -0
- package/dist/esm/models/Report.d.ts +1 -1
- package/dist/esm/models/Report.d.ts.map +1 -1
- package/dist/esm/models/Tables.d.ts +16 -0
- package/dist/esm/models/Tables.d.ts.map +1 -1
- package/dist/esm/utils/astFilterProcessing.js +27 -27
- package/dist/esm/utils/astProcessing.d.ts +42 -0
- package/dist/esm/utils/astProcessing.d.ts.map +1 -1
- package/dist/esm/utils/astProcessing.js +204 -0
- package/dist/esm/utils/constants.d.ts +1 -0
- package/dist/esm/utils/constants.d.ts.map +1 -1
- package/dist/esm/utils/constants.js +1 -0
- package/dist/esm/utils/dataFetcher.d.ts +4 -0
- package/dist/esm/utils/dataFetcher.d.ts.map +1 -1
- package/dist/esm/utils/dataFetcher.js +22 -0
- package/dist/esm/utils/dates.d.ts +1 -1
- package/dist/esm/utils/filterProcessing.d.ts +2 -2
- package/dist/esm/utils/filterProcessing.d.ts.map +1 -1
- package/dist/esm/utils/filterProcessing.js +7 -7
- package/dist/esm/utils/pivotConstructor.d.ts +1 -1
- package/dist/esm/utils/pivotConstructor.d.ts.map +1 -1
- package/dist/esm/utils/pivotConstructor.js +7 -4
- package/dist/esm/utils/pivotProcessing.d.ts +4 -4
- package/dist/esm/utils/pivotProcessing.d.ts.map +1 -1
- package/dist/esm/utils/pivotProcessing.js +19 -1
- package/dist/esm/utils/queryConstructor.d.ts +1 -1
- package/dist/esm/utils/queryConstructor.d.ts.map +1 -1
- package/dist/esm/utils/queryConstructor.js +3 -3
- package/dist/esm/utils/report.d.ts +25 -0
- package/dist/esm/utils/report.d.ts.map +1 -1
- package/dist/esm/utils/report.js +114 -3
- package/dist/esm/utils/schema.d.ts.map +1 -1
- package/dist/esm/utils/schema.js +1 -1
- package/dist/esm/utils/tableProcessing.d.ts +18 -0
- package/dist/esm/utils/tableProcessing.d.ts.map +1 -1
- package/dist/esm/utils/tableProcessing.js +91 -1
- package/package.json +1 -1
- package/dist/cjs/components/ReportBuilder/pivot.d.ts.map +0 -1
- package/dist/cjs/models/Pivots.d.ts +0 -2
- package/dist/cjs/models/Pivots.d.ts.map +0 -1
- package/dist/cjs/models/Pivots.js +0 -2
- package/dist/esm/components/ReportBuilder/pivot.d.ts.map +0 -1
- package/dist/esm/models/Pivots.d.ts +0 -2
- package/dist/esm/models/Pivots.d.ts.map +0 -1
- package/dist/esm/models/Pivots.js +0 -1
- /package/dist/cjs/{components/ReportBuilder/pivot.js → models/Pivot.js} +0 -0
- /package/dist/esm/{components/ReportBuilder/pivot.js → models/Pivot.js} +0 -0
|
@@ -15,10 +15,7 @@ const ast_1 = require("./components/ReportBuilder/ast");
|
|
|
15
15
|
const ChartBuilder_1 = require("./ChartBuilder");
|
|
16
16
|
const UiComponents_2 = require("./components/UiComponents");
|
|
17
17
|
const ui_1 = require("./components/ReportBuilder/ui");
|
|
18
|
-
const postgres_1 = require("./components/ReportBuilder/postgres");
|
|
19
|
-
const convert_1 = require("./components/ReportBuilder/convert");
|
|
20
18
|
const util_1 = require("./components/ReportBuilder/util");
|
|
21
|
-
const operators_1 = require("./components/ReportBuilder/operators");
|
|
22
19
|
const crypto_1 = require("./utils/crypto");
|
|
23
20
|
const constants_1 = require("./components/ReportBuilder/constants");
|
|
24
21
|
const AddColumnModal_1 = __importDefault(require("./components/ReportBuilder/AddColumnModal"));
|
|
@@ -29,12 +26,9 @@ const AddLimitPopover_1 = require("./components/ReportBuilder/AddLimitPopover");
|
|
|
29
26
|
const width_1 = require("./utils/width");
|
|
30
27
|
const QuillSelect_1 = require("./components/QuillSelect");
|
|
31
28
|
const QuillCard_1 = require("./components/QuillCard");
|
|
32
|
-
const dataFetcher_1 = require("./utils/dataFetcher");
|
|
33
29
|
const valueFormatter_1 = require("./utils/valueFormatter");
|
|
34
30
|
const pivotProcessing_1 = require("./utils/pivotProcessing");
|
|
35
31
|
const tableProcessing_1 = require("./utils/tableProcessing");
|
|
36
|
-
const useQuill_1 = require("./hooks/useQuill");
|
|
37
|
-
const dataFetcher_2 = require("./utils/dataFetcher");
|
|
38
32
|
const columnProcessing_1 = require("./utils/columnProcessing");
|
|
39
33
|
const astProcessing_1 = require("./utils/astProcessing");
|
|
40
34
|
const PivotForm_1 = __importDefault(require("./internals/ReportBuilder/PivotForm"));
|
|
@@ -47,7 +41,6 @@ const filterProcessing_1 = require("./utils/filterProcessing");
|
|
|
47
41
|
const QuillMultiSelectWithCombo_1 = require("./components/QuillMultiSelectWithCombo");
|
|
48
42
|
const paginationProcessing_1 = require("./utils/paginationProcessing");
|
|
49
43
|
const report_1 = require("./utils/report");
|
|
50
|
-
const dataProcessing_1 = require("./utils/dataProcessing");
|
|
51
44
|
exports.QUILL_SERVER = (typeof process !== 'undefined' && process?.env?.QUILL_SERVER_HOST) ||
|
|
52
45
|
'https://quill-344421.uc.r.appspot.com';
|
|
53
46
|
/**
|
|
@@ -81,8 +74,12 @@ exports.QUILL_SERVER = (typeof process !== 'undefined' && process?.env?.QUILL_SE
|
|
|
81
74
|
* ### Report Builder API
|
|
82
75
|
* @see https://docs.quillsql.com/components/report-builder
|
|
83
76
|
*/
|
|
84
|
-
function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void null, onSubmitCreateReport = () => void null, destinationDashboard = undefined, organizationName = '', ButtonComponent = UiComponents_1.MemoizedButton, SecondaryButtonComponent = UiComponents_1.MemoizedSecondaryButton, DeleteButtonComponent = UiComponents_1.MemoizedDeleteButton, ModalComponent = UiComponents_1.MemoizedModal, TextInputComponent = UiComponents_2.QuillTextInput, SelectComponent = QuillSelect_1.QuillSelectComponent, MultiSelectComponent = QuillMultiSelectWithCombo_1.QuillMultiSelectComponentWithCombo, TableComponent = UiComponents_1.QuillTableSQLEditorComponent, PopoverComponent = UiComponents_1.MemoizedPopover, TabsComponent = UiComponents_1.QuillTabs,
|
|
85
|
-
|
|
77
|
+
function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void null, onSubmitCreateReport = () => void null, destinationDashboard = undefined, organizationName = '', ButtonComponent = UiComponents_1.MemoizedButton, SecondaryButtonComponent = UiComponents_1.MemoizedSecondaryButton, DeleteButtonComponent = UiComponents_1.MemoizedDeleteButton, ModalComponent = UiComponents_1.MemoizedModal, TextInputComponent = UiComponents_2.QuillTextInput, SelectComponent = QuillSelect_1.QuillSelectComponent, MultiSelectComponent = QuillMultiSelectWithCombo_1.QuillMultiSelectComponentWithCombo, TableComponent = UiComponents_1.QuillTableSQLEditorComponent, PopoverComponent = UiComponents_1.MemoizedPopover, TabsComponent = UiComponents_1.QuillTabs,
|
|
78
|
+
// CheckboxComponent = MemoizedCheckbox,
|
|
79
|
+
SidebarComponent = ui_1.QuillSidebar, ContainerComponent = ui_1.CustomContainer, SelectColumnComponent = ui_1.QuillSelectColumn, DraggableColumnComponent = ui_1.QuillDraggableColumn, SidebarHeadingComponent = ui_1.QuillSidebarHeading, FilterPopoverComponent = ui_1.QuillFilterPopover, SortPopoverComponent = ui_1.QuillSortPopover, LimitPopoverComponent = ui_1.QuillLimitPopover, CardComponent = QuillCard_1.QuillCard, LabelComponent = UiComponents_1.MemoizedLabel, HeaderComponent = UiComponents_1.MemoizedHeader, SubHeaderComponent = UiComponents_1.MemoizedSubHeader, TextComponent = UiComponents_1.MemoizedText, ErrorMessageComponent = UiComponents_1.QuillErrorMessageComponent, ChartBuilderInputRowContainer = UiComponents_1.QuillChartBuilderInputRowContainer, ChartBuilderInputColumnContainer = UiComponents_1.QuillChartBuilderInputColumnContainer, PivotRowContainer = UiComponents_1.QuillPivotRowContainer, PivotColumnContainer = UiComponents_1.QuillPivotColumnContainer, LoadingComponent = UiComponents_1.QuillLoadingComponent, ColumnSearchEmptyState = UiComponents_1.QuillColumnSearchEmptyState, ChartBuilderFormContainer = UiComponents_1.QuillChartBuilderFormContainer, ChartBuilderModalComponent = UiComponents_1.MemoizedModal, isAdminEnabled = false, isAIEnabled = true, showChartBuilderTableFormatOptions = true, containerStyle, className, pivotRecommendationsEnabled = true, reportId, hideCopySQL = true, isChartBuilderHorizontalView = true, onClickChartElement, }) {
|
|
80
|
+
const [dashboard] = (0, react_1.useContext)(Context_1.DashboardContext);
|
|
81
|
+
const [schema, setSchema] = (0, react_1.useContext)(Context_1.SchemaContext);
|
|
82
|
+
const [reportInfo, setReportInfo] = (0, react_1.useState)(null);
|
|
86
83
|
const [aiPrompt, setAiPrompt] = (0, react_1.useState)('');
|
|
87
84
|
const [errorMessage, setErrorMessage] = (0, react_1.useState)('');
|
|
88
85
|
const [baseAst, setBaseAst] = (0, react_1.useState)(null);
|
|
@@ -90,22 +87,20 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
90
87
|
const [orderedColumnNames, setOrderedColumnNames] = (0, react_1.useState)([]);
|
|
91
88
|
const [selectedColumns, setSelectedColumns] = (0, react_1.useState)([]);
|
|
92
89
|
const [selectedOrderedColumns, setSelectedOrderedColumns] = (0, react_1.useState)([]);
|
|
93
|
-
const [schema, setSchema] = (0, react_1.useContext)(Context_1.SchemaContext);
|
|
94
90
|
const [activeQuery, setActiveQuery] = (0, react_1.useState)('');
|
|
95
|
-
const [
|
|
91
|
+
const [, setActiveEditItem] = (0, react_1.useState)(null);
|
|
96
92
|
const [activePath, setActivePath] = (0, react_1.useState)(null);
|
|
97
93
|
const [openPopover, setOpenPopover] = (0, react_1.useState)(null);
|
|
98
94
|
const [loading, setLoading] = (0, react_1.useState)(!!initialTableName);
|
|
99
95
|
const [loadingSchema, setLoadingSchema] = (0, react_1.useState)(false);
|
|
100
96
|
const [isChartBuilderOpen, setIsChartBuilderOpen] = (0, react_1.useState)(false);
|
|
101
|
-
const [
|
|
97
|
+
const [, setIsPending] = (0, react_1.useState)(false);
|
|
102
98
|
const [isCopying, setIsCopying] = (0, react_1.useState)(false);
|
|
103
99
|
const [dataDisplayed, setDataDisplayed] = (0, react_1.useState)(false);
|
|
104
100
|
const [rows, setRows] = (0, react_1.useState)([]);
|
|
105
101
|
const [formattedRows, setFormattedRows] = (0, react_1.useState)([]);
|
|
106
102
|
const [columns, setColumns] = (0, react_1.useState)([]);
|
|
107
103
|
const [tempReport, setTempReport] = (0, react_1.useState)(report_1.EMPTY_REPORT);
|
|
108
|
-
const [topLevelBinaryOperator, setTopLevelBinaryOperator] = (0, react_1.useState)('AND');
|
|
109
104
|
const [uniqueValues, setUniqueValues] = (0, react_1.useState)({});
|
|
110
105
|
const [pivot, setPivot] = (0, react_1.useState)(null);
|
|
111
106
|
const [pivotData, setPivotData] = (0, react_1.useState)(null);
|
|
@@ -189,7 +184,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
189
184
|
const column = columns.find((c) => c.field === changeField);
|
|
190
185
|
if (column?.jsType === 'date') {
|
|
191
186
|
newPivot.rowFieldType = 'date';
|
|
192
|
-
newPivot.sort =
|
|
187
|
+
newPivot.sort = true;
|
|
193
188
|
newPivot.sortField = changeField;
|
|
194
189
|
newPivot.sortFieldType = column.format;
|
|
195
190
|
newPivot.sortDirection = 'ASC';
|
|
@@ -200,7 +195,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
200
195
|
}
|
|
201
196
|
}
|
|
202
197
|
let dateBucket = undefined;
|
|
203
|
-
const tempDateRange = dateRanges && dateRanges[newPivot.rowField];
|
|
198
|
+
const tempDateRange = dateRanges && dateRanges[newPivot.rowField || ''];
|
|
204
199
|
if (tempDateRange) {
|
|
205
200
|
dateBucket = (0, dates_1.getDateBucketFromRange)(tempDateRange.dateRange);
|
|
206
201
|
}
|
|
@@ -253,7 +248,6 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
253
248
|
setDataDisplayed(false);
|
|
254
249
|
setRows([]);
|
|
255
250
|
setColumns([]);
|
|
256
|
-
setTopLevelBinaryOperator('AND');
|
|
257
251
|
setErrorMessage('');
|
|
258
252
|
setFormattedRows([]);
|
|
259
253
|
// setUniqueValues({});
|
|
@@ -270,12 +264,6 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
270
264
|
clearAllState();
|
|
271
265
|
}
|
|
272
266
|
}, [client]);
|
|
273
|
-
(0, react_1.useEffect)(() => {
|
|
274
|
-
if (activePath !== null) {
|
|
275
|
-
// update the modal with the new subtree
|
|
276
|
-
setActiveEditItem(getByKey(formData, activePath));
|
|
277
|
-
}
|
|
278
|
-
}, [formData]);
|
|
279
267
|
const formatRows = (rows, columns, pivot, aggregationType) => {
|
|
280
268
|
const copiedRows = (0, util_1.deepCopy)(rows);
|
|
281
269
|
if (pivot) {
|
|
@@ -320,19 +308,6 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
320
308
|
return formattedRows;
|
|
321
309
|
}
|
|
322
310
|
};
|
|
323
|
-
const getByKey = (formData, path) => {
|
|
324
|
-
if (!path)
|
|
325
|
-
return (0, util_1.deepCopy)(formData);
|
|
326
|
-
// Function to immutably update or delete nodes based on their path
|
|
327
|
-
const paths = path.split('.');
|
|
328
|
-
let current = (0, util_1.deepCopy)(formData);
|
|
329
|
-
for (let i = 0; i < paths.length; i++) {
|
|
330
|
-
if (current[paths[i]]) {
|
|
331
|
-
current = current[paths[i]];
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
return current;
|
|
335
|
-
};
|
|
336
311
|
const copySQLToClipboard = () => {
|
|
337
312
|
let query = activeQuery;
|
|
338
313
|
if (pivot) {
|
|
@@ -377,7 +352,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
377
352
|
const data = await response.json();
|
|
378
353
|
setActiveQuery(data.query);
|
|
379
354
|
if (fetchData) {
|
|
380
|
-
|
|
355
|
+
fetchReportFromASTHelper(ast, formData);
|
|
381
356
|
}
|
|
382
357
|
return data.query;
|
|
383
358
|
}
|
|
@@ -465,7 +440,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
465
440
|
return -1;
|
|
466
441
|
return 0;
|
|
467
442
|
});
|
|
468
|
-
await
|
|
443
|
+
await fetchAstFromPromptHelper(`get ${columnsForTable} from ${initialTableName}`);
|
|
469
444
|
setInitialLoad(false);
|
|
470
445
|
};
|
|
471
446
|
const fetchSchema = async () => {
|
|
@@ -504,106 +479,27 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
504
479
|
};
|
|
505
480
|
(0, react_1.useEffect)(() => {
|
|
506
481
|
const loadChart = async () => {
|
|
507
|
-
|
|
508
|
-
// @ts-ignore THIS PROCESS SHOULD BE UPDATED TO NOT USE USEQUILL
|
|
509
|
-
if (!report || report.referencedTables.length !== 1) {
|
|
510
|
-
setInitialChartLoad(false);
|
|
511
|
-
return;
|
|
512
|
-
}
|
|
482
|
+
let report;
|
|
513
483
|
try {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
const ast = (0, astProcessing_1.getSelectFromAST)(resp.ast);
|
|
529
|
-
let convertedAst = (0, astProcessing_1.processStarColumn)(ast, report.columns);
|
|
530
|
-
(0, astProcessing_1.processApostrophe)(convertedAst, ['type', 'value']);
|
|
531
|
-
convertedAst = (0, convert_1.convertBigQuery)(convertedAst);
|
|
532
|
-
const schemaInfo = schema.length !== 0 ? schema : await fetchSchema();
|
|
533
|
-
let newAst;
|
|
534
|
-
let groupByPivot = {};
|
|
535
|
-
({ ast: newAst, pivot: groupByPivot } = (0, convert_1.convertGroupBy)(convertedAst,
|
|
536
|
-
// @ts-ignore
|
|
537
|
-
report.pivot, schemaInfo));
|
|
538
|
-
if (convertedAst.where) {
|
|
539
|
-
setFormData((0, util_1.deepCopy)(convertedAst.where));
|
|
540
|
-
}
|
|
541
|
-
// @ts-ignore THIS PROCESS SHOULD BE UPDATED TO NOT USE USEQUILL
|
|
542
|
-
setActiveQuery(report.queryString);
|
|
543
|
-
newAst = groupByPivot ? newAst : convertedAst;
|
|
544
|
-
const initialRows = await fetchUponChange(newAst, undefined);
|
|
545
|
-
if (initialRows.error) {
|
|
546
|
-
setBaseAst(null);
|
|
547
|
-
setErrorMessage(initialRows.message);
|
|
548
|
-
setInitialChartLoad(false);
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
551
|
-
setBaseAst(newAst);
|
|
552
|
-
const tableInfo = schemaInfo.find((table) => table.name === tableName);
|
|
553
|
-
let newUniqueValues = undefined;
|
|
554
|
-
let dateRangesTemp = undefined;
|
|
555
|
-
if (tableName) {
|
|
556
|
-
newUniqueValues = await getUniqueStringValues(tableInfo.columns, tableName);
|
|
557
|
-
setUniqueValues(newUniqueValues);
|
|
558
|
-
dateRangesTemp = await getDateRanges(tableInfo.columns, tableName);
|
|
559
|
-
setDateRanges(dateRangesTemp);
|
|
560
|
-
}
|
|
561
|
-
if (groupByPivot) {
|
|
562
|
-
// @ts-ignore
|
|
563
|
-
setPivotRowField(groupByPivot.rowField);
|
|
564
|
-
// @ts-ignore
|
|
565
|
-
setPivotAggregation(groupByPivot.aggregationType);
|
|
566
|
-
// @ts-ignore
|
|
567
|
-
setPivotColumnField(groupByPivot.columnField);
|
|
568
|
-
// @ts-ignore
|
|
569
|
-
setPivotValueField(groupByPivot.valueField);
|
|
570
|
-
setPivot(groupByPivot);
|
|
571
|
-
let dateBucket = undefined;
|
|
572
|
-
const tempDateRange = dateRangesTemp &&
|
|
573
|
-
groupByPivot.rowField &&
|
|
574
|
-
dateRangesTemp[groupByPivot.rowField];
|
|
575
|
-
if (tempDateRange) {
|
|
576
|
-
dateBucket = (0, dates_1.getDateBucketFromRange)(tempDateRange.dateRange);
|
|
577
|
-
}
|
|
578
|
-
const pivotedData = await (0, PivotModal_1.generatePivotTable)(
|
|
579
|
-
// @ts-ignore
|
|
580
|
-
groupByPivot, initialRows, tempDateRange, false, -1, undefined, dateBucket, report, client, newUniqueValues[tableName]);
|
|
581
|
-
setPivotData(pivotedData || []);
|
|
582
|
-
const formattedRows = formatRows(pivotedData.rows, report.columns, true,
|
|
583
|
-
// @ts-ignore
|
|
584
|
-
groupByPivot.aggregationType);
|
|
585
|
-
setFormattedRows(formattedRows);
|
|
586
|
-
}
|
|
587
|
-
else {
|
|
588
|
-
const formattedRows = formatRows(report.rows, report.columns);
|
|
589
|
-
setFormattedRows(formattedRows);
|
|
590
|
-
}
|
|
591
|
-
setCurrentTable(tableName);
|
|
592
|
-
}
|
|
593
|
-
catch (error) {
|
|
594
|
-
console.error(error);
|
|
595
|
-
setErrorMessage('Error loading report');
|
|
484
|
+
if (!reportId) {
|
|
485
|
+
throw new Error('Report ID is required');
|
|
486
|
+
}
|
|
487
|
+
report = dashboard[reportId];
|
|
488
|
+
if (!report || report.referencedTables?.length !== 1) {
|
|
489
|
+
throw new Error('Report not found');
|
|
490
|
+
}
|
|
491
|
+
const { ast: newAst, pivot: newPivot, schema: curSchema, } = await (0, astProcessing_1.fetchASTFromQuillReport)(report, client, schema);
|
|
492
|
+
setBaseAst({ ...newAst, where: null });
|
|
493
|
+
await fetchReportFromASTHelper({ ...newAst, where: null }, newAst.where, newPivot, curSchema, report);
|
|
494
|
+
await fetchSchema();
|
|
495
|
+
setReportInfo(report);
|
|
596
496
|
}
|
|
597
|
-
|
|
598
|
-
setTimeout(() => {
|
|
497
|
+
catch (err) {
|
|
599
498
|
setInitialChartLoad(false);
|
|
600
|
-
}
|
|
499
|
+
}
|
|
601
500
|
};
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
loadChart();
|
|
605
|
-
}
|
|
606
|
-
}, [report]);
|
|
501
|
+
loadChart();
|
|
502
|
+
}, [dashboard[reportId || '']]);
|
|
607
503
|
(0, react_1.useEffect)(() => {
|
|
608
504
|
if (schema.length === 0) {
|
|
609
505
|
fetchSchema();
|
|
@@ -626,7 +522,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
626
522
|
...constants_1.defaultAST,
|
|
627
523
|
...baseAst,
|
|
628
524
|
...(!baseAst?.columns && {
|
|
629
|
-
columns: getAllPossibleColumns().map((c) => {
|
|
525
|
+
columns: (0, astProcessing_1.getAllPossibleColumns)(baseAst, schema).map((c) => {
|
|
630
526
|
const newColumn = (0, util_1.deepCopy)(constants_1.defaultColumn);
|
|
631
527
|
newColumn.expr.column = c.name;
|
|
632
528
|
return newColumn;
|
|
@@ -646,7 +542,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
646
542
|
...constants_1.defaultAST,
|
|
647
543
|
...baseAst,
|
|
648
544
|
...(!baseAst?.columns && {
|
|
649
|
-
columns: getAllPossibleColumns().map((c) => {
|
|
545
|
+
columns: (0, astProcessing_1.getAllPossibleColumns)(baseAst, schema).map((c) => {
|
|
650
546
|
const newColumn = (0, util_1.deepCopy)(constants_1.defaultColumn);
|
|
651
547
|
newColumn.expr.column = c.name;
|
|
652
548
|
return newColumn;
|
|
@@ -747,7 +643,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
747
643
|
...constants_1.defaultAST,
|
|
748
644
|
...baseAst,
|
|
749
645
|
...(!baseAst?.columns && {
|
|
750
|
-
columns: getAllPossibleColumns().map((c) => {
|
|
646
|
+
columns: (0, astProcessing_1.getAllPossibleColumns)(baseAst, schema).map((c) => {
|
|
751
647
|
const newColumn = (0, util_1.deepCopy)(constants_1.defaultColumn);
|
|
752
648
|
newColumn.expr.column = c.name;
|
|
753
649
|
return newColumn;
|
|
@@ -762,169 +658,6 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
762
658
|
fetchSqlQuery(newAst, newState);
|
|
763
659
|
});
|
|
764
660
|
};
|
|
765
|
-
// TODO: Merge this function with the updateFormData function
|
|
766
|
-
const updateActiveItem = (updates, { isDeletion = false, isInsertion = false, isReplaceSubtree = false, isAddVariant = false, isDeleteVariant = false, column = undefined, }) => {
|
|
767
|
-
let newState = (0, util_1.deepCopy)(activeEditItem);
|
|
768
|
-
updates.forEach(({ path, value }) => {
|
|
769
|
-
let current = newState;
|
|
770
|
-
const globalPath = path;
|
|
771
|
-
const paths = globalPath.split('.').filter((p) => p);
|
|
772
|
-
if (paths.length === 0 && !isInsertion && !isReplaceSubtree) {
|
|
773
|
-
setActiveEditItem(null);
|
|
774
|
-
return;
|
|
775
|
-
}
|
|
776
|
-
const isOperatorChange = paths[paths.length - 1] === 'operator';
|
|
777
|
-
let parent = null;
|
|
778
|
-
let parentKey = null;
|
|
779
|
-
for (let i = 0; i < paths.length - 1; i++) {
|
|
780
|
-
let currentPath = paths[i];
|
|
781
|
-
let index;
|
|
782
|
-
if (paths[i].includes('||')) {
|
|
783
|
-
const splitPath = paths[i].split('||');
|
|
784
|
-
currentPath = splitPath[0];
|
|
785
|
-
index = splitPath[1];
|
|
786
|
-
}
|
|
787
|
-
if (current[currentPath]) {
|
|
788
|
-
parent = current;
|
|
789
|
-
parentKey = currentPath;
|
|
790
|
-
current = current[currentPath];
|
|
791
|
-
}
|
|
792
|
-
if (index) {
|
|
793
|
-
current = current[parseInt(index)];
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
const lastKey = paths[paths.length - 1];
|
|
797
|
-
if (isDeletion) {
|
|
798
|
-
if (lastKey === 'left' || lastKey === 'right') {
|
|
799
|
-
if (parent) {
|
|
800
|
-
if (lastKey === 'right') {
|
|
801
|
-
parent[parentKey] = parent[parentKey].left;
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
parent[parentKey] = parent[parentKey].right;
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
else {
|
|
808
|
-
delete current[lastKey];
|
|
809
|
-
if (newState?.left && !newState?.right) {
|
|
810
|
-
newState = newState.left;
|
|
811
|
-
}
|
|
812
|
-
else if (newState?.right && !newState?.left) {
|
|
813
|
-
newState = newState.right;
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
else if (isInsertion) {
|
|
819
|
-
const columns = getAllPossibleColumns();
|
|
820
|
-
const defaultColumn = columns[0].name;
|
|
821
|
-
// TODO: I think this is a bug, take a closer look here
|
|
822
|
-
newState = {
|
|
823
|
-
type: 'binary_expr',
|
|
824
|
-
operator: 'AND',
|
|
825
|
-
left: newState,
|
|
826
|
-
right: {
|
|
827
|
-
...constants_1.defaultEntry,
|
|
828
|
-
left: {
|
|
829
|
-
...constants_1.defaultEntry.left,
|
|
830
|
-
column: defaultColumn,
|
|
831
|
-
},
|
|
832
|
-
},
|
|
833
|
-
};
|
|
834
|
-
}
|
|
835
|
-
else if (isAddVariant) {
|
|
836
|
-
const newVariant = (0, util_1.deepCopy)(constants_1.defaultVariant);
|
|
837
|
-
if (value) {
|
|
838
|
-
newVariant.args.value[0].value = value;
|
|
839
|
-
// if there is already a single default value there,
|
|
840
|
-
// let's remove it so when we push we replace.
|
|
841
|
-
if (current[lastKey].length === 1 &&
|
|
842
|
-
current[lastKey][0].args.value[0].value === '') {
|
|
843
|
-
current[lastKey].pop();
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
current[lastKey].push(newVariant);
|
|
847
|
-
}
|
|
848
|
-
else if (isDeleteVariant) {
|
|
849
|
-
if (value) {
|
|
850
|
-
const argList = current[lastKey];
|
|
851
|
-
argList.splice(argList.findIndex((arg) => arg.args.value[0].value === value), 1);
|
|
852
|
-
}
|
|
853
|
-
else {
|
|
854
|
-
current[lastKey].pop();
|
|
855
|
-
}
|
|
856
|
-
// add back in a phantom element to prevent app from crashing
|
|
857
|
-
// when the user removes all variants and hits save.
|
|
858
|
-
if (current[lastKey].length === 0) {
|
|
859
|
-
const newVariant = (0, util_1.deepCopy)(constants_1.defaultVariant);
|
|
860
|
-
newVariant.args.value[0].value = '';
|
|
861
|
-
current[lastKey].push(newVariant);
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
else if (isReplaceSubtree) {
|
|
865
|
-
if (lastKey) {
|
|
866
|
-
current[lastKey] = value;
|
|
867
|
-
}
|
|
868
|
-
else {
|
|
869
|
-
newState = value;
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
else if (isOperatorChange) {
|
|
873
|
-
const newOp = value;
|
|
874
|
-
const oldOp = current[lastKey];
|
|
875
|
-
if (operators_1.OPERATOR_GROUPS[oldOp] === operators_1.OPERATOR_GROUPS[newOp]) {
|
|
876
|
-
current[lastKey] = value;
|
|
877
|
-
}
|
|
878
|
-
else {
|
|
879
|
-
const group = operators_1.OPERATOR_GROUPS[newOp];
|
|
880
|
-
const subtree = (0, operators_1.getDefaultOperatorSubtrees)(group, newOp, column, '', client.databaseType);
|
|
881
|
-
if (parentKey) {
|
|
882
|
-
parent[parentKey] = (0, util_1.deepCopy)(subtree);
|
|
883
|
-
}
|
|
884
|
-
else {
|
|
885
|
-
newState = (0, util_1.deepCopy)(subtree);
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
else {
|
|
890
|
-
if (typeof current[lastKey] === 'object' && current[lastKey] !== null) {
|
|
891
|
-
current[lastKey].value = value;
|
|
892
|
-
}
|
|
893
|
-
else {
|
|
894
|
-
current[lastKey] = value;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
});
|
|
898
|
-
// Function to immutably update or delete nodes based on their path
|
|
899
|
-
setActiveEditItem(newState);
|
|
900
|
-
};
|
|
901
|
-
const handleChange = (updates) => {
|
|
902
|
-
const callback = isPending ? updateActiveItem : updateFormData;
|
|
903
|
-
callback(updates, {});
|
|
904
|
-
};
|
|
905
|
-
const handleChangeText = (updates) => {
|
|
906
|
-
const callback = isPending ? updateActiveItem : updateFormData;
|
|
907
|
-
callback(updates, {});
|
|
908
|
-
};
|
|
909
|
-
// Function to handle operator changes
|
|
910
|
-
const handleOperatorChange = (value, node, keyPrefix, column = null) => {
|
|
911
|
-
if (!keyPrefix) {
|
|
912
|
-
setTopLevelBinaryOperator(value);
|
|
913
|
-
}
|
|
914
|
-
if (isPending) {
|
|
915
|
-
updateActiveItem([{ path: keyPrefix + 'operator', value }], { column });
|
|
916
|
-
}
|
|
917
|
-
else {
|
|
918
|
-
updateFormData([{ path: keyPrefix + 'operator', value }], { column });
|
|
919
|
-
}
|
|
920
|
-
};
|
|
921
|
-
// Function to replace an entire subtree with a given value.
|
|
922
|
-
const handleReplaceSubtree = (keyPrefix, newValue, pending = isPending) => {
|
|
923
|
-
const callback = pending ? updateActiveItem : updateFormData;
|
|
924
|
-
callback([{ path: keyPrefix, value: newValue }], {
|
|
925
|
-
isReplaceSubtree: true,
|
|
926
|
-
});
|
|
927
|
-
};
|
|
928
661
|
// Function to handle the insertion of expressions
|
|
929
662
|
const handleInsertion = (value, op = 'OR', isCondition = undefined) => {
|
|
930
663
|
updateFormData([{ path: '', value }], {
|
|
@@ -933,23 +666,6 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
933
666
|
isCondition,
|
|
934
667
|
});
|
|
935
668
|
};
|
|
936
|
-
// Function to handle the insertion of expr_list variants
|
|
937
|
-
const handleInsertVariant = (key, name = null) => {
|
|
938
|
-
// note: if name, treat that as the name of the value to insert
|
|
939
|
-
const callback = isPending ? updateActiveItem : updateFormData;
|
|
940
|
-
callback([{ path: key, value: name }], { isAddVariant: true });
|
|
941
|
-
};
|
|
942
|
-
// Function to handle the insertion of expr_list variants
|
|
943
|
-
const handleDeleteVariant = (key, name = null) => {
|
|
944
|
-
// note: if name, treat that as the name of the valeu to delete
|
|
945
|
-
const callback = isPending ? updateActiveItem : updateFormData;
|
|
946
|
-
callback([{ path: key, value: name }], { isDeleteVariant: true });
|
|
947
|
-
};
|
|
948
|
-
const getColumnValueForColumnComparison = (node) => node.left.value ??
|
|
949
|
-
node.left.column ??
|
|
950
|
-
node.left.args?.value[0]?.value ??
|
|
951
|
-
node.left.args?.value[0]?.column ??
|
|
952
|
-
undefined;
|
|
953
669
|
/**
|
|
954
670
|
* Searches for the column by name and returns the field type.
|
|
955
671
|
*
|
|
@@ -1046,676 +762,6 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
1046
762
|
return;
|
|
1047
763
|
}
|
|
1048
764
|
};
|
|
1049
|
-
/**
|
|
1050
|
-
* Render form fields based on the type of the node
|
|
1051
|
-
* @param node the AST or subtree to render recursively
|
|
1052
|
-
* @param keyPrefix a stringified version of the path from the root
|
|
1053
|
-
*
|
|
1054
|
-
* Note: The keyPrefix should be separated by '.' characters and each item
|
|
1055
|
-
* should be a valid index into the node (eg. 'left.right.value' is a valid
|
|
1056
|
-
* keyPrefix but 'left.args[0].value' is not -- should be 'left.args.0.value')
|
|
1057
|
-
*/
|
|
1058
|
-
const renderNode = (node, keyPrefix = '') => {
|
|
1059
|
-
const dateComparisonPartialMatch = (0, util_1.formatDateComparisonNode)(node);
|
|
1060
|
-
switch (node.type) {
|
|
1061
|
-
case 'binary_expr':
|
|
1062
|
-
if (dateComparisonPartialMatch ||
|
|
1063
|
-
((0, util_1.isDateTruncEquals)(node) && client.databaseType !== 'BigQuery')) {
|
|
1064
|
-
const { dateColumn, dateFilterType, intervalCount, intervalType, intervalPaths, } = (0, util_1.getDateFilterInfo)(node);
|
|
1065
|
-
const isPlural = intervalCount !== 1 && dateFilterType !== 'in the current'
|
|
1066
|
-
? 's'
|
|
1067
|
-
: '';
|
|
1068
|
-
// Pull off the string literal date for "equals" comparisons
|
|
1069
|
-
const rawDateStringEquals = node.right?.value ??
|
|
1070
|
-
node.right?.args?.value[1]?.column ??
|
|
1071
|
-
node.right?.args?.value[1]?.value;
|
|
1072
|
-
const rawDateStringEqualsPath = (node.right?.value && 'node.right.value') ??
|
|
1073
|
-
(node.right?.args?.value[1]?.column &&
|
|
1074
|
-
'node.right.args.value.1.column') ??
|
|
1075
|
-
(node.right?.args?.value[1]?.value &&
|
|
1076
|
-
'node.right.args.value.1.value');
|
|
1077
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', gap: 20 }, children: [(0, jsx_runtime_1.jsx)(SelectComponent, { value: dateColumn, onChange: (event) => {
|
|
1078
|
-
const columnType = getColumnTypeByName(event.target.value);
|
|
1079
|
-
if ((0, ast_1.isDateishColumnType)(columnType)) {
|
|
1080
|
-
// handleChange(value, keyPrefix + dateColumnPath, "text");
|
|
1081
|
-
handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
|
|
1082
|
-
}
|
|
1083
|
-
else if ((0, ast_1.isNumericColumnType)(columnType)) {
|
|
1084
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultNumericComparison);
|
|
1085
|
-
newSubtree.left.column = event.target.value;
|
|
1086
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1087
|
-
}
|
|
1088
|
-
else if ((0, ast_1.isBoolColumnType)(columnType)) {
|
|
1089
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultBoolComparison);
|
|
1090
|
-
newSubtree.left.column = event.target.value;
|
|
1091
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1092
|
-
}
|
|
1093
|
-
else {
|
|
1094
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultEntry);
|
|
1095
|
-
newSubtree.left.args.value[0].column = event.target.value;
|
|
1096
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1097
|
-
}
|
|
1098
|
-
}, options: getAllPossibleColumns().map((column) => ({
|
|
1099
|
-
label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(column.displayName),
|
|
1100
|
-
value: column.name,
|
|
1101
|
-
})), width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { value: dateFilterType, onChange: (event) => {
|
|
1102
|
-
if (event.target.value === dateFilterType)
|
|
1103
|
-
return null;
|
|
1104
|
-
let newSubtree = {};
|
|
1105
|
-
// TODO: implement one for each database type (eg. pg, snowflake, etc.)
|
|
1106
|
-
if (event.target.value === 'in the last') {
|
|
1107
|
-
newSubtree = (0, postgres_1.generateLastNPeriodsPostgres)({
|
|
1108
|
-
dateField: dateColumn,
|
|
1109
|
-
intervalPeriod: `${intervalCount ?? 1} ${intervalType}`,
|
|
1110
|
-
});
|
|
1111
|
-
}
|
|
1112
|
-
else if (event.target.value === 'in the previous') {
|
|
1113
|
-
newSubtree = (0, postgres_1.generatePreviousPeriodPostgres)({
|
|
1114
|
-
dateField: dateColumn,
|
|
1115
|
-
intervalPeriod: `${intervalCount ?? 1} ${intervalType}`,
|
|
1116
|
-
currentPeriod: intervalType,
|
|
1117
|
-
});
|
|
1118
|
-
}
|
|
1119
|
-
else if (event.target.value === 'in the current') {
|
|
1120
|
-
newSubtree = (0, postgres_1.generateCurrentPeriodPostgres)({
|
|
1121
|
-
dateField: dateColumn,
|
|
1122
|
-
currentPeriod: intervalType,
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
else if (event.target.value === 'equals') {
|
|
1126
|
-
newSubtree = (0, postgres_1.generateEqualsPostgres)({
|
|
1127
|
-
dateField: dateColumn,
|
|
1128
|
-
currentPeriod: intervalType,
|
|
1129
|
-
timestamp: '2024-01-01',
|
|
1130
|
-
});
|
|
1131
|
-
}
|
|
1132
|
-
// replace the entire subtree for this filter
|
|
1133
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1134
|
-
}, options: [
|
|
1135
|
-
{ label: 'in the last', value: 'in the last' },
|
|
1136
|
-
{ label: 'in the previous', value: 'in the previous' },
|
|
1137
|
-
{ label: 'in the current', value: 'in the current' },
|
|
1138
|
-
{ label: 'equals', value: 'equals' },
|
|
1139
|
-
], width: 200 }), !['in the current', 'equals'].includes(dateFilterType) && ((0, jsx_runtime_1.jsx)(TextInputComponent, { id: "date_filter_interval_count", value: intervalCount?.toString() ?? '', width: 70, onChange: (e) => {
|
|
1140
|
-
if (Number.isNaN(parseFloat(e.target.value || '0'))) {
|
|
1141
|
-
alert('Please input a number.');
|
|
1142
|
-
return;
|
|
1143
|
-
}
|
|
1144
|
-
const isPluralNow = parseFloat(e.target.value || '0') !== 1 ? 's' : '';
|
|
1145
|
-
intervalPaths.forEach((intervalPath) => handleChangeText([
|
|
1146
|
-
{
|
|
1147
|
-
value: `${e.target.value || 0} ${intervalType}${isPluralNow}`,
|
|
1148
|
-
path: keyPrefix + intervalPath,
|
|
1149
|
-
},
|
|
1150
|
-
]));
|
|
1151
|
-
} })), (0, jsx_runtime_1.jsx)(SelectComponent, { value: intervalType, onChange: (event) => {
|
|
1152
|
-
if (intervalPaths.length === 1 &&
|
|
1153
|
-
dateFilterType !== 'in the previous') {
|
|
1154
|
-
handleChangeText([
|
|
1155
|
-
{
|
|
1156
|
-
value: intervalCount !== null
|
|
1157
|
-
? `${intervalCount} ${event.target.value}${isPlural}`
|
|
1158
|
-
: event.target.value,
|
|
1159
|
-
path: keyPrefix + intervalPaths[0],
|
|
1160
|
-
},
|
|
1161
|
-
]);
|
|
1162
|
-
return;
|
|
1163
|
-
}
|
|
1164
|
-
let newSubtree;
|
|
1165
|
-
if (dateFilterType === 'in the previous') {
|
|
1166
|
-
newSubtree = (0, postgres_1.generatePreviousPeriodPostgres)({
|
|
1167
|
-
dateField: dateColumn,
|
|
1168
|
-
intervalPeriod: `${intervalCount ?? 1} ${event.target.value}`,
|
|
1169
|
-
currentPeriod: event.target.value,
|
|
1170
|
-
});
|
|
1171
|
-
}
|
|
1172
|
-
else if (dateFilterType === 'equals') {
|
|
1173
|
-
newSubtree = (0, postgres_1.generateEqualsPostgres)({
|
|
1174
|
-
dateField: dateColumn,
|
|
1175
|
-
currentPeriod: event.target.value,
|
|
1176
|
-
timestamp: rawDateStringEquals,
|
|
1177
|
-
});
|
|
1178
|
-
}
|
|
1179
|
-
else {
|
|
1180
|
-
newSubtree = (0, postgres_1.generateCurrentPeriodPostgres)({
|
|
1181
|
-
dateField: dateColumn,
|
|
1182
|
-
currentPeriod: event.target.value,
|
|
1183
|
-
});
|
|
1184
|
-
}
|
|
1185
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1186
|
-
}, options: dateFilterType === 'in the previous' ||
|
|
1187
|
-
dateFilterType === 'in the last'
|
|
1188
|
-
? [
|
|
1189
|
-
{ label: `year${isPlural}`, value: 'year' },
|
|
1190
|
-
{ label: `month${isPlural}`, value: 'month' },
|
|
1191
|
-
{ label: `week${isPlural}`, value: 'week' },
|
|
1192
|
-
{ label: `day${isPlural}`, value: 'day' },
|
|
1193
|
-
{ label: `hour${isPlural}`, value: 'hour' },
|
|
1194
|
-
]
|
|
1195
|
-
: [
|
|
1196
|
-
{ label: `year${isPlural}`, value: 'year' },
|
|
1197
|
-
{ label: `quarter${isPlural}`, value: 'quarter' },
|
|
1198
|
-
{ label: `month${isPlural}`, value: 'month' },
|
|
1199
|
-
{ label: `week${isPlural}`, value: 'week' },
|
|
1200
|
-
{ label: `day${isPlural}`, value: 'day' },
|
|
1201
|
-
{ label: `hour${isPlural}`, value: 'hour' },
|
|
1202
|
-
], width: 200 }), dateFilterType === 'equals' && ((0, jsx_runtime_1.jsx)(TextInputComponent, { id: "date_filter_equals_raw_date", value: rawDateStringEquals, width: 120, onChange: (e) => {
|
|
1203
|
-
handleChangeText([
|
|
1204
|
-
{
|
|
1205
|
-
value: e.target.value,
|
|
1206
|
-
path: keyPrefix + rawDateStringEqualsPath,
|
|
1207
|
-
},
|
|
1208
|
-
]);
|
|
1209
|
-
} }))] }));
|
|
1210
|
-
}
|
|
1211
|
-
else if ((0, util_1.isInTheLastInterval)(node, client.databaseType)) {
|
|
1212
|
-
const { dateColumn } = (0, util_1.getDateFilterInfo)(node);
|
|
1213
|
-
const options = getAllPossibleColumns().map((column) => ({
|
|
1214
|
-
label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(column.displayName),
|
|
1215
|
-
value: column.name,
|
|
1216
|
-
}));
|
|
1217
|
-
const plural = node.right.args.value[1].expr.value !== 1 ? 's' : '';
|
|
1218
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1219
|
-
display: 'flex',
|
|
1220
|
-
flexDirection: 'row',
|
|
1221
|
-
alignItems: 'center',
|
|
1222
|
-
gap: 20,
|
|
1223
|
-
}, children: [(0, jsx_runtime_1.jsx)(SelectComponent, { value: node.left.column, onChange: (event) => {
|
|
1224
|
-
const columnType = getColumnTypeByName(event.target.value);
|
|
1225
|
-
if ((0, ast_1.isDateishColumnType)(columnType)) {
|
|
1226
|
-
// handleChange(value, keyPrefix + dateColumnPath, "text");
|
|
1227
|
-
handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
|
|
1228
|
-
}
|
|
1229
|
-
else if ((0, ast_1.isNumericColumnType)(columnType)) {
|
|
1230
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultNumericComparison);
|
|
1231
|
-
newSubtree.left.column = event.target.value;
|
|
1232
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1233
|
-
}
|
|
1234
|
-
else if ((0, ast_1.isBoolColumnType)(columnType)) {
|
|
1235
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultBoolComparison);
|
|
1236
|
-
newSubtree.left.column = event.target.value;
|
|
1237
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1238
|
-
}
|
|
1239
|
-
else {
|
|
1240
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultEntry);
|
|
1241
|
-
newSubtree.left.args.value[0].column = event.target.value;
|
|
1242
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1243
|
-
}
|
|
1244
|
-
}, options: options, width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { value: 'IN_THE_LAST', onChange: (event) => {
|
|
1245
|
-
handleOperatorChange(event.target.value, node, keyPrefix, dateColumn);
|
|
1246
|
-
}, options: [
|
|
1247
|
-
{ label: 'in the last', value: 'IN_THE_LAST' },
|
|
1248
|
-
{ label: 'in the previous', value: 'IN_THE_PREVIOUS' },
|
|
1249
|
-
{ label: 'in the current', value: 'IN_THE_CURRENT' },
|
|
1250
|
-
{ label: 'equals', value: 'EQUALS' },
|
|
1251
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1252
|
-
{ label: 'is null', value: 'IS' },
|
|
1253
|
-
], width: 200 }), (0, jsx_runtime_1.jsx)(TextInputComponent, { id: 'date_window_interval_count', value: node.right.args.value[1].expr.value, width: 120, onChange: (e) => {
|
|
1254
|
-
handleChange([
|
|
1255
|
-
{
|
|
1256
|
-
value: e.target.value,
|
|
1257
|
-
path: keyPrefix + 'right.args.value||1.expr.value',
|
|
1258
|
-
},
|
|
1259
|
-
]);
|
|
1260
|
-
} }), (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(SelectComponent, { value: node.right.args.value[1].unit, onChange: (event) => handleChange([
|
|
1261
|
-
{
|
|
1262
|
-
value: event.target.value,
|
|
1263
|
-
path: keyPrefix + 'right.args.value||1.unit',
|
|
1264
|
-
},
|
|
1265
|
-
]), options: [
|
|
1266
|
-
{ label: `year${plural}`, value: '* 365 DAY' },
|
|
1267
|
-
{ label: `month${plural}`, value: '* 30 DAY' },
|
|
1268
|
-
{ label: `week${plural}`, value: '* 7 DAY' },
|
|
1269
|
-
{ label: `day${plural}`, value: 'DAY' },
|
|
1270
|
-
], width: 200 }) })] }));
|
|
1271
|
-
}
|
|
1272
|
-
else if ((0, util_1.isTheCurrentInterval)(node, client.databaseType)) {
|
|
1273
|
-
const options = getAllPossibleColumns().map((column) => ({
|
|
1274
|
-
label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(column.displayName),
|
|
1275
|
-
value: column.name,
|
|
1276
|
-
}));
|
|
1277
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1278
|
-
display: 'flex',
|
|
1279
|
-
flexDirection: 'row',
|
|
1280
|
-
alignItems: 'center',
|
|
1281
|
-
gap: 20,
|
|
1282
|
-
}, children: [(0, jsx_runtime_1.jsx)(SelectComponent, { value: node.left.column, onChange: (event) => {
|
|
1283
|
-
const columnType = getColumnTypeByName(event.target.value);
|
|
1284
|
-
if ((0, ast_1.isDateishColumnType)(columnType)) {
|
|
1285
|
-
// handleChange(value, keyPrefix + dateColumnPath, "text");
|
|
1286
|
-
handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
|
|
1287
|
-
}
|
|
1288
|
-
else if ((0, ast_1.isNumericColumnType)(columnType)) {
|
|
1289
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultNumericComparison);
|
|
1290
|
-
newSubtree.left.column = event.target.value;
|
|
1291
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1292
|
-
}
|
|
1293
|
-
else if ((0, ast_1.isBoolColumnType)(columnType)) {
|
|
1294
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultBoolComparison);
|
|
1295
|
-
newSubtree.left.column = event.target.value;
|
|
1296
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1297
|
-
}
|
|
1298
|
-
else {
|
|
1299
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultEntry);
|
|
1300
|
-
newSubtree.left.args.value[0].column = event.target.value;
|
|
1301
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1302
|
-
}
|
|
1303
|
-
}, options: options, width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { value: 'IN_THE_CURRENT', onChange: (event) => {
|
|
1304
|
-
handleOperatorChange(event.target.value, node, keyPrefix, node.left.column);
|
|
1305
|
-
}, options: [
|
|
1306
|
-
{ label: 'in the last', value: 'IN_THE_LAST' },
|
|
1307
|
-
{ label: 'in the previous', value: 'IN_THE_PREVIOUS' },
|
|
1308
|
-
{ label: 'in the current', value: 'IN_THE_CURRENT' },
|
|
1309
|
-
{ label: 'equals', value: 'EQUALS' },
|
|
1310
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1311
|
-
{ label: 'is null', value: 'IS' },
|
|
1312
|
-
// { label: 'equals', value: 'equals' },
|
|
1313
|
-
], width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { value: node.left.args.value[1].column, onChange: (event) => {
|
|
1314
|
-
handleChange([
|
|
1315
|
-
{
|
|
1316
|
-
value: event.target.value,
|
|
1317
|
-
path: 'right.args.value||1.column',
|
|
1318
|
-
},
|
|
1319
|
-
{
|
|
1320
|
-
value: event.target.value,
|
|
1321
|
-
path: 'left.args.value||1.column',
|
|
1322
|
-
},
|
|
1323
|
-
]);
|
|
1324
|
-
}, options: [
|
|
1325
|
-
{ label: `year`, value: 'YEAR' },
|
|
1326
|
-
{ label: `quarter`, value: 'QUARTER' },
|
|
1327
|
-
{ label: `month`, value: 'MONTH' },
|
|
1328
|
-
{ label: `week`, value: 'WEEK' },
|
|
1329
|
-
], width: 200 })] }));
|
|
1330
|
-
}
|
|
1331
|
-
else if ((0, util_1.isThePreviousInterval)(node)) {
|
|
1332
|
-
const options = getAllPossibleColumns().map((column) => ({
|
|
1333
|
-
label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(column.displayName),
|
|
1334
|
-
value: column.name,
|
|
1335
|
-
}));
|
|
1336
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1337
|
-
display: 'flex',
|
|
1338
|
-
flexDirection: 'row',
|
|
1339
|
-
alignItems: 'center',
|
|
1340
|
-
gap: 20,
|
|
1341
|
-
}, children: [(0, jsx_runtime_1.jsx)(SelectComponent, { value: node.left.column, onChange: (event) => {
|
|
1342
|
-
const columnType = getColumnTypeByName(event.target.value);
|
|
1343
|
-
if ((0, ast_1.isDateishColumnType)(columnType)) {
|
|
1344
|
-
// handleChange(value, keyPrefix + dateColumnPath, "text");
|
|
1345
|
-
handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
|
|
1346
|
-
}
|
|
1347
|
-
else if ((0, ast_1.isNumericColumnType)(columnType)) {
|
|
1348
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultNumericComparison);
|
|
1349
|
-
newSubtree.left.column = event.target.value;
|
|
1350
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1351
|
-
}
|
|
1352
|
-
else if ((0, ast_1.isBoolColumnType)(columnType)) {
|
|
1353
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultBoolComparison);
|
|
1354
|
-
newSubtree.left.column = event.target.value;
|
|
1355
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1356
|
-
}
|
|
1357
|
-
else {
|
|
1358
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultEntry);
|
|
1359
|
-
newSubtree.left.args.value[0].column = event.target.value;
|
|
1360
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1361
|
-
}
|
|
1362
|
-
}, options: options, width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { value: 'IN_THE_PREVIOUS', onChange: (event) => {
|
|
1363
|
-
handleOperatorChange(event.target.value, node, keyPrefix, node.left.column);
|
|
1364
|
-
}, options: [
|
|
1365
|
-
{ label: 'in the last', value: 'IN_THE_LAST' },
|
|
1366
|
-
{ label: 'in the previous', value: 'IN_THE_PREVIOUS' },
|
|
1367
|
-
{ label: 'in the current', value: 'IN_THE_CURRENT' },
|
|
1368
|
-
{ label: 'equals', value: 'EQUALS' },
|
|
1369
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1370
|
-
{ label: 'is null', value: 'IS' },
|
|
1371
|
-
// { label: 'equals', value: 'equals' },
|
|
1372
|
-
], width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { value: node.left.args.value[1].column, onChange: (event) => {
|
|
1373
|
-
const dayConversion = {
|
|
1374
|
-
YEAR: 365,
|
|
1375
|
-
QUARTER: 90,
|
|
1376
|
-
MONTH: 30,
|
|
1377
|
-
WEEK: 7,
|
|
1378
|
-
};
|
|
1379
|
-
handleChange([
|
|
1380
|
-
{
|
|
1381
|
-
value: event.target.value,
|
|
1382
|
-
path: 'left.args.value||1.column',
|
|
1383
|
-
},
|
|
1384
|
-
{
|
|
1385
|
-
value: event.target.value,
|
|
1386
|
-
path: 'right.args.value||1.column',
|
|
1387
|
-
},
|
|
1388
|
-
{
|
|
1389
|
-
value: dayConversion[event.target.value] || 30,
|
|
1390
|
-
path: 'right.args.value||0.args.value||1.expr.value',
|
|
1391
|
-
},
|
|
1392
|
-
]);
|
|
1393
|
-
}, options: [
|
|
1394
|
-
{ label: `year`, value: 'YEAR' },
|
|
1395
|
-
{ label: `quarter`, value: 'QUARTER' },
|
|
1396
|
-
{ label: `month`, value: 'MONTH' },
|
|
1397
|
-
{ label: `week`, value: 'WEEK' },
|
|
1398
|
-
], width: 200 })] }));
|
|
1399
|
-
}
|
|
1400
|
-
else if ((0, util_1.isEquals)(node, client.databaseType)) {
|
|
1401
|
-
const options = getAllPossibleColumns().map((column) => ({
|
|
1402
|
-
label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(column.displayName),
|
|
1403
|
-
value: column.name,
|
|
1404
|
-
}));
|
|
1405
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1406
|
-
display: 'flex',
|
|
1407
|
-
flexDirection: 'row',
|
|
1408
|
-
alignItems: 'center',
|
|
1409
|
-
gap: 20,
|
|
1410
|
-
}, children: [(0, jsx_runtime_1.jsx)(SelectComponent, { value: node.left.column, onChange: (event) => {
|
|
1411
|
-
const columnType = getColumnTypeByName(event.target.value);
|
|
1412
|
-
if ((0, ast_1.isDateishColumnType)(columnType)) {
|
|
1413
|
-
// handleChange(value, keyPrefix + dateColumnPath, "text");
|
|
1414
|
-
handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
|
|
1415
|
-
}
|
|
1416
|
-
else if ((0, ast_1.isNumericColumnType)(columnType)) {
|
|
1417
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultNumericComparison);
|
|
1418
|
-
newSubtree.left.column = event.target.value;
|
|
1419
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1420
|
-
}
|
|
1421
|
-
else if ((0, ast_1.isBoolColumnType)(columnType)) {
|
|
1422
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultBoolComparison);
|
|
1423
|
-
newSubtree.left.column = event.target.value;
|
|
1424
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1425
|
-
}
|
|
1426
|
-
else {
|
|
1427
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultEntry);
|
|
1428
|
-
newSubtree.left.args.value[0].column = event.target.value;
|
|
1429
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1430
|
-
}
|
|
1431
|
-
}, options: options, width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { value: 'EQUALS', onChange: (event) => {
|
|
1432
|
-
handleOperatorChange(event.target.value, node, keyPrefix, node.left.column);
|
|
1433
|
-
}, options: [
|
|
1434
|
-
{ label: 'in the last', value: 'IN_THE_LAST' },
|
|
1435
|
-
{ label: 'in the previous', value: 'IN_THE_PREVIOUS' },
|
|
1436
|
-
{ label: 'in the current', value: 'IN_THE_CURRENT' },
|
|
1437
|
-
{ label: 'equals', value: 'EQUALS' },
|
|
1438
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1439
|
-
{ label: 'is null', value: 'IS' },
|
|
1440
|
-
// { label: 'equals', value: 'equals' },
|
|
1441
|
-
], width: 200 }), (0, jsx_runtime_1.jsx)(SelectComponent, { value: node.right.args.value[1].column, onChange: (event) => {
|
|
1442
|
-
handleChange([
|
|
1443
|
-
{
|
|
1444
|
-
value: event.target.value,
|
|
1445
|
-
path: 'right.args.value||1.column',
|
|
1446
|
-
},
|
|
1447
|
-
{
|
|
1448
|
-
value: event.target.value,
|
|
1449
|
-
path: 'left.args.value||1.column',
|
|
1450
|
-
},
|
|
1451
|
-
]);
|
|
1452
|
-
}, options: [
|
|
1453
|
-
{ label: `year`, value: 'YEAR' },
|
|
1454
|
-
{ label: `quarter`, value: 'QUARTER' },
|
|
1455
|
-
{ label: `month`, value: 'MONTH' },
|
|
1456
|
-
{ label: `week`, value: 'WEEK' },
|
|
1457
|
-
], width: 200 }), (0, jsx_runtime_1.jsx)(TextInputComponent, { id: 'quoted_string', value: node.right.args.value[0].value, width: 120, onChange: (e) => handleChange([
|
|
1458
|
-
{
|
|
1459
|
-
value: e.target.value,
|
|
1460
|
-
path: 'right.args.value||0.value',
|
|
1461
|
-
},
|
|
1462
|
-
]) })] }));
|
|
1463
|
-
}
|
|
1464
|
-
else if ((0, util_1.isColumnComparison)(node)) {
|
|
1465
|
-
const options = getAllPossibleColumns().map((column) => ({
|
|
1466
|
-
label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(column.displayName),
|
|
1467
|
-
value: column.name,
|
|
1468
|
-
}));
|
|
1469
|
-
// grab the value of the left child of the column comparison
|
|
1470
|
-
// operator (ie. the column name)
|
|
1471
|
-
const leftChildValue = getColumnValueForColumnComparison(node);
|
|
1472
|
-
const tables = (0, ast_1.getTableNames)(baseAst);
|
|
1473
|
-
const table = tables.length === 1 ? tables[0] : initialTableName;
|
|
1474
|
-
const column = schema
|
|
1475
|
-
.find((tableInfo) => tableInfo.name === table)
|
|
1476
|
-
?.columns.find((col) => col.name === leftChildValue);
|
|
1477
|
-
const columnType = column?.fieldType;
|
|
1478
|
-
const operatorOptions = [
|
|
1479
|
-
...((0, ast_1.isNumericColumnType)(columnType)
|
|
1480
|
-
? [
|
|
1481
|
-
{ label: 'equal to', value: '=' },
|
|
1482
|
-
{ label: 'not equal to', value: '!=' },
|
|
1483
|
-
{ label: 'greater than', value: '>' },
|
|
1484
|
-
{ label: 'less than', value: '<' },
|
|
1485
|
-
{ label: 'greater than or equal to', value: '>=' },
|
|
1486
|
-
{ label: 'less than or equal to', value: '<=' },
|
|
1487
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1488
|
-
{ label: 'is null', value: 'IS' },
|
|
1489
|
-
]
|
|
1490
|
-
: []),
|
|
1491
|
-
...((0, ast_1.isTextColumnType)(columnType)
|
|
1492
|
-
? [
|
|
1493
|
-
{ label: 'is exactly', value: 'LIKE' },
|
|
1494
|
-
{ label: 'is not exactly', value: 'NOT LIKE' },
|
|
1495
|
-
{ label: 'is', value: 'IN' },
|
|
1496
|
-
{ label: 'is not', value: 'NOT IN' },
|
|
1497
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1498
|
-
{ label: 'is null', value: 'IS' },
|
|
1499
|
-
]
|
|
1500
|
-
: []),
|
|
1501
|
-
...((0, ast_1.isDateishColumnType)(columnType)
|
|
1502
|
-
? [
|
|
1503
|
-
{ label: 'in the last', value: 'IN_THE_LAST' },
|
|
1504
|
-
{
|
|
1505
|
-
label: 'in the previous',
|
|
1506
|
-
value: 'IN_THE_PREVIOUS',
|
|
1507
|
-
},
|
|
1508
|
-
{ label: 'in the current', value: 'IN_THE_CURRENT' },
|
|
1509
|
-
{ label: 'equals', value: 'equals' },
|
|
1510
|
-
]
|
|
1511
|
-
: []),
|
|
1512
|
-
];
|
|
1513
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1514
|
-
display: 'flex',
|
|
1515
|
-
gap: 12,
|
|
1516
|
-
flexDirection: 'column',
|
|
1517
|
-
width: '100%',
|
|
1518
|
-
padding: '6px 0px',
|
|
1519
|
-
}, children: [(0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1520
|
-
display: 'flex',
|
|
1521
|
-
gap: 20,
|
|
1522
|
-
flexDirection: (0, util_1.showNodeAsRow)(node, formData)
|
|
1523
|
-
? 'row'
|
|
1524
|
-
: 'column',
|
|
1525
|
-
width: '100%',
|
|
1526
|
-
}, children: [(0, jsx_runtime_1.jsx)(SelectComponent, { value: leftChildValue, onChange: (event) => {
|
|
1527
|
-
const columnType = getColumnTypeByName(event.target.value);
|
|
1528
|
-
if ((0, ast_1.isDateishColumnType)(columnType)) {
|
|
1529
|
-
handleOperatorChange('IN_THE_LAST', node, keyPrefix, event.target.value);
|
|
1530
|
-
}
|
|
1531
|
-
else if ((0, ast_1.isNumericColumnType)(columnType)) {
|
|
1532
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultNumericComparison);
|
|
1533
|
-
newSubtree.left.column = event.target.value;
|
|
1534
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1535
|
-
}
|
|
1536
|
-
else if ((0, ast_1.isBoolColumnType)(columnType)) {
|
|
1537
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultBoolComparison);
|
|
1538
|
-
newSubtree.left.column = event.target.value;
|
|
1539
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1540
|
-
}
|
|
1541
|
-
else {
|
|
1542
|
-
const newSubtree = (0, util_1.deepCopy)(constants_1.defaultEntry);
|
|
1543
|
-
newSubtree.left.args.value[0].column = event.target.value;
|
|
1544
|
-
handleReplaceSubtree(keyPrefix, newSubtree);
|
|
1545
|
-
}
|
|
1546
|
-
}, options: options, width: 200 }), operatorOptions.length > 0 && ((0, jsx_runtime_1.jsx)(SelectComponent, { value: node.operator, onChange: (event) => {
|
|
1547
|
-
handleOperatorChange(event.target.value, node, keyPrefix, leftChildValue);
|
|
1548
|
-
}, options: operatorOptions, width: 200 })), node.right &&
|
|
1549
|
-
node.right.type !== 'expr_list' &&
|
|
1550
|
-
renderNode(node.right, keyPrefix + 'right.')] }, keyPrefix), node.right && node.right.type === 'expr_list' && ((0, jsx_runtime_1.jsx)("div", { style: {
|
|
1551
|
-
display: 'grid',
|
|
1552
|
-
gridTemplateColumns: 'repeat(2, 1fr)',
|
|
1553
|
-
gap: 12,
|
|
1554
|
-
}, children: uniqueValues[table] &&
|
|
1555
|
-
Object.keys(uniqueValues[table][leftChildValue] ?? {}).map((key) => ((0, jsx_runtime_1.jsx)(CheckboxComponent, { label: key, isChecked: uniqueValues[table][leftChildValue][key], onChange: (event) => {
|
|
1556
|
-
const newValues = (0, util_1.deepCopy)(uniqueValues);
|
|
1557
|
-
newValues[table][leftChildValue][key] =
|
|
1558
|
-
event.target.checked;
|
|
1559
|
-
setUniqueValues(newValues);
|
|
1560
|
-
if (event.target.checked) {
|
|
1561
|
-
handleInsertVariant(keyPrefix + 'right.' + 'value', key);
|
|
1562
|
-
}
|
|
1563
|
-
else {
|
|
1564
|
-
handleDeleteVariant(keyPrefix + 'right.' + 'value', key);
|
|
1565
|
-
}
|
|
1566
|
-
} }))) }, keyPrefix + 'right.'))] }));
|
|
1567
|
-
}
|
|
1568
|
-
else {
|
|
1569
|
-
const columnName = node.left.column;
|
|
1570
|
-
const column = schema
|
|
1571
|
-
.find((tableInfo) => tableInfo.name === currentTable)
|
|
1572
|
-
?.columns.find((col) => col.name === columnName);
|
|
1573
|
-
const columnType = column?.fieldType;
|
|
1574
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: {
|
|
1575
|
-
display: 'flex',
|
|
1576
|
-
gap: 12,
|
|
1577
|
-
justifyContent: 'space-between',
|
|
1578
|
-
flexDirection: (0, util_1.showNodeAsRow)(node, formData) ? 'row' : 'column',
|
|
1579
|
-
width: '100%',
|
|
1580
|
-
}, children: [node.left && renderNode(node.left, keyPrefix + 'left.'), (0, jsx_runtime_1.jsx)(SelectComponent, { value: node.operator, onChange: (event) => {
|
|
1581
|
-
handleOperatorChange(event.target.value, node, keyPrefix);
|
|
1582
|
-
}, options: [
|
|
1583
|
-
// { label: `and`, value: "AND" },
|
|
1584
|
-
// { label: `or`, value: "OR" },
|
|
1585
|
-
...((0, ast_1.isNumericColumnType)(columnType)
|
|
1586
|
-
? [
|
|
1587
|
-
{ label: 'equal to', value: '=' },
|
|
1588
|
-
{ label: 'not equal to', value: '!=' },
|
|
1589
|
-
{ label: 'greater than', value: '>' },
|
|
1590
|
-
{ label: 'less than', value: '<' },
|
|
1591
|
-
{ label: 'greater than or equal to', value: '>=' },
|
|
1592
|
-
{ label: 'less than or equal to', value: '<=' },
|
|
1593
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1594
|
-
{ label: 'is null', value: 'IS' },
|
|
1595
|
-
]
|
|
1596
|
-
: []),
|
|
1597
|
-
...((0, ast_1.isTextColumnType)(columnType)
|
|
1598
|
-
? [
|
|
1599
|
-
{ label: 'is exactly', value: 'LIKE' },
|
|
1600
|
-
{ label: 'is not exactly', value: 'NOT LIKE' },
|
|
1601
|
-
{ label: 'is', value: 'IN' },
|
|
1602
|
-
{ label: 'is not', value: 'NOT IN' },
|
|
1603
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1604
|
-
{ label: 'is null', value: 'IS' },
|
|
1605
|
-
]
|
|
1606
|
-
: []),
|
|
1607
|
-
...((0, ast_1.isDateishColumnType)(columnType)
|
|
1608
|
-
? [
|
|
1609
|
-
{ label: 'in the last', value: 'IN_THE_LAST' },
|
|
1610
|
-
{ label: 'in the previous', value: 'IN_THE_PREVIOUS' },
|
|
1611
|
-
{ label: 'in the current', value: 'IN_THE_CURRENT' },
|
|
1612
|
-
{ label: 'equals', value: 'EQUALS' },
|
|
1613
|
-
{ label: 'is not null', value: 'IS NOT' },
|
|
1614
|
-
{ label: 'is null', value: 'IS' },
|
|
1615
|
-
]
|
|
1616
|
-
: []),
|
|
1617
|
-
// { label: `minus`, value: "-" },
|
|
1618
|
-
// { label: `plus`, value: "+" },
|
|
1619
|
-
], width: 200 }), node.right && renderNode(node.right, keyPrefix + 'right.')] }, keyPrefix));
|
|
1620
|
-
}
|
|
1621
|
-
case 'column_ref': {
|
|
1622
|
-
const options = getAllPossibleColumns().map((column) => ({
|
|
1623
|
-
label: (0, textProcessing_1.snakeAndCamelCaseToTitleCase)(column.displayName),
|
|
1624
|
-
value: column.name,
|
|
1625
|
-
}));
|
|
1626
|
-
return ((0, jsx_runtime_1.jsx)(SelectComponent, { value: node.column ?? options[0]?.value, onChange: (event) => {
|
|
1627
|
-
handleChange([
|
|
1628
|
-
{ value: event.target.value, path: keyPrefix + 'column' },
|
|
1629
|
-
]);
|
|
1630
|
-
}, options: options, width: 200 }));
|
|
1631
|
-
}
|
|
1632
|
-
case 'expr_list': {
|
|
1633
|
-
const len = node.value.length;
|
|
1634
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'row', gap: 12 }, children: [node.value.map((elem, index) => {
|
|
1635
|
-
if (elem.value) {
|
|
1636
|
-
return ((0, jsx_runtime_1.jsx)(TextInputComponent, { id: `expr_list_${index}`, width: 200, value: elem.value, onChange: (e) => handleChange([
|
|
1637
|
-
{
|
|
1638
|
-
value: e.target.value,
|
|
1639
|
-
path: keyPrefix + `value.${index}.`,
|
|
1640
|
-
},
|
|
1641
|
-
]) }, `input_${index}`));
|
|
1642
|
-
}
|
|
1643
|
-
return renderNode(elem, keyPrefix + `value.${index}.`);
|
|
1644
|
-
}), len > 1 && ((0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: '-', onClick: () => handleDeleteVariant(keyPrefix + 'value') })), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { onClick: () => handleInsertVariant(keyPrefix + 'value'), label: '+' })] }, keyPrefix));
|
|
1645
|
-
}
|
|
1646
|
-
case 'double_quote_string':
|
|
1647
|
-
case 'single_quote_string':
|
|
1648
|
-
return ((0, jsx_runtime_1.jsx)(TextInputComponent, { id: 'quoted_string', value: node.value.replaceAll('%', ''), width: 120, onChange: (e) => handleChange([
|
|
1649
|
-
{
|
|
1650
|
-
value: e.target.value,
|
|
1651
|
-
path: keyPrefix + 'value',
|
|
1652
|
-
},
|
|
1653
|
-
]) }));
|
|
1654
|
-
case 'null':
|
|
1655
|
-
return (0, jsx_runtime_1.jsx)("div", {});
|
|
1656
|
-
case 'number':
|
|
1657
|
-
return ((0, jsx_runtime_1.jsx)(TextInputComponent, { id: "quill_number_input", value: node.value, width: 120, onChange: (e) => {
|
|
1658
|
-
handleChange([
|
|
1659
|
-
{
|
|
1660
|
-
value: e.target.value,
|
|
1661
|
-
path: keyPrefix + 'value',
|
|
1662
|
-
},
|
|
1663
|
-
]);
|
|
1664
|
-
} }));
|
|
1665
|
-
case 'bool':
|
|
1666
|
-
return ((0, jsx_runtime_1.jsx)(SelectComponent, { value: node.value.toString(), onChange: (event) => {
|
|
1667
|
-
let formatted = true;
|
|
1668
|
-
if (event.target.value === 'false') {
|
|
1669
|
-
formatted = false;
|
|
1670
|
-
}
|
|
1671
|
-
handleChange([
|
|
1672
|
-
{
|
|
1673
|
-
value: formatted,
|
|
1674
|
-
path: keyPrefix + 'value',
|
|
1675
|
-
},
|
|
1676
|
-
]);
|
|
1677
|
-
}, options: [
|
|
1678
|
-
{ label: 'is true', value: 'true' },
|
|
1679
|
-
{ label: 'is false', value: 'false' },
|
|
1680
|
-
], width: 200 }));
|
|
1681
|
-
case 'function':
|
|
1682
|
-
if (!node.args) {
|
|
1683
|
-
return (0, jsx_runtime_1.jsx)("label", {});
|
|
1684
|
-
}
|
|
1685
|
-
else if (node.args.type === 'expr_list' &&
|
|
1686
|
-
node.args.value.length === 1) {
|
|
1687
|
-
return ((0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'row' }, children: node.args.value[0] &&
|
|
1688
|
-
renderNode(node.args.value[0], keyPrefix + 'args.value.0.') }));
|
|
1689
|
-
}
|
|
1690
|
-
else if (node.args.type === 'expr_list' &&
|
|
1691
|
-
node.args.value.length === 2) {
|
|
1692
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'row', gap: 20 }, children: [node.args.value[0] &&
|
|
1693
|
-
renderNode(node.args.value[0], keyPrefix + 'args.value.0.'), node.args.value[1] &&
|
|
1694
|
-
renderNode(node.args.value[1], keyPrefix + 'args.value.1.')] }));
|
|
1695
|
-
}
|
|
1696
|
-
return node.name;
|
|
1697
|
-
case 'interval':
|
|
1698
|
-
return ((0, jsx_runtime_1.jsx)("div", { style: { display: 'flex', flexDirection: 'row', gap: 20 }, children: renderNode(node.expr, keyPrefix + 'expr.') }));
|
|
1699
|
-
default:
|
|
1700
|
-
return null;
|
|
1701
|
-
}
|
|
1702
|
-
};
|
|
1703
|
-
const isValidPivot = (fields) => {
|
|
1704
|
-
let validPivot = true;
|
|
1705
|
-
if (pivot.rowField &&
|
|
1706
|
-
!fields.find((field) => field.name === pivot.rowField)) {
|
|
1707
|
-
validPivot = false;
|
|
1708
|
-
}
|
|
1709
|
-
if (pivot.valueField &&
|
|
1710
|
-
!fields.find((field) => field.name === pivot.valueField)) {
|
|
1711
|
-
validPivot = false;
|
|
1712
|
-
}
|
|
1713
|
-
if (pivot.columnField &&
|
|
1714
|
-
!fields.find((field) => field.name === pivot.columnField)) {
|
|
1715
|
-
validPivot = false;
|
|
1716
|
-
}
|
|
1717
|
-
return validPivot;
|
|
1718
|
-
};
|
|
1719
765
|
/**
|
|
1720
766
|
* @param filterTree
|
|
1721
767
|
* Returns a list of filters to be displayed
|
|
@@ -1811,7 +857,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
1811
857
|
...constants_1.defaultAST,
|
|
1812
858
|
...baseAst,
|
|
1813
859
|
...(!baseAst?.columns && {
|
|
1814
|
-
columns: getAllPossibleColumns().map((c) => {
|
|
860
|
+
columns: (0, astProcessing_1.getAllPossibleColumns)(baseAst, schema).map((c) => {
|
|
1815
861
|
const newColumn = (0, util_1.deepCopy)(constants_1.defaultColumn);
|
|
1816
862
|
newColumn.expr.column = c.name;
|
|
1817
863
|
return newColumn;
|
|
@@ -1838,7 +884,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
1838
884
|
...constants_1.defaultAST,
|
|
1839
885
|
...baseAst,
|
|
1840
886
|
...(!baseAst?.columns && {
|
|
1841
|
-
columns: getAllPossibleColumns().map((c) => {
|
|
887
|
+
columns: (0, astProcessing_1.getAllPossibleColumns)(baseAst, schema).map((c) => {
|
|
1842
888
|
const newColumn = (0, util_1.deepCopy)(constants_1.defaultColumn);
|
|
1843
889
|
newColumn.expr.column = c.name;
|
|
1844
890
|
return newColumn;
|
|
@@ -1873,7 +919,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
1873
919
|
...constants_1.defaultAST,
|
|
1874
920
|
...baseAst,
|
|
1875
921
|
...(!baseAst?.columns && {
|
|
1876
|
-
columns: getAllPossibleColumns().map((c) => {
|
|
922
|
+
columns: (0, astProcessing_1.getAllPossibleColumns)(baseAst, schema).map((c) => {
|
|
1877
923
|
const newColumn = (0, util_1.deepCopy)(constants_1.defaultColumn);
|
|
1878
924
|
newColumn.expr.column = c.name;
|
|
1879
925
|
return newColumn;
|
|
@@ -1891,38 +937,6 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
1891
937
|
}
|
|
1892
938
|
}) }));
|
|
1893
939
|
};
|
|
1894
|
-
const getAllPossibleColumns = () => {
|
|
1895
|
-
if (!baseAst || !baseAst.from) {
|
|
1896
|
-
return schema.flatMap((table) => table.columns.map((c) => ({
|
|
1897
|
-
...c,
|
|
1898
|
-
table: table.displayName,
|
|
1899
|
-
})));
|
|
1900
|
-
}
|
|
1901
|
-
// TODO: support infinitely nested FROM table lookups.
|
|
1902
|
-
// This currently only supports top-level table names in the FROM section
|
|
1903
|
-
// of queries (eg. FROM "table_name", not "FROM (SELECT * FROM other) AS table_name")
|
|
1904
|
-
const tableNamesInQuery = baseAst.from.map((tbl) => tbl.table);
|
|
1905
|
-
return schema
|
|
1906
|
-
.filter((t) => tableNamesInQuery.includes(t.displayName))
|
|
1907
|
-
.flatMap((table) => table.columns
|
|
1908
|
-
.map((c) => ({
|
|
1909
|
-
...c,
|
|
1910
|
-
table: table.displayName,
|
|
1911
|
-
}))
|
|
1912
|
-
.sort((a, b) => {
|
|
1913
|
-
const aIsId = a.name.toLowerCase() === 'id' ||
|
|
1914
|
-
a.name.toLowerCase().endsWith('_id') ||
|
|
1915
|
-
a.name.endsWith('Id');
|
|
1916
|
-
const bIsId = b.name.toLowerCase() === 'id' ||
|
|
1917
|
-
b.name.toLowerCase().endsWith('_id') ||
|
|
1918
|
-
b.name.endsWith('Id');
|
|
1919
|
-
if (aIsId && !bIsId)
|
|
1920
|
-
return 1;
|
|
1921
|
-
if (bIsId && !aIsId)
|
|
1922
|
-
return -1;
|
|
1923
|
-
return 0;
|
|
1924
|
-
}));
|
|
1925
|
-
};
|
|
1926
940
|
/**
|
|
1927
941
|
* Return whether all columns have been selected (used to hide select all
|
|
1928
942
|
* and show clear button).
|
|
@@ -1946,497 +960,81 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
1946
960
|
},
|
|
1947
961
|
as: null,
|
|
1948
962
|
});
|
|
1949
|
-
const
|
|
1950
|
-
return ((0, jsx_runtime_1.jsxs)("div", { style: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [(0, jsx_runtime_1.jsx)("h1", { style: {
|
|
1951
|
-
fontWeight: '600',
|
|
1952
|
-
fontSize: 18,
|
|
1953
|
-
margin: 0,
|
|
1954
|
-
textAlign: 'left',
|
|
1955
|
-
}, children: "Add condition" }), (0, jsx_runtime_1.jsx)(TabsComponent, { value: topLevelBinaryOperator, options: UiComponents_1.DEFAULT_TAB_OPTIONS, onChange: (event) => setTopLevelBinaryOperator(event.target.value) }), activeEditItem && renderNode(activeEditItem), (0, jsx_runtime_1.jsx)("div", { style: {
|
|
1956
|
-
display: 'flex',
|
|
1957
|
-
flexDirection: 'row',
|
|
1958
|
-
gap: 8,
|
|
1959
|
-
justifyContent: 'end',
|
|
1960
|
-
}, children: (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: onSave, label: 'Add condition' }) })] }));
|
|
1961
|
-
};
|
|
1962
|
-
const fetchUponChange = async (baseAst, newFormData) => {
|
|
1963
|
-
// if newFormData is null still use it
|
|
963
|
+
const fetchReportFromASTHelper = async (baseAst, newFormData, curPivot, curSchema, previousReport) => {
|
|
1964
964
|
const curFormData = newFormData !== undefined ? newFormData : formData;
|
|
1965
|
-
let
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
clientId: client.publicKey,
|
|
1972
|
-
ast: { ...baseAst, where: curFormData },
|
|
1973
|
-
publicKey: client.publicKey,
|
|
1974
|
-
orgId: client.customerId,
|
|
1975
|
-
task: 'patterns',
|
|
1976
|
-
getCustomFields: false,
|
|
1977
|
-
customFields,
|
|
1978
|
-
additionalProcessing: { page: { currentPage: 0, rowsPerPage: 20 } },
|
|
1979
|
-
useUpdatedDataGathering: true,
|
|
1980
|
-
useNewNodeSql: true, // new flag
|
|
1981
|
-
},
|
|
1982
|
-
};
|
|
1983
|
-
const tables = (0, ast_1.getTableNames)(baseAst);
|
|
1984
|
-
const table = tables.length >= 1 ? tables[0] : initialTableName;
|
|
1985
|
-
let newUniqueValues = uniqueValues;
|
|
1986
|
-
let dateRangesTemp = dateRanges;
|
|
1987
|
-
let curReport = tempReport;
|
|
1988
|
-
if ((newUniqueValues && Object.keys(newUniqueValues).length === 0) ||
|
|
1989
|
-
table !== currentTable) {
|
|
1990
|
-
const tableInfo = schema.find((tableInfo) => tableInfo.name === table);
|
|
1991
|
-
if (tableInfo) {
|
|
1992
|
-
newUniqueValues = await getUniqueStringValues(tableInfo.columns, table);
|
|
1993
|
-
if ((0, crypto_1.hashCode)(uniqueValues) !== (0, crypto_1.hashCode)(newUniqueValues)) {
|
|
1994
|
-
setUniqueValues(newUniqueValues);
|
|
1995
|
-
}
|
|
1996
|
-
dateRangesTemp = await getDateRanges(tableInfo.columns, table);
|
|
1997
|
-
setDateRanges(dateRangesTemp || {});
|
|
1998
|
-
}
|
|
1999
|
-
setCurrentTable(table);
|
|
2000
|
-
}
|
|
2001
|
-
const cloudBody = {};
|
|
2002
|
-
const data2 = await (0, dataFetcher_1.getData)(client, 'dashquery', 'same-origin', hostedBody, cloudBody);
|
|
2003
|
-
if (data2.success === false) {
|
|
2004
|
-
throw new Error(data2.errorMessage);
|
|
2005
|
-
}
|
|
2006
|
-
if (client.databaseType &&
|
|
2007
|
-
client.databaseType.toLowerCase() === 'bigquery') {
|
|
2008
|
-
(0, dataProcessing_1.parseValueFromBigQueryDates)(data2.rows, columns);
|
|
2009
|
-
}
|
|
2010
|
-
rows = data2.rows;
|
|
2011
|
-
if (data2.rowCount) {
|
|
2012
|
-
setNumberOfRows(data2.rowCount);
|
|
2013
|
-
}
|
|
2014
|
-
if (data2.rows && data2.rows.length) {
|
|
2015
|
-
if (pivot) {
|
|
2016
|
-
// check if any of the pivot fields aren't in the data2.fields array
|
|
2017
|
-
if (!isValidPivot(data2.fields)) {
|
|
2018
|
-
const processedFields = data2.fields.map((elem) => (0, columnProcessing_1.convertPostgresColumn)(elem));
|
|
2019
|
-
setPivot(null);
|
|
2020
|
-
setPivotData(null);
|
|
2021
|
-
setRows(data2.rows);
|
|
2022
|
-
setColumns(processedFields);
|
|
2023
|
-
if (data2.rowCount) {
|
|
2024
|
-
const processedFormData = report
|
|
2025
|
-
? report
|
|
2026
|
-
: (0, ChartBuilder_1.createInitialFormData)(processedFields);
|
|
2027
|
-
setNumberOfRows(data2.rowCount);
|
|
2028
|
-
curReport = {
|
|
2029
|
-
...formData,
|
|
2030
|
-
...processedFormData,
|
|
2031
|
-
itemQuery: data2.itemQuery,
|
|
2032
|
-
rowCount: data2.rowCount,
|
|
2033
|
-
filtersApplied: [],
|
|
2034
|
-
rows: data2.rows,
|
|
2035
|
-
columns: processedFields,
|
|
2036
|
-
};
|
|
2037
|
-
setTempReport(curReport);
|
|
2038
|
-
}
|
|
2039
|
-
const formattedRows = formatRows(data2.rows, processedFields, false);
|
|
2040
|
-
setFormattedRows(formattedRows);
|
|
2041
|
-
return;
|
|
2042
|
-
}
|
|
2043
|
-
curReport = {
|
|
2044
|
-
...formData,
|
|
2045
|
-
itemQuery: data2.itemQuery,
|
|
2046
|
-
rowCount: data2.rowCount,
|
|
2047
|
-
filtersApplied: [],
|
|
2048
|
-
rows: data2.rows,
|
|
2049
|
-
};
|
|
2050
|
-
// Do all of this to make sure we have the right unique columns when applying a pivot
|
|
2051
|
-
let dateBucket = undefined;
|
|
2052
|
-
const tempDateRange = dateRangesTemp &&
|
|
2053
|
-
pivot.rowField &&
|
|
2054
|
-
dateRangesTemp[pivot.rowField];
|
|
2055
|
-
if (tempDateRange) {
|
|
2056
|
-
dateBucket = (0, dates_1.getDateBucketFromRange)(tempDateRange.dateRange);
|
|
2057
|
-
}
|
|
2058
|
-
let distinctValuesForQuery = {};
|
|
2059
|
-
if (pivot.columnField) {
|
|
2060
|
-
const sqlQuery = await fetchSqlQuery({ ...baseAst, where: curFormData }, null, false);
|
|
2061
|
-
distinctValuesForQuery = await (0, tableProcessing_1.getUniqueValuesByColumns)([
|
|
2062
|
-
{
|
|
2063
|
-
field: pivot.columnField,
|
|
2064
|
-
label: pivot.columnField,
|
|
2065
|
-
format: 'string',
|
|
2066
|
-
},
|
|
2067
|
-
], sqlQuery, [], client, customFields);
|
|
2068
|
-
}
|
|
2069
|
-
const pivotedData = await (0, PivotModal_1.generatePivotTable)(
|
|
2070
|
-
// @ts-ignore
|
|
2071
|
-
pivot, data2.rows, undefined, false, -1, undefined, dateBucket, curReport, client, distinctValuesForQuery ? distinctValuesForQuery : undefined);
|
|
2072
|
-
console.info(`%c[Pivot]: ${JSON.stringify(pivot)}`, 'color: dimgray');
|
|
2073
|
-
const processedFields = data2.fields.map((elem) => (0, columnProcessing_1.convertPostgresColumn)(elem));
|
|
2074
|
-
setPivotData(pivotedData);
|
|
2075
|
-
setRows(data2.rows);
|
|
2076
|
-
setColumns(processedFields);
|
|
2077
|
-
if (data2.rowCount) {
|
|
2078
|
-
const processedFormData = report
|
|
2079
|
-
? report
|
|
2080
|
-
: (0, ChartBuilder_1.createInitialFormData)(processedFields);
|
|
2081
|
-
setNumberOfRows(data2.rowCount);
|
|
2082
|
-
setTempReport({
|
|
2083
|
-
...formData,
|
|
2084
|
-
...processedFormData,
|
|
2085
|
-
itemQuery: data2.itemQuery,
|
|
2086
|
-
rowCount: data2.rowCount,
|
|
2087
|
-
filtersApplied: [],
|
|
2088
|
-
rows: data2.rows,
|
|
2089
|
-
columns: processedFields,
|
|
2090
|
-
});
|
|
2091
|
-
}
|
|
2092
|
-
const formattedRows = formatRows(pivotedData.rows, processedFields, true, pivot.aggregationType);
|
|
2093
|
-
setSelectedColumns(processedFields.map((column) => {
|
|
2094
|
-
return `${table}.${column.field}`;
|
|
2095
|
-
}));
|
|
2096
|
-
setFormattedRows(formattedRows);
|
|
2097
|
-
}
|
|
2098
|
-
else {
|
|
2099
|
-
const processedFields = data2.fields.map((elem) => (0, columnProcessing_1.convertPostgresColumn)(elem));
|
|
2100
|
-
setRows(data2.rows);
|
|
2101
|
-
setColumns(processedFields);
|
|
2102
|
-
if (data2.rowCount) {
|
|
2103
|
-
const processedFormData = report
|
|
2104
|
-
? report
|
|
2105
|
-
: (0, ChartBuilder_1.createInitialFormData)(processedFields);
|
|
2106
|
-
setNumberOfRows(data2.rowCount);
|
|
2107
|
-
setTempReport({
|
|
2108
|
-
...formData,
|
|
2109
|
-
...processedFormData,
|
|
2110
|
-
itemQuery: data2.itemQuery,
|
|
2111
|
-
rowCount: data2.rowCount,
|
|
2112
|
-
filtersApplied: [],
|
|
2113
|
-
rows: data2.rows,
|
|
2114
|
-
columns: processedFields,
|
|
2115
|
-
});
|
|
2116
|
-
}
|
|
2117
|
-
setSelectedColumns(processedFields.map((column) => {
|
|
2118
|
-
return `${table}.${column.field}`;
|
|
2119
|
-
}));
|
|
2120
|
-
const formattedRows = formatRows(data2.rows, processedFields, false);
|
|
2121
|
-
setFormattedRows(formattedRows);
|
|
2122
|
-
if (data2.errorMessage) {
|
|
2123
|
-
setErrorMessage(`Error: ${data2.errorMessage}`);
|
|
2124
|
-
}
|
|
2125
|
-
}
|
|
2126
|
-
}
|
|
2127
|
-
else {
|
|
2128
|
-
setRows([]);
|
|
2129
|
-
setColumns([]);
|
|
2130
|
-
setFormattedRows([]);
|
|
2131
|
-
setPivotData(null);
|
|
2132
|
-
}
|
|
2133
|
-
setLoading(false);
|
|
2134
|
-
setDataDisplayed(true);
|
|
2135
|
-
return rows;
|
|
965
|
+
let reportBuilderInfo = undefined;
|
|
966
|
+
try {
|
|
967
|
+
setLoading(true);
|
|
968
|
+
reportBuilderInfo = await (0, report_1.fetchReportBuilderDataFromAST)(baseAst, curFormData, curSchema ?? schema, client, curPivot ?? pivot, formData, currentTable, { uniqueStrings: uniqueValues, dateRanges: dateRanges ?? {} }, previousReport ?? reportInfo ?? undefined, customFields);
|
|
969
|
+
if (reportBuilderInfo.error) {
|
|
970
|
+
throw new Error(reportBuilderInfo.error);
|
|
2136
971
|
}
|
|
2137
|
-
|
|
2138
|
-
|
|
972
|
+
}
|
|
973
|
+
catch (err) {
|
|
974
|
+
if (err instanceof Error) {
|
|
975
|
+
setErrorMessage(err.message);
|
|
2139
976
|
setLoading(false);
|
|
2140
|
-
|
|
2141
|
-
setRows([]);
|
|
2142
|
-
setColumns([]);
|
|
2143
|
-
setFormattedRows([]);
|
|
2144
|
-
setPivotData(null);
|
|
2145
|
-
return { error: true, message: e.message };
|
|
977
|
+
return { error: true, message: err.message, rows: [] };
|
|
2146
978
|
}
|
|
979
|
+
setLoading(false);
|
|
980
|
+
setErrorMessage('Failed to fetch');
|
|
981
|
+
return { error: true, message: 'Failed to fetch', rows: [] };
|
|
2147
982
|
}
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
if (!node)
|
|
2152
|
-
return false;
|
|
2153
|
-
if (node.ast)
|
|
2154
|
-
return true;
|
|
2155
|
-
if (node.left && isSubquery(node.left))
|
|
2156
|
-
return true;
|
|
2157
|
-
if (node.right && isSubquery(node.right))
|
|
2158
|
-
return true;
|
|
2159
|
-
if (node.value && Array.isArray(node.value)) {
|
|
2160
|
-
for (const value of node.value) {
|
|
2161
|
-
if (isSubquery(value))
|
|
2162
|
-
return true;
|
|
2163
|
-
}
|
|
983
|
+
if (!reportBuilderInfo) {
|
|
984
|
+
setErrorMessage('Failed to fetch');
|
|
985
|
+
return;
|
|
2164
986
|
}
|
|
2165
|
-
|
|
987
|
+
const reportTable = reportBuilderInfo.table;
|
|
988
|
+
const reportBuilderInfoColumns = reportBuilderInfo.columns.map((column) => {
|
|
989
|
+
return `${reportTable}.${column.field}`;
|
|
990
|
+
});
|
|
991
|
+
setRows(reportBuilderInfo.rows);
|
|
992
|
+
setColumns(reportBuilderInfo.columns);
|
|
993
|
+
setNumberOfRows(reportBuilderInfo.rowCount);
|
|
994
|
+
setPivot(reportBuilderInfo.pivot);
|
|
995
|
+
setPivotData(reportBuilderInfo.pivotData);
|
|
996
|
+
setFormattedRows(reportBuilderInfo.formattedRows);
|
|
997
|
+
setTempReport(reportBuilderInfo.report);
|
|
998
|
+
setSelectedColumns(reportBuilderInfoColumns);
|
|
999
|
+
setActiveQuery(reportBuilderInfo.query);
|
|
1000
|
+
setUniqueValues(reportBuilderInfo.uniqueValues);
|
|
1001
|
+
setDateRanges(reportBuilderInfo.dateRanges);
|
|
1002
|
+
setLoading(false);
|
|
1003
|
+
setDataDisplayed(true);
|
|
1004
|
+
setCurrentTable(reportBuilderInfo.table);
|
|
1005
|
+
setFormData(curFormData);
|
|
1006
|
+
if (reportBuilderInfo.pivot) {
|
|
1007
|
+
setPivotRowField(reportBuilderInfo.pivot.rowField);
|
|
1008
|
+
setPivotAggregation(reportBuilderInfo.pivot.aggregationType);
|
|
1009
|
+
setPivotColumnField(reportBuilderInfo.pivot.columnField);
|
|
1010
|
+
setPivotValueField(reportBuilderInfo.pivot.valueField);
|
|
1011
|
+
}
|
|
1012
|
+
setReportInfo(reportBuilderInfo.report);
|
|
2166
1013
|
};
|
|
2167
|
-
const
|
|
2168
|
-
|
|
1014
|
+
const fetchAstFromPromptHelper = async (overridePrompt) => {
|
|
1015
|
+
let astInfo = {};
|
|
1016
|
+
const prompt = overridePrompt || aiPrompt;
|
|
1017
|
+
if (!prompt) {
|
|
1018
|
+
setErrorMessage('Please supply a prompt.');
|
|
2169
1019
|
return;
|
|
2170
1020
|
}
|
|
2171
1021
|
try {
|
|
2172
1022
|
setLoading(true);
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
let numRetries = 0;
|
|
2177
|
-
const MAX_RETRIES = 3;
|
|
2178
|
-
// refetch the request if it comes back and we know it's invalid.
|
|
2179
|
-
// TODO: remove this to allow joins later down the road
|
|
2180
|
-
let isTableJoin = !ast || !ast.from || ast.from.length !== 1;
|
|
2181
|
-
while (isTableJoin || isSubquery(ast?.where)) {
|
|
2182
|
-
if (numRetries === MAX_RETRIES)
|
|
2183
|
-
break;
|
|
2184
|
-
if (!activeQuery || (ast && (isTableJoin || isSubquery(ast?.where)))) {
|
|
2185
|
-
res = await fetch(`${exports.QUILL_SERVER}/magic`, {
|
|
2186
|
-
method: 'POST',
|
|
2187
|
-
headers: { 'Content-Type': 'application/json' },
|
|
2188
|
-
body: JSON.stringify({
|
|
2189
|
-
initialQuestion: aiPrompt || overridePrompt,
|
|
2190
|
-
publicKey: client.publicKey,
|
|
2191
|
-
useNewNodeSql: true, // new flag
|
|
2192
|
-
}),
|
|
2193
|
-
});
|
|
2194
|
-
}
|
|
2195
|
-
else {
|
|
2196
|
-
res = await fetch(`${exports.QUILL_SERVER}/magic/edit`, {
|
|
2197
|
-
method: 'POST',
|
|
2198
|
-
headers: { 'Content-Type': 'application/json' },
|
|
2199
|
-
body: JSON.stringify({
|
|
2200
|
-
sqlQuery: activeQuery,
|
|
2201
|
-
initialQuestion: aiPrompt,
|
|
2202
|
-
publicKey: client.publicKey,
|
|
2203
|
-
useNewNodeSql: true, // new flag
|
|
2204
|
-
}),
|
|
2205
|
-
});
|
|
2206
|
-
}
|
|
2207
|
-
data = await res.json();
|
|
2208
|
-
ast = data?.ast?.length ? data?.ast[0] : data?.ast;
|
|
2209
|
-
// TODO: Debug invalid table joins in handleAsk
|
|
2210
|
-
isTableJoin =
|
|
2211
|
-
ast?.type !== 'bigquery' &&
|
|
2212
|
-
(!ast || !ast.from || ast.from.length !== 1);
|
|
2213
|
-
numRetries += 1;
|
|
2214
|
-
}
|
|
2215
|
-
if (numRetries === MAX_RETRIES) {
|
|
2216
|
-
console.error('[Error]: Max retries exceeded.');
|
|
2217
|
-
console.info(`%c[Prompt]: ${aiPrompt}`, 'color: dimgray');
|
|
2218
|
-
setErrorMessage("Error: Couldn't process your request, please re-word your prompt.");
|
|
2219
|
-
return;
|
|
2220
|
-
}
|
|
2221
|
-
let currentSchema = schema;
|
|
2222
|
-
if (currentSchema && currentSchema.length === 0) {
|
|
2223
|
-
currentSchema = await fetchSchema();
|
|
2224
|
-
}
|
|
2225
|
-
let newAst, groupByPivot;
|
|
2226
|
-
if (ast) {
|
|
2227
|
-
// Unwrap the ast object, supporting many possible types
|
|
2228
|
-
ast = ast.length ? ast[0] : ast;
|
|
2229
|
-
newAst = (0, convert_1.convertBigQuery)(ast);
|
|
2230
|
-
newAst = (0, convert_1.convertWildcardColumns)(newAst, currentSchema); // must go before groupby
|
|
2231
|
-
({ ast: newAst, pivot: groupByPivot } = (0, convert_1.convertGroupBy)(newAst, pivot, currentSchema));
|
|
2232
|
-
newAst = (0, convert_1.convertStringComparison)(newAst, client.databaseType);
|
|
2233
|
-
newAst = (0, convert_1.convertRemoveSimpleParentheses)(newAst);
|
|
2234
|
-
const table = (0, ast_1.getTableNames)(newAst)[0] ?? initialTableName;
|
|
2235
|
-
const tableAlias = (0, ast_1.getTableAliases)(newAst)[0] ?? initialTableName;
|
|
2236
|
-
newAst = (0, convert_1.convertUnaryToBinary)(newAst);
|
|
2237
|
-
newAst = (0, util_1.removeNonSelectedTableReferences)(newAst, tableAlias ?? table, getAllPossibleColumns().map((col) => col.name));
|
|
2238
|
-
const procesedColumns = (0, util_1.deepCopy)(newAst).columns?.map((column) => {
|
|
2239
|
-
if (column.expr.type === 'column_ref') {
|
|
2240
|
-
const columnName = (0, ast_1.extractColumnish)(column.expr);
|
|
2241
|
-
return `${table}.${columnName}`;
|
|
2242
|
-
}
|
|
2243
|
-
else if (column.as) {
|
|
2244
|
-
return `${table}.${column.as}`;
|
|
2245
|
-
}
|
|
2246
|
-
return `${table}.${column.expr.value}`;
|
|
2247
|
-
});
|
|
2248
|
-
setSelectedColumns(procesedColumns);
|
|
2249
|
-
if (groupByPivot) {
|
|
2250
|
-
setBaseAst((0, util_1.deepCopy)({ ...newAst, orderby: null, limit: null }));
|
|
2251
|
-
newAst = (0, util_1.deepCopy)({ ...newAst, orderby: null, limit: null });
|
|
2252
|
-
}
|
|
2253
|
-
else {
|
|
2254
|
-
setBaseAst((0, util_1.deepCopy)({ ...newAst }));
|
|
2255
|
-
}
|
|
2256
|
-
setFormData((0, util_1.deepCopy)(newAst.where));
|
|
2257
|
-
setTopLevelBinaryOperator(
|
|
2258
|
-
// @ts-ignore
|
|
2259
|
-
newAst?.where ? newAst?.where?.operator : 'AND');
|
|
2260
|
-
}
|
|
2261
|
-
ast = newAst; // so we fetch data for newAst later.
|
|
2262
|
-
fetchSqlQuery(ast, undefined, false);
|
|
2263
|
-
const table = (0, ast_1.getTableNames)(newAst)[0] ?? initialTableName;
|
|
2264
|
-
const hostedBody = {
|
|
2265
|
-
metadata: {
|
|
2266
|
-
clientId: client.publicKey,
|
|
2267
|
-
ast,
|
|
2268
|
-
publicKey: client.publicKey,
|
|
2269
|
-
orgId: client.customerId,
|
|
2270
|
-
task: 'patterns',
|
|
2271
|
-
additionalProcessing: { page: { currentPage: 0, rowsPerPage: 20 } },
|
|
2272
|
-
useUpdatedDataGathering: true,
|
|
2273
|
-
pivot: groupByPivot,
|
|
2274
|
-
useNewNodeSql: true, // new flag
|
|
2275
|
-
},
|
|
2276
|
-
};
|
|
2277
|
-
let currentUniqueValues = uniqueValues;
|
|
2278
|
-
let dateRangesTemp = dateRanges;
|
|
2279
|
-
if ((currentUniqueValues &&
|
|
2280
|
-
currentUniqueValues[table] &&
|
|
2281
|
-
Object.keys(currentUniqueValues[table]).length === 0) ||
|
|
2282
|
-
table !== currentTable) {
|
|
2283
|
-
const tableInfo = currentSchema.find((tableInfo) => tableInfo.name === table);
|
|
2284
|
-
if (tableInfo) {
|
|
2285
|
-
const newUniqueValues = await getUniqueStringValues(tableInfo.columns, table);
|
|
2286
|
-
currentUniqueValues = newUniqueValues;
|
|
2287
|
-
if ((0, crypto_1.hashCode)(uniqueValues) !== (0, crypto_1.hashCode)(newUniqueValues)) {
|
|
2288
|
-
setUniqueValues(newUniqueValues);
|
|
2289
|
-
}
|
|
2290
|
-
dateRangesTemp = await getDateRanges(tableInfo.columns, table);
|
|
2291
|
-
setDateRanges(dateRangesTemp);
|
|
2292
|
-
}
|
|
2293
|
-
setCurrentTable(table);
|
|
2294
|
-
}
|
|
2295
|
-
const cloudBody = {};
|
|
2296
|
-
const data2 = await (0, dataFetcher_1.getData)(client, 'patterns', 'same-origin', hostedBody, cloudBody);
|
|
2297
|
-
if (!data2 || data2.status === 'error') {
|
|
2298
|
-
throw new Error('Error querying data from patterns');
|
|
2299
|
-
}
|
|
2300
|
-
if (data2.rows && data2.rows.length) {
|
|
2301
|
-
const processedFields = data2.fields
|
|
2302
|
-
.map((elem) => (0, columnProcessing_1.convertPostgresColumn)(elem))
|
|
2303
|
-
.map((elem) => {
|
|
2304
|
-
const tableInfo = currentSchema.find((t) => t.name === table);
|
|
2305
|
-
const columnInfo = tableInfo?.columns.find((column) => column.name === elem.field);
|
|
2306
|
-
return columnInfo
|
|
2307
|
-
? (0, columnProcessing_1.convertColumnInfoToColumnInternal)(columnInfo)
|
|
2308
|
-
: null;
|
|
2309
|
-
})
|
|
2310
|
-
.filter((elem) => elem);
|
|
2311
|
-
let possiblePivot = true;
|
|
2312
|
-
const possibleColumns = (0, pivotProcessing_1.getPossiblePivotFieldOptions)(processedFields, currentUniqueValues[table]);
|
|
2313
|
-
if (groupByPivot &&
|
|
2314
|
-
((groupByPivot.columnField &&
|
|
2315
|
-
!possibleColumns.columnFields.includes(groupByPivot?.columnField)) ||
|
|
2316
|
-
(groupByPivot.rowField &&
|
|
2317
|
-
!possibleColumns.rowFields.includes(groupByPivot?.rowField)) ||
|
|
2318
|
-
(groupByPivot.valueField &&
|
|
2319
|
-
!possibleColumns.valueFields.includes(groupByPivot?.valueField || '')))) {
|
|
2320
|
-
possiblePivot = false;
|
|
2321
|
-
let errorMessageEnding = '';
|
|
2322
|
-
if (groupByPivot.columnField &&
|
|
2323
|
-
!possibleColumns.columnFields.includes(groupByPivot?.columnField || '')) {
|
|
2324
|
-
if (currentUniqueValues[table]?.[groupByPivot?.columnField || '']) {
|
|
2325
|
-
errorMessageEnding = `The column ${groupByPivot?.columnField} has more than 24 unique values to pivot on.`;
|
|
2326
|
-
}
|
|
2327
|
-
else {
|
|
2328
|
-
errorMessageEnding = `The column ${groupByPivot?.columnField} is not a proper column field.`;
|
|
2329
|
-
}
|
|
2330
|
-
}
|
|
2331
|
-
else if (groupByPivot.rowField &&
|
|
2332
|
-
!possibleColumns.rowFields.includes(groupByPivot?.rowField || '')) {
|
|
2333
|
-
if (currentUniqueValues[table]?.[groupByPivot?.rowField || '']) {
|
|
2334
|
-
errorMessageEnding = `The column ${groupByPivot?.rowField} has more than 36 unique values to pivot on.`;
|
|
2335
|
-
}
|
|
2336
|
-
else {
|
|
2337
|
-
errorMessageEnding = `The column ${groupByPivot?.rowField} is not a proper row field.`;
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
else if (groupByPivot.valueField &&
|
|
2341
|
-
!possibleColumns.valueFields.includes(groupByPivot?.valueField || '')) {
|
|
2342
|
-
errorMessageEnding = `The column ${groupByPivot?.valueField} is not a proper value field.`;
|
|
2343
|
-
}
|
|
2344
|
-
setErrorMessage(`The requested pivot is not supported. ${errorMessageEnding}`);
|
|
2345
|
-
}
|
|
2346
|
-
if (groupByPivot && possiblePivot) {
|
|
2347
|
-
let curReport = report ? report : undefined;
|
|
2348
|
-
if (data2.rowCount) {
|
|
2349
|
-
const processedFormData = report
|
|
2350
|
-
? report
|
|
2351
|
-
: (0, ChartBuilder_1.createInitialFormData)(processedFields);
|
|
2352
|
-
setNumberOfRows(data2.rowCount);
|
|
2353
|
-
curReport = {
|
|
2354
|
-
...formData,
|
|
2355
|
-
...processedFormData,
|
|
2356
|
-
itemQuery: data2.itemQuery,
|
|
2357
|
-
rowCount: data2.rowCount,
|
|
2358
|
-
filtersApplied: [],
|
|
2359
|
-
rows: data2.rows,
|
|
2360
|
-
columns: processedFields,
|
|
2361
|
-
};
|
|
2362
|
-
setTempReport(curReport || null);
|
|
2363
|
-
}
|
|
2364
|
-
let dateBucket = undefined;
|
|
2365
|
-
const tempDateRange = dateRangesTemp &&
|
|
2366
|
-
groupByPivot.rowField &&
|
|
2367
|
-
dateRangesTemp[groupByPivot.rowField];
|
|
2368
|
-
if (tempDateRange) {
|
|
2369
|
-
dateBucket = (0, dates_1.getDateBucketFromRange)(tempDateRange.dateRange);
|
|
2370
|
-
}
|
|
2371
|
-
const pivotedData = await (0, PivotModal_1.generatePivotTable)(
|
|
2372
|
-
// @ts-ignore
|
|
2373
|
-
groupByPivot, data2.rows, undefined, false, -1, undefined, dateBucket, curReport, client, groupByPivot.columnField
|
|
2374
|
-
? currentUniqueValues[groupByPivot.columnField]
|
|
2375
|
-
: undefined);
|
|
2376
|
-
console.info(`%c[Pivot]: ${JSON.stringify(groupByPivot)}`, 'color: dimgray');
|
|
2377
|
-
setPivotData(pivotedData);
|
|
2378
|
-
setPivot(groupByPivot);
|
|
2379
|
-
if (client.databaseType &&
|
|
2380
|
-
client.databaseType.toLowerCase() === 'bigquery') {
|
|
2381
|
-
(0, dataProcessing_1.parseValueFromBigQueryDates)(data2.rows, processedFields);
|
|
2382
|
-
}
|
|
2383
|
-
setRows(data2.rows);
|
|
2384
|
-
setPivotRowField(groupByPivot?.rowField);
|
|
2385
|
-
setPivotColumnField(groupByPivot?.columnField);
|
|
2386
|
-
setPivotValueField(groupByPivot?.valueField);
|
|
2387
|
-
setPivotAggregation(groupByPivot?.aggregationType);
|
|
2388
|
-
setColumns(processedFields);
|
|
2389
|
-
const formattedRows = formatRows(pivotedData.rows, processedFields, true, groupByPivot.aggregationType);
|
|
2390
|
-
setFormattedRows(formattedRows);
|
|
2391
|
-
}
|
|
2392
|
-
else {
|
|
2393
|
-
const processedFields = data2.fields.map((elem) => (0, columnProcessing_1.convertPostgresColumn)(elem));
|
|
2394
|
-
if (client.databaseType &&
|
|
2395
|
-
client.databaseType.toLowerCase() === 'bigquery') {
|
|
2396
|
-
(0, dataProcessing_1.parseValueFromBigQueryDates)(data2.rows, processedFields);
|
|
2397
|
-
}
|
|
2398
|
-
setRows(data2.rows);
|
|
2399
|
-
setColumns(processedFields);
|
|
2400
|
-
if (data2.rowCount) {
|
|
2401
|
-
setNumberOfRows(data2.rowCount);
|
|
2402
|
-
setTempReport({
|
|
2403
|
-
...formData,
|
|
2404
|
-
itemQuery: data2.itemQuery,
|
|
2405
|
-
rowCount: data2.rowCount,
|
|
2406
|
-
filtersApplied: [],
|
|
2407
|
-
rows: data2.rows,
|
|
2408
|
-
columns: processedFields,
|
|
2409
|
-
});
|
|
2410
|
-
}
|
|
2411
|
-
const formattedRows = formatRows(data2.rows, processedFields, false);
|
|
2412
|
-
setFormattedRows(formattedRows);
|
|
2413
|
-
}
|
|
2414
|
-
return data2.rows;
|
|
1023
|
+
astInfo = await (0, astProcessing_1.fetchAndProcessASTFromPrompt)(prompt, schema, client, pivot, activeQuery);
|
|
1024
|
+
if (astInfo.error) {
|
|
1025
|
+
throw new Error(astInfo.error);
|
|
2415
1026
|
}
|
|
2416
|
-
else {
|
|
2417
|
-
setPivotData([]);
|
|
2418
|
-
setRows([]);
|
|
2419
|
-
setColumns([]);
|
|
2420
|
-
setFormattedRows([]);
|
|
2421
|
-
}
|
|
2422
|
-
if (data2.query) {
|
|
2423
|
-
setActiveQuery(data2.query);
|
|
2424
|
-
}
|
|
2425
|
-
else {
|
|
2426
|
-
setActiveQuery('');
|
|
2427
|
-
}
|
|
2428
|
-
if (data2.errorMessage) {
|
|
2429
|
-
setErrorMessage(`Error: Couldn't process your request, please re-word your prompt.`);
|
|
2430
|
-
}
|
|
2431
|
-
}
|
|
2432
|
-
catch (e) {
|
|
2433
|
-
console.error(e);
|
|
2434
|
-
setErrorMessage(`Error: Couldn't process your request, please re-word your prompt.`);
|
|
2435
1027
|
}
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
1028
|
+
catch (err) {
|
|
1029
|
+
if (err instanceof Error) {
|
|
1030
|
+
setErrorMessage(err.message);
|
|
1031
|
+
setLoading(false);
|
|
1032
|
+
}
|
|
1033
|
+
return;
|
|
2439
1034
|
}
|
|
1035
|
+
setBaseAst(astInfo.ast);
|
|
1036
|
+
setFormData(astInfo.whereAst);
|
|
1037
|
+
await fetchReportFromASTHelper(astInfo.ast, astInfo.whereAST, astInfo.pivot);
|
|
2440
1038
|
};
|
|
2441
1039
|
const handleDeleteColumn = (name) => {
|
|
2442
1040
|
if (!baseAst || !baseAst.columns.length || selectedColumns.length === 1) {
|
|
@@ -2628,46 +1226,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
2628
1226
|
setIsPending(false);
|
|
2629
1227
|
const item = (0, astFilterProcessing_1.filterToAst)(filter, client.databaseType.toLowerCase());
|
|
2630
1228
|
handleInsertion(item, 'AND', false);
|
|
2631
|
-
}, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, SecondaryButtonComponent: SecondaryButtonComponent, MultiSelectComponent: MultiSelectComponent }) }) }),
|
|
2632
|
-
false && ( // temp removed the AddConditionPopover
|
|
2633
|
-
(0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { onClick: () => {
|
|
2634
|
-
if (!openPopover) {
|
|
2635
|
-
setActiveEditItem((0, util_1.deepCopy)(constants_1.defaultEntry));
|
|
2636
|
-
setOpenPopover('AddConditionPopover');
|
|
2637
|
-
setActivePath('');
|
|
2638
|
-
setIsPending(true);
|
|
2639
|
-
}
|
|
2640
|
-
}, label: "Add condition" }), (0, jsx_runtime_1.jsx)(PopoverComponent, { isOpen: openPopover === 'AddConditionPopover', setIsOpen: (isOpen) => {
|
|
2641
|
-
if (!isOpen) {
|
|
2642
|
-
setIsPending(false);
|
|
2643
|
-
setTimeout(() => {
|
|
2644
|
-
clearCheckboxes();
|
|
2645
|
-
setActiveEditItem(null);
|
|
2646
|
-
}, 300);
|
|
2647
|
-
setActivePath(null);
|
|
2648
|
-
setOpenPopover(null);
|
|
2649
|
-
}
|
|
2650
|
-
}, popoverTitle: "Add condition", popoverChildren: (0, jsx_runtime_1.jsx)(AddConditionPopover, { onSave: () => {
|
|
2651
|
-
if ((0, util_1.isNodeEmptyCollection)(activeEditItem)) {
|
|
2652
|
-
setIsPending(false);
|
|
2653
|
-
setTimeout(() => {
|
|
2654
|
-
setActiveEditItem(null);
|
|
2655
|
-
clearCheckboxes();
|
|
2656
|
-
}, 300);
|
|
2657
|
-
setActivePath(null);
|
|
2658
|
-
setOpenPopover(null);
|
|
2659
|
-
}
|
|
2660
|
-
else {
|
|
2661
|
-
setIsPending(false);
|
|
2662
|
-
handleInsertion(activeEditItem, topLevelBinaryOperator, true);
|
|
2663
|
-
setTimeout(() => {
|
|
2664
|
-
setActiveEditItem(null);
|
|
2665
|
-
clearCheckboxes();
|
|
2666
|
-
}, 300);
|
|
2667
|
-
setActivePath(null);
|
|
2668
|
-
setOpenPopover(null);
|
|
2669
|
-
}
|
|
2670
|
-
} }) })] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { style: { width: '100%' }, children: [(0, jsx_runtime_1.jsx)(SidebarHeadingComponent, { label: "Pivot" }), (0, jsx_runtime_1.jsx)(PivotModal_1.PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, CardComponent: CardComponent, SelectComponent: SelectComponent, ButtonComponent: ButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, LoadingComponent: LoadingComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEditingPivot, setShowUpdatePivot: setIsEditingPivot, parentRef: parentRef, data: rows, columns: columns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
|
|
1229
|
+
}, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, SecondaryButtonComponent: SecondaryButtonComponent, MultiSelectComponent: MultiSelectComponent }) }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: { width: '100%' }, children: [(0, jsx_runtime_1.jsx)(SidebarHeadingComponent, { label: "Pivot" }), (0, jsx_runtime_1.jsx)(PivotModal_1.PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, CardComponent: CardComponent, SelectComponent: SelectComponent, ButtonComponent: ButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, LoadingComponent: LoadingComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEditingPivot, setShowUpdatePivot: setIsEditingPivot, parentRef: parentRef, data: rows, columns: columns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
|
|
2671
1230
|
setPivot(null);
|
|
2672
1231
|
setPivotData(null);
|
|
2673
1232
|
const formattedRows = formatRows(rows, columns, false);
|
|
@@ -2676,7 +1235,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
2676
1235
|
// TODOs
|
|
2677
1236
|
selectPivot: () => {
|
|
2678
1237
|
return;
|
|
2679
|
-
}, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: LabelComponent, HeaderComponent: HeaderComponent, dateRange: undefined, pivotCountRequest: 4, SecondaryButtonComponent: SecondaryButtonComponent, query: activeQuery, initialUniqueValues: uniqueValues[currentTable], disabled: !loading && (!baseAst || !dataDisplayed), pivotRecommendationsEnabled: pivotRecommendationsEnabled && overrideRecommendations, report: tempReport ??
|
|
1238
|
+
}, selectPivotOnEdit: true, showTrigger: !pivot, theme: theme, LabelComponent: LabelComponent, HeaderComponent: HeaderComponent, dateRange: undefined, pivotCountRequest: 4, SecondaryButtonComponent: SecondaryButtonComponent, query: activeQuery, initialUniqueValues: uniqueValues[currentTable], disabled: !loading && (!baseAst || !dataDisplayed), pivotRecommendationsEnabled: pivotRecommendationsEnabled && overrideRecommendations, report: tempReport ?? reportInfo }), pivot && ((0, jsx_runtime_1.jsx)(PivotForm_1.default, { columns: columns, uniqueValues: uniqueValues[currentTable], setPivotRowField: (value) => {
|
|
2680
1239
|
setPivotRowField(value);
|
|
2681
1240
|
}, setPivotColumnField: setPivotColumnField, setPivotValueField: setPivotValueField, setPivotAggregation: setPivotAggregation, pivotRowField: pivotRowField, pivotColumnField: pivotColumnField, pivotValueField: pivotValueField, pivotAggregation: pivotAggregation, onDelete: () => {
|
|
2682
1241
|
setPivot(null);
|
|
@@ -2822,7 +1381,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
2822
1381
|
display: 'flex',
|
|
2823
1382
|
flexDirection: 'row',
|
|
2824
1383
|
gap: '12px',
|
|
2825
|
-
}, children: [(0, jsx_runtime_1.jsx)("div", { style: { width: '100%' } }), !hideCopySQL && ((0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { onClick: () => copySQLToClipboard(), label: isCopying ? '✅ Copied' : 'Copy SQL' })), (0, jsx_runtime_1.jsx)(ButtonComponent, { label:
|
|
1384
|
+
}, children: [(0, jsx_runtime_1.jsx)("div", { style: { width: '100%' } }), !hideCopySQL && ((0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { onClick: () => copySQLToClipboard(), label: isCopying ? '✅ Copied' : 'Copy SQL' })), (0, jsx_runtime_1.jsx)(ButtonComponent, { label: reportInfo ? 'Save changes' : 'Add to dashboard', onClick: () => { } })] }))] })] }), (0, jsx_runtime_1.jsx)("style", { children: `body{margin:0;}` })] }));
|
|
2826
1385
|
}
|
|
2827
1386
|
return ((0, jsx_runtime_1.jsxs)("div", { style: { backgroundColor: theme.backgroundColor, ...containerStyle }, className: className, children: [(!isChartBuilderHorizontalView ||
|
|
2828
1387
|
(isChartBuilderHorizontalView && !isChartBuilderOpen)) && ((0, jsx_runtime_1.jsxs)("div", { ref: parentRef, style: {
|
|
@@ -2909,47 +1468,7 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
2909
1468
|
setIsPending(false);
|
|
2910
1469
|
const item = (0, astFilterProcessing_1.filterToAst)(filter, client.databaseType.toLowerCase());
|
|
2911
1470
|
handleInsertion(item, 'AND', false);
|
|
2912
|
-
}, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, MultiSelectComponent: MultiSelectComponent }) }) }),
|
|
2913
|
-
false && ( // temp removed the AddConditionPopover
|
|
2914
|
-
(0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { onClick: () => {
|
|
2915
|
-
if (!openPopover) {
|
|
2916
|
-
setActiveEditItem((0, util_1.deepCopy)(constants_1.defaultEntry));
|
|
2917
|
-
setOpenPopover('AddConditionPopover');
|
|
2918
|
-
setActivePath('');
|
|
2919
|
-
setIsPending(true);
|
|
2920
|
-
}
|
|
2921
|
-
}, label: 'Add condition' }), (0, jsx_runtime_1.jsx)(PopoverComponent, { isOpen: openPopover === 'AddConditionPopover', setIsOpen: (isOpen) => {
|
|
2922
|
-
if (!isOpen) {
|
|
2923
|
-
// delay onClose callback so onClick no-ops
|
|
2924
|
-
setTimeout(() => {
|
|
2925
|
-
setIsPending(false);
|
|
2926
|
-
setActiveEditItem(null);
|
|
2927
|
-
setActivePath(null);
|
|
2928
|
-
setOpenPopover(null);
|
|
2929
|
-
clearCheckboxes();
|
|
2930
|
-
}, 200);
|
|
2931
|
-
}
|
|
2932
|
-
}, popoverChildren: (0, jsx_runtime_1.jsx)(AddConditionPopover, { onSave: () => {
|
|
2933
|
-
if ((0, util_1.isNodeEmptyCollection)(activeEditItem)) {
|
|
2934
|
-
setIsPending(false);
|
|
2935
|
-
setTimeout(() => {
|
|
2936
|
-
setActiveEditItem(null);
|
|
2937
|
-
}, 300);
|
|
2938
|
-
setActivePath(null);
|
|
2939
|
-
setOpenPopover(null);
|
|
2940
|
-
clearCheckboxes();
|
|
2941
|
-
}
|
|
2942
|
-
else {
|
|
2943
|
-
setIsPending(false);
|
|
2944
|
-
handleInsertion(activeEditItem, topLevelBinaryOperator, true);
|
|
2945
|
-
setTimeout(() => {
|
|
2946
|
-
setActiveEditItem(null);
|
|
2947
|
-
}, 300);
|
|
2948
|
-
setActivePath(null);
|
|
2949
|
-
setOpenPopover(null);
|
|
2950
|
-
clearCheckboxes();
|
|
2951
|
-
}
|
|
2952
|
-
} }) })] }))] })] }), (0, jsx_runtime_1.jsxs)("div", { style: { width: '100%' }, children: [(0, jsx_runtime_1.jsx)(SidebarHeadingComponent, { label: "Pivot" }), (0, jsx_runtime_1.jsx)(PivotModal_1.PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, SelectComponent: SelectComponent, ButtonComponent: ButtonComponent, CardComponent: CardComponent, SecondaryButtonComponent: SecondaryButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, LoadingComponent: LoadingComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEditingPivot, setShowUpdatePivot: setIsEditingPivot, parentRef: parentRef, data: rows, columns: columns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
|
|
1471
|
+
}, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, MultiSelectComponent: MultiSelectComponent }) }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { style: { width: '100%' }, children: [(0, jsx_runtime_1.jsx)(SidebarHeadingComponent, { label: "Pivot" }), (0, jsx_runtime_1.jsx)(PivotModal_1.PivotModal, { pivotRowField: pivotRowField, setPivotRowField: setPivotRowField, pivotColumnField: pivotColumnField, setPivotColumnField: setPivotColumnField, pivotValueField: pivotValueField, setPivotValueField: setPivotValueField, pivotAggregation: pivotAggregation, setPivotAggregation: setPivotAggregation, createdPivots: createdPivots, setCreatedPivots: setCreatedPivots, recommendedPivots: recommendedPivots, setRecommendedPivots: setRecommendedPivots, popUpTitle: pivotPopUpTitle, setPopUpTitle: setPivotPopUpTitle, selectedTable: initialTableName, SelectComponent: SelectComponent, ButtonComponent: ButtonComponent, CardComponent: CardComponent, SecondaryButtonComponent: SecondaryButtonComponent, PopoverComponent: PopoverComponent, TextComponent: TextComponent, ErrorMessageComponent: ErrorMessageComponent, PivotRowContainer: PivotRowContainer, PivotColumnContainer: PivotColumnContainer, LoadingComponent: LoadingComponent, isOpen: showPivotPopover, setIsOpen: setShowPivotPopover, showUpdatePivot: isEditingPivot, setShowUpdatePivot: setIsEditingPivot, parentRef: parentRef, data: rows, columns: columns, triggerButtonText: 'Add pivot', selectedPivotIndex: selectedPivotIndex, setSelectedPivotIndex: setSelectedPivotIndex, removePivot: () => {
|
|
2953
1472
|
setPivot(null);
|
|
2954
1473
|
setPivotData(null);
|
|
2955
1474
|
const formattedRows = formatRows(rows, columns, false);
|
|
@@ -3244,7 +1763,9 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
3244
1763
|
? askAIInputWidth
|
|
3245
1764
|
: askAILoadingContainerWidth, onChange: (e) => setAiPrompt(e.target.value), placeholder: askedAQuestion
|
|
3246
1765
|
? 'Ask a follow-up question...'
|
|
3247
|
-
: 'Ask a question...' }), (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick:
|
|
1766
|
+
: 'Ask a question...' }), (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: () => {
|
|
1767
|
+
fetchAstFromPromptHelper();
|
|
1768
|
+
}, label: 'Ask AI' }), ((baseAst && dataDisplayed) || initialLoad) && ((0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: 'New report', onClick: clearAllState }))] }) })), baseAst && ((0, jsx_runtime_1.jsx)(TableComponent, { isLoading: tableLoading ||
|
|
3248
1769
|
(loading && errorMessage.length === 0) ||
|
|
3249
1770
|
initialChartLoad, rows: formattedRows, rowCount: pivot ? undefined : numberOfRows, columns: pivot
|
|
3250
1771
|
? pivotData?.columns || emptyPivotColumns()
|
|
@@ -3265,15 +1786,17 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
3265
1786
|
width: '100%',
|
|
3266
1787
|
gap: 12,
|
|
3267
1788
|
alignItems: 'center',
|
|
3268
|
-
}, children: [(0, jsx_runtime_1.jsx)(ErrorMessageComponent, { errorMessage: errorMessage }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { onClick:
|
|
1789
|
+
}, children: [(0, jsx_runtime_1.jsx)(ErrorMessageComponent, { errorMessage: errorMessage }), (0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { onClick: () => {
|
|
1790
|
+
fetchAstFromPromptHelper();
|
|
1791
|
+
}, label: 'Retry' })] })) : ((0, jsx_runtime_1.jsx)("div", { style: { width: '100%' } })), baseAst && dataDisplayed && !initialChartLoad && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [!hideCopySQL && ((0, jsx_runtime_1.jsx)(SecondaryButtonComponent, { label: isCopying ? '✅ Copied' : 'Copy SQL', onClick: () => copySQLToClipboard() })), (0, jsx_runtime_1.jsx)(ButtonComponent, { onClick: () => {
|
|
3269
1792
|
setIsChartBuilderOpen(true);
|
|
3270
|
-
}, disabled: !!errorMessage, label:
|
|
1793
|
+
}, disabled: !!errorMessage, label: reportInfo ? 'Save changes' : 'Add to dashboard' })] }))] })] }), (0, jsx_runtime_1.jsx)("style", { children: `body{margin:0;}` })] })), (!isChartBuilderHorizontalView || isChartBuilderOpen) && ((0, jsx_runtime_1.jsx)(ChartBuilder_1.ChartBuilderWithModal, { hideDeleteButton: true, report: reportInfo
|
|
3271
1794
|
? {
|
|
3272
|
-
...
|
|
1795
|
+
...reportInfo,
|
|
3273
1796
|
...tempReport,
|
|
3274
1797
|
pivot: pivot,
|
|
3275
|
-
yAxisFields:
|
|
3276
|
-
columns:
|
|
1798
|
+
yAxisFields: reportInfo.pivot && !pivot ? [] : reportInfo.yAxisFields,
|
|
1799
|
+
columns: reportInfo.columns.filter((col) => {
|
|
3277
1800
|
return columns.find((c) => {
|
|
3278
1801
|
return col.field === c.field;
|
|
3279
1802
|
});
|
|
@@ -3281,6 +1804,6 @@ function ReportBuilder({ initialTableName = '', onSubmitEditReport = () => void
|
|
|
3281
1804
|
queryString: activeQuery,
|
|
3282
1805
|
rows: rows,
|
|
3283
1806
|
}
|
|
3284
|
-
: tempReport, rows: rows, columns: columns, pivot: pivot, query: activeQuery, showTableFormatOptions: showChartBuilderTableFormatOptions, showDateFieldOptions: isAdminEnabled, showAccessControlOptions: isAdminEnabled, title:
|
|
1807
|
+
: tempReport, rows: rows, columns: columns, pivot: pivot, query: activeQuery, showTableFormatOptions: showChartBuilderTableFormatOptions, showDateFieldOptions: isAdminEnabled, showAccessControlOptions: isAdminEnabled, title: reportInfo ? 'Save changes' : 'Add to dashboard', isHorizontalView: true, isOpen: isChartBuilderOpen, setIsOpen: setIsChartBuilderOpen, onAddToDashboardComplete: reportInfo ? onSubmitEditReport : onSubmitCreateReport, destinationDashboard: destinationDashboard, organizationName: organizationName, pivotData: pivotData, initialUniqueValues: uniqueValues[currentTable], pivotRecommendationsEnabled: pivotRecommendationsEnabled && overrideRecommendations, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, HeaderComponent: HeaderComponent, SubHeaderComponent: SubHeaderComponent, LabelComponent: LabelComponent, TextComponent: TextComponent, CardComponent: CardComponent, ModalComponent: ChartBuilderModalComponent, PopoverComponent: PopoverComponent, TableComponent: TableComponent, DeleteButtonComponent: DeleteButtonComponent, LoadingComponent: LoadingComponent, ChartBuilderInputRowContainer: ChartBuilderInputRowContainer, ChartBuilderInputColumnContainer: ChartBuilderInputColumnContainer, FormContainer: ChartBuilderFormContainer, hideDateRangeFilter: true, buttonLabel: reportInfo ? 'Save changes' : 'Add to dashboard', onClickChartElement: onClickChartElement, rowCount: numberOfRows, onPageChange: onPageChange, onSortChange: onSortChange, isLoading: tableLoading }))] }));
|
|
3285
1808
|
}
|
|
3286
1809
|
exports.default = ReportBuilder;
|