@quillsql/react 2.12.26 → 2.12.28
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.d.ts +17 -2
- package/dist/cjs/Chart.d.ts.map +1 -1
- package/dist/cjs/Chart.js +137 -90
- package/dist/cjs/ChartBuilder.d.ts +3 -3
- package/dist/cjs/ChartBuilder.d.ts.map +1 -1
- package/dist/cjs/ChartBuilder.js +30 -23
- package/dist/cjs/ChartEditor.d.ts.map +1 -1
- package/dist/cjs/ChartEditor.js +66 -26
- package/dist/cjs/Context.d.ts +1 -0
- package/dist/cjs/Context.d.ts.map +1 -1
- package/dist/cjs/Context.js +17 -2
- package/dist/cjs/Dashboard.d.ts +6 -1
- package/dist/cjs/Dashboard.d.ts.map +1 -1
- package/dist/cjs/Dashboard.js +3 -1
- package/dist/cjs/ReportBuilder.d.ts +1 -1
- package/dist/cjs/ReportBuilder.d.ts.map +1 -1
- package/dist/cjs/ReportBuilder.js +12 -10
- package/dist/cjs/SQLEditor.d.ts +10 -1
- package/dist/cjs/SQLEditor.d.ts.map +1 -1
- package/dist/cjs/SQLEditor.js +27 -3
- package/dist/cjs/Table.d.ts +15 -1
- package/dist/cjs/Table.d.ts.map +1 -1
- package/dist/cjs/Table.js +143 -59
- package/dist/cjs/components/Chart/ChartTooltip.d.ts.map +1 -1
- package/dist/cjs/components/Chart/ChartTooltip.js +5 -4
- package/dist/cjs/components/Dashboard/DashboardFilter.d.ts.map +1 -1
- package/dist/cjs/components/Dashboard/DashboardFilter.js +1 -1
- package/dist/cjs/components/Dashboard/DataLoader.d.ts.map +1 -1
- package/dist/cjs/components/Dashboard/DataLoader.js +52 -15
- package/dist/cjs/components/Dashboard/MetricComponent.d.ts.map +1 -1
- package/dist/cjs/components/Dashboard/MetricComponent.js +7 -1
- package/dist/cjs/components/Dashboard/TableComponent.d.ts +16 -2
- package/dist/cjs/components/Dashboard/TableComponent.d.ts.map +1 -1
- package/dist/cjs/components/Dashboard/TableComponent.js +2 -14
- package/dist/cjs/components/QuillTable.d.ts +2 -2
- package/dist/cjs/components/QuillTable.d.ts.map +1 -1
- package/dist/cjs/components/QuillTable.js +7 -5
- package/dist/cjs/components/UiComponents.d.ts +3 -3
- package/dist/cjs/components/UiComponents.d.ts.map +1 -1
- package/dist/cjs/components/UiComponents.js +4 -4
- package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts +16 -1
- package/dist/cjs/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
- package/dist/cjs/internals/ReportBuilder/PivotModal.js +155 -80
- package/dist/cjs/utils/constants.d.ts +2 -0
- package/dist/cjs/utils/constants.d.ts.map +1 -0
- package/dist/cjs/utils/constants.js +4 -0
- package/dist/cjs/utils/dashboard.d.ts +1 -0
- package/dist/cjs/utils/dashboard.d.ts.map +1 -1
- package/dist/cjs/utils/dashboard.js +46 -97
- package/dist/cjs/utils/dataFetcher.d.ts.map +1 -1
- package/dist/cjs/utils/dataFetcher.js +56 -13
- package/dist/cjs/utils/dates.d.ts +8 -0
- package/dist/cjs/utils/dates.d.ts.map +1 -1
- package/dist/cjs/utils/dates.js +34 -1
- package/dist/cjs/utils/filterProcessing.d.ts +2 -0
- package/dist/cjs/utils/filterProcessing.d.ts.map +1 -1
- package/dist/cjs/utils/filterProcessing.js +129 -1
- package/dist/cjs/utils/logging.d.ts +2 -0
- package/dist/cjs/utils/logging.d.ts.map +1 -0
- package/dist/cjs/utils/logging.js +10 -0
- package/dist/cjs/utils/pivotConstructor.d.ts +6 -0
- package/dist/cjs/utils/pivotConstructor.d.ts.map +1 -0
- package/dist/cjs/utils/pivotConstructor.js +87 -0
- package/dist/cjs/utils/queryConstructor.d.ts +2 -1
- package/dist/cjs/utils/queryConstructor.d.ts.map +1 -1
- package/dist/cjs/utils/queryConstructor.js +46 -11
- package/dist/cjs/utils/tableProcessing.d.ts +22 -0
- package/dist/cjs/utils/tableProcessing.d.ts.map +1 -1
- package/dist/cjs/utils/tableProcessing.js +87 -1
- package/dist/esm/Chart.d.ts +17 -2
- package/dist/esm/Chart.d.ts.map +1 -1
- package/dist/esm/Chart.js +140 -93
- package/dist/esm/ChartBuilder.d.ts +3 -3
- package/dist/esm/ChartBuilder.d.ts.map +1 -1
- package/dist/esm/ChartBuilder.js +30 -23
- package/dist/esm/ChartEditor.d.ts.map +1 -1
- package/dist/esm/ChartEditor.js +66 -26
- package/dist/esm/Context.d.ts +1 -0
- package/dist/esm/Context.d.ts.map +1 -1
- package/dist/esm/Context.js +16 -1
- package/dist/esm/Dashboard.d.ts +6 -1
- package/dist/esm/Dashboard.d.ts.map +1 -1
- package/dist/esm/Dashboard.js +3 -1
- package/dist/esm/ReportBuilder.d.ts +1 -1
- package/dist/esm/ReportBuilder.d.ts.map +1 -1
- package/dist/esm/ReportBuilder.js +13 -11
- package/dist/esm/SQLEditor.d.ts +10 -1
- package/dist/esm/SQLEditor.d.ts.map +1 -1
- package/dist/esm/SQLEditor.js +27 -3
- package/dist/esm/Table.d.ts +15 -1
- package/dist/esm/Table.d.ts.map +1 -1
- package/dist/esm/Table.js +146 -62
- package/dist/esm/components/Chart/ChartTooltip.d.ts.map +1 -1
- package/dist/esm/components/Chart/ChartTooltip.js +5 -4
- package/dist/esm/components/Dashboard/DashboardFilter.d.ts.map +1 -1
- package/dist/esm/components/Dashboard/DashboardFilter.js +1 -1
- package/dist/esm/components/Dashboard/DataLoader.d.ts.map +1 -1
- package/dist/esm/components/Dashboard/DataLoader.js +52 -15
- package/dist/esm/components/Dashboard/MetricComponent.d.ts.map +1 -1
- package/dist/esm/components/Dashboard/MetricComponent.js +7 -1
- package/dist/esm/components/Dashboard/TableComponent.d.ts +16 -2
- package/dist/esm/components/Dashboard/TableComponent.d.ts.map +1 -1
- package/dist/esm/components/Dashboard/TableComponent.js +2 -14
- package/dist/esm/components/QuillTable.d.ts +2 -2
- package/dist/esm/components/QuillTable.d.ts.map +1 -1
- package/dist/esm/components/QuillTable.js +7 -5
- package/dist/esm/components/UiComponents.d.ts +3 -3
- package/dist/esm/components/UiComponents.d.ts.map +1 -1
- package/dist/esm/components/UiComponents.js +4 -4
- package/dist/esm/internals/ReportBuilder/PivotModal.d.ts +16 -1
- package/dist/esm/internals/ReportBuilder/PivotModal.d.ts.map +1 -1
- package/dist/esm/internals/ReportBuilder/PivotModal.js +153 -80
- package/dist/esm/utils/constants.d.ts +2 -0
- package/dist/esm/utils/constants.d.ts.map +1 -0
- package/dist/esm/utils/constants.js +1 -0
- package/dist/esm/utils/dashboard.d.ts +1 -0
- package/dist/esm/utils/dashboard.d.ts.map +1 -1
- package/dist/esm/utils/dashboard.js +45 -97
- package/dist/esm/utils/dataFetcher.d.ts.map +1 -1
- package/dist/esm/utils/dataFetcher.js +56 -13
- package/dist/esm/utils/dates.d.ts +8 -0
- package/dist/esm/utils/dates.d.ts.map +1 -1
- package/dist/esm/utils/dates.js +31 -0
- package/dist/esm/utils/filterProcessing.d.ts +2 -0
- package/dist/esm/utils/filterProcessing.d.ts.map +1 -1
- package/dist/esm/utils/filterProcessing.js +126 -0
- package/dist/esm/utils/logging.d.ts +2 -0
- package/dist/esm/utils/logging.d.ts.map +1 -0
- package/dist/esm/utils/logging.js +6 -0
- package/dist/esm/utils/pivotConstructor.d.ts +6 -0
- package/dist/esm/utils/pivotConstructor.d.ts.map +1 -0
- package/dist/esm/utils/pivotConstructor.js +83 -0
- package/dist/esm/utils/queryConstructor.d.ts +2 -1
- package/dist/esm/utils/queryConstructor.d.ts.map +1 -1
- package/dist/esm/utils/queryConstructor.js +44 -10
- package/dist/esm/utils/tableProcessing.d.ts +22 -0
- package/dist/esm/utils/tableProcessing.d.ts.map +1 -1
- package/dist/esm/utils/tableProcessing.js +85 -1
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { valueFormatter } from './valueFormatter';
|
|
2
|
-
import { generatePivotTable, generatePivotTableYAxis,
|
|
2
|
+
import { generatePivotTable, generatePivotTableYAxis, } from '../internals/ReportBuilder/PivotModal';
|
|
3
3
|
import { snakeAndCamelCaseToTitleCase } from './textProcessing';
|
|
4
|
-
import { generatePivotQuery } from './queryConstructor';
|
|
5
4
|
import { getData } from './dataFetcher';
|
|
6
|
-
import {
|
|
5
|
+
import { getDateBucketFromRange } from './dates';
|
|
6
|
+
import { generatePivotWithSQL } from './pivotConstructor';
|
|
7
7
|
const defaultDashboardItem = {
|
|
8
8
|
id: '',
|
|
9
9
|
name: '',
|
|
@@ -67,8 +67,10 @@ export async function cleanDashboardItem(item, dashboardFilters, client, dateBuc
|
|
|
67
67
|
xAxisFormat: item.xAxisFormat,
|
|
68
68
|
order: item.order,
|
|
69
69
|
filtersApplied: item.filtersApplied,
|
|
70
|
+
rowCount: parseInt(item.rowCount),
|
|
70
71
|
sort: item.sort,
|
|
71
72
|
page: item.page,
|
|
73
|
+
itemQuery: item.itemQuery,
|
|
72
74
|
};
|
|
73
75
|
}
|
|
74
76
|
/**
|
|
@@ -118,106 +120,34 @@ async function getPivotTable(report, dashboardFilters, client, dateBucketInitial
|
|
|
118
120
|
}
|
|
119
121
|
const pivot = report?.pivot;
|
|
120
122
|
const data = report || {};
|
|
121
|
-
if (client && client.databaseType.toLowerCase() === 'postgresql') {
|
|
123
|
+
if (pivot && client && client.databaseType.toLowerCase() === 'postgresql') {
|
|
124
|
+
if (report.rowCount === 0) {
|
|
125
|
+
return { rows: [], columns: [] };
|
|
126
|
+
}
|
|
122
127
|
try {
|
|
123
|
-
let dateRange = undefined;
|
|
124
|
-
let comparisonInterval = undefined;
|
|
125
128
|
let dateBucket = dateBucketInitial;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
dateRange = getDateRange(filterDateRange, pivot.rowField, data.rows);
|
|
135
|
-
const difference = differenceInDays(dateRange.end, dateRange.start);
|
|
136
|
-
if (difference < 14) {
|
|
137
|
-
dateBucket = 'day';
|
|
138
|
-
}
|
|
139
|
-
else if (difference < 60) {
|
|
140
|
-
dateBucket = 'week';
|
|
141
|
-
}
|
|
142
|
-
else if (difference < 365 * 3) {
|
|
143
|
-
dateBucket = 'month';
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
dateBucket = 'year';
|
|
147
|
-
}
|
|
129
|
+
let filterDateRange = undefined;
|
|
130
|
+
if (dateFilter) {
|
|
131
|
+
filterDateRange = {
|
|
132
|
+
start: dateFilter.startDate,
|
|
133
|
+
end: dateFilter.endDate,
|
|
134
|
+
};
|
|
148
135
|
}
|
|
149
|
-
if (
|
|
150
|
-
|
|
151
|
-
if (!isNaN(comparisonRange)) {
|
|
152
|
-
if (dateBucket === 'month') {
|
|
153
|
-
comparisonInterval = comparisonRange / 30 + ' month';
|
|
154
|
-
}
|
|
155
|
-
else if (dateBucket === 'year') {
|
|
156
|
-
comparisonInterval = comparisonRange / 365 + ' year';
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
comparisonInterval = comparisonRange + ' day';
|
|
160
|
-
}
|
|
161
|
-
}
|
|
136
|
+
else if (report.dateRange) {
|
|
137
|
+
filterDateRange = report.dateRange;
|
|
162
138
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const hostedBody = {
|
|
166
|
-
metadata: {
|
|
167
|
-
preQueries: [sqlQuery],
|
|
168
|
-
task: 'query',
|
|
169
|
-
orgId: client.customerId || '*',
|
|
170
|
-
clientId: client.publicKey,
|
|
171
|
-
databaseType: client?.databaseType,
|
|
172
|
-
getCustomFields: false,
|
|
173
|
-
runQueryConfig: {
|
|
174
|
-
overridePost: true,
|
|
175
|
-
convertDatatypes: true,
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
};
|
|
179
|
-
const cloudBody = { ...hostedBody };
|
|
180
|
-
const resp = await getData(client, 'query', 'same-origin', hostedBody, cloudBody);
|
|
181
|
-
// With our current design we have to remove the second row field but leave the first for comparison purposes.
|
|
182
|
-
const rows = resp.queryResults[0].rows;
|
|
183
|
-
const columns = resp.queryResults[0].fields
|
|
184
|
-
.map((field) => ({
|
|
185
|
-
field: field.name,
|
|
186
|
-
label: field.name.replace('comparison_', 'comparison '),
|
|
187
|
-
}))
|
|
188
|
-
.filter((field, index) => field.field !== 'comparison_' + pivot.rowField || index === 0);
|
|
189
|
-
if (pivot.rowFieldType !== 'string') {
|
|
190
|
-
rows.forEach((row) => {
|
|
191
|
-
row[pivot.rowField] = getDateString(row[pivot.rowField], undefined, dateBucket);
|
|
192
|
-
});
|
|
193
|
-
// add a row for each date in the range that doesn't have a value
|
|
194
|
-
if (pivot.rowFieldType !== 'string') {
|
|
195
|
-
const dateSet = new Set(rows.map((row) => row[pivot.rowField]));
|
|
196
|
-
// create a loop that will go through each formatted date and add a row if it doesn't exist going to the current date
|
|
197
|
-
for (let date = dateFilter.startDate; date <= dateFilter.endDate; date = new Date(date.getTime() + 24 * 60 * 60 * 1000)) {
|
|
198
|
-
const formattedDate = getDateString(date.toDateString(), undefined, dateBucket);
|
|
199
|
-
if (!dateSet.has(formattedDate)) {
|
|
200
|
-
const newRow = {};
|
|
201
|
-
newRow[pivot.rowField] = formattedDate;
|
|
202
|
-
rows.push(newRow);
|
|
203
|
-
dateSet.add(formattedDate);
|
|
204
|
-
}
|
|
205
|
-
// order the rows by the date field
|
|
206
|
-
rows.sort((a, b) => {
|
|
207
|
-
return new Date(a[pivot.rowField]) < new Date(b[pivot.rowField])
|
|
208
|
-
? -1
|
|
209
|
-
: 1;
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return {
|
|
215
|
-
rows: rows,
|
|
216
|
-
columns: columns,
|
|
217
|
-
};
|
|
139
|
+
if (!dateBucket && filterDateRange) {
|
|
140
|
+
dateBucket = getDateBucketFromRange(filterDateRange);
|
|
218
141
|
}
|
|
142
|
+
const pivotTable = await generatePivotWithSQL(pivot, report, client, dateBucket, dateFilter, report.distinctStrings);
|
|
143
|
+
if (pivotTable) {
|
|
144
|
+
return pivotTable;
|
|
145
|
+
}
|
|
146
|
+
throw new Error('Error generating pivot table');
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
throw new Error('Error generating pivot table: ' + e);
|
|
219
150
|
}
|
|
220
|
-
catch (e) { }
|
|
221
151
|
}
|
|
222
152
|
return pivot && data.rows
|
|
223
153
|
? generatePivotTable(pivot, JSON.parse(JSON.stringify(data.rows)), // deep copy
|
|
@@ -274,3 +204,21 @@ function extractPivotedYAxis(pivotTable, itemInfo, config = undefined) {
|
|
|
274
204
|
}
|
|
275
205
|
return fields;
|
|
276
206
|
}
|
|
207
|
+
export async function getDashboard(dashboardName, client) {
|
|
208
|
+
const searchParams = new URLSearchParams({
|
|
209
|
+
publicKey: client.publicKey,
|
|
210
|
+
orgId: client.customerId,
|
|
211
|
+
name: dashboardName,
|
|
212
|
+
}).toString();
|
|
213
|
+
const hostedBody = {
|
|
214
|
+
metadata: {
|
|
215
|
+
name: dashboardName,
|
|
216
|
+
task: 'config',
|
|
217
|
+
clientId: client.publicKey,
|
|
218
|
+
orgId: client.customerId || '*',
|
|
219
|
+
databaseType: client.databaseType,
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
const resp = await getData(client, `dashconfig?${searchParams}`, 'omit', hostedBody, null, 'GET');
|
|
223
|
+
return resp;
|
|
224
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataFetcher.d.ts","sourceRoot":"","sources":["../../../src/utils/dataFetcher.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dataFetcher.d.ts","sourceRoot":"","sources":["../../../src/utils/dataFetcher.tsx"],"names":[],"mappings":"AAqBA,wBAAsB,OAAO,CAC3B,MAAM,EAAE,GAAG,EACX,kBAAkB,EAAE,MAAM,EAC1B,MAAM,EAAE,kBAAkB,EAC1B,iBAAiB,EAAE,GAAG,EACtB,gBAAgB,EAAE,GAAG,EACrB,MAAM,SAAS,gBAmGhB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,GAAG,EACX,kBAAkB,EAAE,MAAM,EAC1B,gBAAgB,EAAE,GAAG,EACrB,MAAM,SAAS,gBAgChB"}
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
function parseData(rows, queryType) {
|
|
2
|
+
if (!rows || rows.length === 0)
|
|
3
|
+
return [];
|
|
4
|
+
switch (queryType) {
|
|
5
|
+
case 'dateRange':
|
|
6
|
+
return {
|
|
7
|
+
start: new Date(rows[0]?.min_date),
|
|
8
|
+
end: new Date(rows[0]?.max_date),
|
|
9
|
+
};
|
|
10
|
+
case 'rowCount':
|
|
11
|
+
return parseInt(rows[0]?.count);
|
|
12
|
+
case 'distinctStrings':
|
|
13
|
+
return rows.map((row) => {
|
|
14
|
+
return row['column_field'];
|
|
15
|
+
});
|
|
16
|
+
default:
|
|
17
|
+
return rows;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
1
20
|
// this function gets the data either from the self hosted endpoint or
|
|
2
21
|
// our cloud server
|
|
3
22
|
export async function getData(client, cloudQueryEndpoint, noCred, hostedRequestBody, cloudRequestBody, method = 'POST') {
|
|
@@ -18,21 +37,45 @@ export async function getData(client, cloudQueryEndpoint, noCred, hostedRequestB
|
|
|
18
37
|
return { success: false, errorMessage: responseJson.error };
|
|
19
38
|
}
|
|
20
39
|
let result;
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
40
|
+
if (hostedRequestBody &&
|
|
41
|
+
hostedRequestBody.metadata &&
|
|
42
|
+
hostedRequestBody.metadata.task === 'report') {
|
|
43
|
+
if (responseJson.data?.data) {
|
|
44
|
+
result = {
|
|
45
|
+
fields: responseJson?.data.queries?.queryResults[0]?.fields,
|
|
46
|
+
...responseJson.data.data,
|
|
47
|
+
};
|
|
48
|
+
responseJson.data.data.queryOrder.forEach((queryKey, index) => {
|
|
49
|
+
result[queryKey] = parseData(responseJson.queries.queryResults[index].rows, queryKey);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
result = {
|
|
54
|
+
fields: responseJson?.queries?.queryResults[0]?.fields,
|
|
55
|
+
...responseJson.data,
|
|
56
|
+
};
|
|
57
|
+
responseJson.data.queryOrder.forEach((queryKey, index) => {
|
|
58
|
+
result[queryKey] = parseData(responseJson.queries.queryResults[index].rows, queryKey);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
28
61
|
}
|
|
29
62
|
else {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
63
|
+
if (responseJson.data?.data) {
|
|
64
|
+
result = {
|
|
65
|
+
fields: responseJson?.data.queries?.queryResults[0]?.fields,
|
|
66
|
+
...responseJson.data.data,
|
|
67
|
+
rows: responseJson?.data.queries?.queryResults[0]?.rows,
|
|
68
|
+
compareRows: responseJson?.data.queries?.queryResults[1]?.rows,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
result = {
|
|
73
|
+
fields: responseJson?.queries?.queryResults[0]?.fields,
|
|
74
|
+
...responseJson.data,
|
|
75
|
+
rows: responseJson?.queries?.queryResults[0]?.rows,
|
|
76
|
+
compareRows: responseJson?.queries?.queryResults[1]?.rows,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
36
79
|
}
|
|
37
80
|
if (responseJson.data.columns &&
|
|
38
81
|
responseJson.data.fields &&
|
|
@@ -7,4 +7,12 @@ export declare function convertComparisonRange(primaryRange: string, comparisonR
|
|
|
7
7
|
* Returns whether the xAxisFormat is a date format.
|
|
8
8
|
*/
|
|
9
9
|
export declare function isDateFormat(xAxisFormat: string): boolean;
|
|
10
|
+
export declare function getComparisonInterval(comparisonRange: {
|
|
11
|
+
startDate: Date;
|
|
12
|
+
endDate: Date;
|
|
13
|
+
}, dateBucket?: string): string | undefined;
|
|
14
|
+
export declare function getDateBucketFromRange(dateRange: {
|
|
15
|
+
start: Date;
|
|
16
|
+
end: Date;
|
|
17
|
+
}): "month" | "week" | "day" | "year";
|
|
10
18
|
//# sourceMappingURL=dates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dates.d.ts","sourceRoot":"","sources":["../../../src/utils/dates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dates.d.ts","sourceRoot":"","sources":["../../../src/utils/dates.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,UAYxB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,WAa/C;AAED,wBAAgB,qBAAqB,CACnC,eAAe,EAAE;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;CACf,EACD,UAAU,CAAC,EAAE,MAAM,sBAepB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,qCAW3E"}
|
package/dist/esm/utils/dates.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { differenceInDays } from 'date-fns';
|
|
1
2
|
import { COMPARISON_OPTIONS } from '../DateRangePicker/dateRangePickerUtils';
|
|
2
3
|
/**
|
|
3
4
|
* Converts the comparison range label to match the date filter range if the
|
|
@@ -23,6 +24,7 @@ export function convertComparisonRange(primaryRange, comparisonRange) {
|
|
|
23
24
|
export function isDateFormat(xAxisFormat) {
|
|
24
25
|
const DATE_FORMATS = [
|
|
25
26
|
'yyyy',
|
|
27
|
+
'MMM_dd',
|
|
26
28
|
'MMM_yyyy',
|
|
27
29
|
'MMM_dd_yyyy',
|
|
28
30
|
'hh_ap_pm',
|
|
@@ -33,3 +35,32 @@ export function isDateFormat(xAxisFormat) {
|
|
|
33
35
|
const isDate = DATE_FORMATS.includes(xAxisFormat);
|
|
34
36
|
return isDate;
|
|
35
37
|
}
|
|
38
|
+
export function getComparisonInterval(comparisonRange, dateBucket) {
|
|
39
|
+
const dayCount = differenceInDays(comparisonRange.endDate, comparisonRange.startDate);
|
|
40
|
+
if (!isNaN(dayCount)) {
|
|
41
|
+
if (dateBucket === 'month') {
|
|
42
|
+
return dayCount / 30 + ' month';
|
|
43
|
+
}
|
|
44
|
+
else if (dateBucket === 'year') {
|
|
45
|
+
return dayCount / 365 + ' year';
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return dayCount + ' day';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function getDateBucketFromRange(dateRange) {
|
|
53
|
+
const difference = differenceInDays(dateRange.end, dateRange.start);
|
|
54
|
+
if (difference < 14) {
|
|
55
|
+
return 'day';
|
|
56
|
+
}
|
|
57
|
+
else if (difference < 60) {
|
|
58
|
+
return 'week';
|
|
59
|
+
}
|
|
60
|
+
else if (difference < 365 * 3) {
|
|
61
|
+
return 'month';
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
return 'year';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export declare function findAndProcessDateFilter(filters: any[]): any;
|
|
2
|
+
export declare function processFilterFromBackend(filter: any, rows: any[]): any;
|
|
3
|
+
export declare function updateFilter(filter: any, value?: any, comparison?: any): any;
|
|
2
4
|
//# sourceMappingURL=filterProcessing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterProcessing.d.ts","sourceRoot":"","sources":["../../../src/utils/filterProcessing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"filterProcessing.d.ts","sourceRoot":"","sources":["../../../src/utils/filterProcessing.ts"],"names":[],"mappings":"AAQA,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,CAoB5D;AAMD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OA4BhE;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,GAAG,EACX,KAAK,GAAE,GAAU,EACjB,UAAU,GAAE,GAAU,OAuGvB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { COMPARISON_RANGE, PRIMARY_RANGE, defaultOptionsV2, getRangeFromPresetOptions, } from '../DateRangePicker/dateRangePickerUtils';
|
|
1
2
|
export function findAndProcessDateFilter(filters) {
|
|
2
3
|
let dateFilter = filters.find((filter) => filter.filterType === 'date_range');
|
|
3
4
|
if (dateFilter) {
|
|
@@ -19,3 +20,128 @@ export function findAndProcessDateFilter(filters) {
|
|
|
19
20
|
function isValidDate(date) {
|
|
20
21
|
return !isNaN(Date.parse(date));
|
|
21
22
|
}
|
|
23
|
+
export function processFilterFromBackend(filter, rows) {
|
|
24
|
+
if (filter.filterType === 'date_range') {
|
|
25
|
+
return {
|
|
26
|
+
...filter,
|
|
27
|
+
startDate: new Date(filter.startDate),
|
|
28
|
+
endDate: new Date(filter.endDate),
|
|
29
|
+
options: defaultOptionsV2,
|
|
30
|
+
comparisonRange: {
|
|
31
|
+
...filter.comparisonRange,
|
|
32
|
+
value: filter.defaultComparisonRange,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (filter.filterType === 'string') {
|
|
37
|
+
const options = rows.map((row) => row[filter.field]);
|
|
38
|
+
const distinctOptions = Array.from(new Set(options)).filter((value) => value !== undefined && value !== null);
|
|
39
|
+
return {
|
|
40
|
+
...filter,
|
|
41
|
+
options: distinctOptions.map((option) => ({
|
|
42
|
+
label: option,
|
|
43
|
+
value: option,
|
|
44
|
+
})),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return filter;
|
|
48
|
+
}
|
|
49
|
+
export function updateFilter(filter, value = null, comparison = null) {
|
|
50
|
+
//for dateObjects only, since values are arrays for dateObjects
|
|
51
|
+
const { selectedValue: _, operator, ...filterWithoutSelectedValue } = filter; // _ is a throwaway variable
|
|
52
|
+
if (filter.filterType === 'string') {
|
|
53
|
+
let selectedValue = {};
|
|
54
|
+
if (value) {
|
|
55
|
+
if (filter.stringFilterType === 'multiselect') {
|
|
56
|
+
const parsedValue = JSON.parse(value);
|
|
57
|
+
if (parsedValue.length === 0) {
|
|
58
|
+
selectedValue = { values: [] };
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
selectedValue = { values: parsedValue, operator: 'IN' };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
selectedValue = { selectedValue: value };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
...filterWithoutSelectedValue,
|
|
70
|
+
...selectedValue,
|
|
71
|
+
dashboardName: name,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (filter.filterType === 'date' || filter.filterType === 'date_range') {
|
|
75
|
+
let presetsOptions = defaultOptionsV2;
|
|
76
|
+
if (filter.presetRanges) {
|
|
77
|
+
presetsOptions = filter.presetRanges.map((elem) => {
|
|
78
|
+
if (!elem.isStatic) {
|
|
79
|
+
return {
|
|
80
|
+
label: elem.label,
|
|
81
|
+
value: elem.value,
|
|
82
|
+
startDate: PRIMARY_RANGE[elem.value].start,
|
|
83
|
+
endDate: PRIMARY_RANGE[elem.value].end,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
label: elem.label,
|
|
88
|
+
value: elem.value,
|
|
89
|
+
startDate: new Date(elem.startDate),
|
|
90
|
+
endDate: new Date(elem.endDate),
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (comparison ||
|
|
95
|
+
(filter.comparison && filter.comparisonRange.value !== 'NO_COMPARISON')) {
|
|
96
|
+
let preset = '';
|
|
97
|
+
if (comparison) {
|
|
98
|
+
preset = filter.preset.label;
|
|
99
|
+
}
|
|
100
|
+
const key = comparison?.value || filter.comparisonRange.value;
|
|
101
|
+
let primaryRange = {
|
|
102
|
+
start: value ? value.startDate : filter.startDate,
|
|
103
|
+
end: value ? value.endDate : filter.endDate,
|
|
104
|
+
};
|
|
105
|
+
if (value && value.preset) {
|
|
106
|
+
preset = value.preset;
|
|
107
|
+
primaryRange = getRangeFromPresetOptions(value.preset, presetsOptions);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
startDate: primaryRange.start,
|
|
111
|
+
endDate: primaryRange.end,
|
|
112
|
+
filterType: 'date_range',
|
|
113
|
+
label: 'Date',
|
|
114
|
+
field: 'date_range',
|
|
115
|
+
preset: { label: preset },
|
|
116
|
+
options: filter.options,
|
|
117
|
+
comparison: true,
|
|
118
|
+
comparisonRange: {
|
|
119
|
+
startDate: COMPARISON_RANGE[key](primaryRange)?.start,
|
|
120
|
+
endDate: COMPARISON_RANGE[key](primaryRange)?.end,
|
|
121
|
+
value: key,
|
|
122
|
+
},
|
|
123
|
+
dashboardName: name,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const primaryRange = value && value.preset
|
|
128
|
+
? getRangeFromPresetOptions(value.preset, presetsOptions)
|
|
129
|
+
: {
|
|
130
|
+
start: value?.startDate || filter.startDate,
|
|
131
|
+
end: value?.endDate || filter.endDate,
|
|
132
|
+
};
|
|
133
|
+
const preset = value?.preset ? value.preset : '';
|
|
134
|
+
return {
|
|
135
|
+
...filter,
|
|
136
|
+
preset: { label: preset },
|
|
137
|
+
startDate: primaryRange.start,
|
|
138
|
+
endDate: primaryRange.end,
|
|
139
|
+
filterType: 'date_range',
|
|
140
|
+
field: 'date_range',
|
|
141
|
+
options: filter.options,
|
|
142
|
+
label: 'Date',
|
|
143
|
+
dashboardName: name,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.d.ts","sourceRoot":"","sources":["../../../src/utils/logging.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,QAKpE"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Pivot } from '../internals/ReportBuilder/PivotModal';
|
|
2
|
+
export declare function generatePivotWithSQL(pivot: Pivot, report: any, client: any, dateBucket?: string, dateFilter?: any, distinctStrings?: any): Promise<{
|
|
3
|
+
rows: any;
|
|
4
|
+
columns: any;
|
|
5
|
+
} | undefined>;
|
|
6
|
+
//# sourceMappingURL=pivotConstructor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pivotConstructor.d.ts","sourceRoot":"","sources":["../../../src/utils/pivotConstructor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAiB,MAAM,uCAAuC,CAAC;AAK7E,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,GAAG,EACX,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,GAAG,EAChB,eAAe,CAAC,EAAE,GAAG;;;eAkHtB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { getDateString } from '../internals/ReportBuilder/PivotModal';
|
|
2
|
+
import { getData } from './dataFetcher';
|
|
3
|
+
import { getComparisonInterval } from './dates';
|
|
4
|
+
import { generatePivotQuery } from './queryConstructor';
|
|
5
|
+
export async function generatePivotWithSQL(pivot, report, client, dateBucket, dateFilter, distinctStrings) {
|
|
6
|
+
if (dateFilter && dateFilter.startDate) {
|
|
7
|
+
dateFilter.start = dateFilter.startDate;
|
|
8
|
+
dateFilter.end = dateFilter.endDate;
|
|
9
|
+
if (dateFilter.comparisonRange && dateFilter.comparisonRange.startDate) {
|
|
10
|
+
dateFilter.comparisonRange.start = dateFilter.comparisonRange.startDate;
|
|
11
|
+
dateFilter.comparisonRange.end = dateFilter.comparisonRange.endDate;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
let comparisonInterval = undefined;
|
|
15
|
+
if (dateFilter && dateFilter.comparisonRange) {
|
|
16
|
+
comparisonInterval = getComparisonInterval({
|
|
17
|
+
startDate: dateFilter.comparisonRange.start,
|
|
18
|
+
endDate: dateFilter.comparisonRange.end,
|
|
19
|
+
}, dateBucket);
|
|
20
|
+
}
|
|
21
|
+
if (pivot.rowField && !pivot.rowFieldType) {
|
|
22
|
+
const rowColumn = report.columns.find((column) => column.field === pivot.rowField);
|
|
23
|
+
pivot.rowFieldType = rowColumn.format;
|
|
24
|
+
}
|
|
25
|
+
const sqlQuery = generatePivotQuery(pivot, report.itemQuery, report.rows, dateBucket, comparisonInterval, distinctStrings);
|
|
26
|
+
if (sqlQuery && report.rows.length > 0) {
|
|
27
|
+
const hostedBody = {
|
|
28
|
+
metadata: {
|
|
29
|
+
preQueries: [sqlQuery],
|
|
30
|
+
task: 'query',
|
|
31
|
+
orgId: client.customerId || '*',
|
|
32
|
+
clientId: client.publicKey,
|
|
33
|
+
databaseType: client?.databaseType,
|
|
34
|
+
getCustomFields: false,
|
|
35
|
+
runQueryConfig: {
|
|
36
|
+
overridePost: true,
|
|
37
|
+
convertDatatypes: true,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const cloudBody = { ...hostedBody };
|
|
42
|
+
const resp = await getData(client, 'query', 'same-origin', hostedBody, cloudBody);
|
|
43
|
+
// With our current design we have to remove the second row field but leave the first for comparison purposes.
|
|
44
|
+
const rows = resp.queryResults[0].rows;
|
|
45
|
+
const columns = resp.queryResults[0].fields
|
|
46
|
+
.map((field) => ({
|
|
47
|
+
field: field.name,
|
|
48
|
+
label: field.name.replace('comparison_', 'comparison '),
|
|
49
|
+
}))
|
|
50
|
+
.filter((field, index) => field.field !== 'comparison_' + pivot.rowField || index === 0);
|
|
51
|
+
if (pivot.rowField && !['string', 'varchar'].includes(pivot.rowFieldType)) {
|
|
52
|
+
rows.forEach((row) => {
|
|
53
|
+
row[pivot.rowField] = getDateString(row[pivot.rowField], undefined, dateBucket);
|
|
54
|
+
});
|
|
55
|
+
// add a row for each date in the range that doesn't have a value
|
|
56
|
+
if (pivot.rowField &&
|
|
57
|
+
!['string', 'varchar'].includes(pivot.rowFieldType) &&
|
|
58
|
+
dateFilter) {
|
|
59
|
+
const dateSet = new Set(rows.map((row) => row[pivot.rowField]));
|
|
60
|
+
// create a loop that will go through each formatted date and add a row if it doesn't exist going to the current date
|
|
61
|
+
for (let date = dateFilter.start ?? dateFilter.startDate; date <= dateFilter.end; date = new Date(date.getTime() + 24 * 60 * 60 * 1000)) {
|
|
62
|
+
const formattedDate = getDateString(date.toDateString(), undefined, dateBucket);
|
|
63
|
+
if (!dateSet.has(formattedDate)) {
|
|
64
|
+
const newRow = {};
|
|
65
|
+
newRow[pivot.rowField] = formattedDate;
|
|
66
|
+
rows.push(newRow);
|
|
67
|
+
dateSet.add(formattedDate);
|
|
68
|
+
}
|
|
69
|
+
// order the rows by the date field
|
|
70
|
+
rows.sort((a, b) => {
|
|
71
|
+
return new Date(a[pivot.rowField]) < new Date(b[pivot.rowField])
|
|
72
|
+
? -1
|
|
73
|
+
: 1;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
rows: rows,
|
|
80
|
+
columns: columns,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Pivot } from '../internals/ReportBuilder/PivotModal';
|
|
2
2
|
export declare function generateDistinctQuery(stringFields: string[], query: string): string;
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function generateMinMaxRangeQueries(columnFields: string[], query: string, databaseType: string): string;
|
|
4
|
+
export declare function generatePivotQuery(pivot: Pivot, itemQueries: string[], rows: any[], dateBucket?: string, comparisonInterval?: string, distinctStrings?: string[]): string | undefined;
|
|
4
5
|
//# sourceMappingURL=queryConstructor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryConstructor.d.ts","sourceRoot":"","sources":["../../../src/utils/queryConstructor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uCAAuC,CAAC;AAe9D,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,UAQ1E;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,MAAM,EAAE,EACrB,IAAI,EAAE,GAAG,EAAE,EACX,UAAU,CAAC,EAAE,MAAM,EACnB,kBAAkB,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"queryConstructor.d.ts","sourceRoot":"","sources":["../../../src/utils/queryConstructor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uCAAuC,CAAC;AAe9D,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,UAQ1E;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,EAAE,EACtB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,UAcrB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,MAAM,EAAE,EACrB,IAAI,EAAE,GAAG,EAAE,EACX,UAAU,CAAC,EAAE,MAAM,EACnB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,MAAM,GAAG,SAAS,CAuBpB"}
|