@quillsql/react 2.12.27 → 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.map +1 -1
- package/dist/cjs/Chart.js +34 -17
- 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.map +1 -1
- 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.map +1 -1
- package/dist/cjs/Table.js +17 -7
- 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/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.map +1 -1
- package/dist/cjs/utils/dashboard.js +26 -96
- 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/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.map +1 -1
- package/dist/esm/Chart.js +34 -17
- 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.map +1 -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.map +1 -1
- package/dist/esm/Table.js +17 -7
- 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/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.map +1 -1
- package/dist/esm/utils/dashboard.js +27 -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/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,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
|
+
}
|
|
@@ -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"}
|
|
@@ -18,29 +18,42 @@ export function generateDistinctQuery(stringFields, query) {
|
|
|
18
18
|
const distinctQuery = distinctQueries.join(' UNION ALL ');
|
|
19
19
|
return `WITH querytable AS (${query.replace(';', '')}) ` + distinctQuery;
|
|
20
20
|
}
|
|
21
|
-
export function
|
|
21
|
+
export function generateMinMaxRangeQueries(columnFields, query, databaseType) {
|
|
22
|
+
const distinctQueries = columnFields.map((field) => {
|
|
23
|
+
const wrappedField = ['postgresql', 'snowflake'].includes(databaseType.toLowerCase())
|
|
24
|
+
? `"${field}"`
|
|
25
|
+
: field;
|
|
26
|
+
return `SELECT '${field}' AS field, MIN(${wrappedField}) AS min_range, MAX(${wrappedField}) AS max_range FROM querytable`;
|
|
27
|
+
});
|
|
28
|
+
const distinctQuery = distinctQueries.join(' UNION ALL ');
|
|
29
|
+
return `WITH querytable AS (${query.replace(';', '')}) ` + distinctQuery;
|
|
30
|
+
}
|
|
31
|
+
export function generatePivotQuery(pivot, itemQueries, rows, dateBucket, comparisonInterval, distinctStrings) {
|
|
22
32
|
if (!isValidPivot(pivot)) {
|
|
23
33
|
return undefined;
|
|
24
34
|
}
|
|
25
|
-
if (!pivot.rowField) {
|
|
26
|
-
return undefined;
|
|
27
|
-
}
|
|
28
35
|
if (pivot.columnField) {
|
|
29
|
-
return create2DPivotQuery(pivot, itemQueries, rows, dateBucket, comparisonInterval);
|
|
36
|
+
return create2DPivotQuery(pivot, itemQueries, rows, dateBucket, comparisonInterval, distinctStrings);
|
|
30
37
|
}
|
|
31
|
-
|
|
38
|
+
if (pivot.rowField) {
|
|
39
|
+
return create1DPivotQuery(pivot, itemQueries, dateBucket, comparisonInterval);
|
|
40
|
+
}
|
|
41
|
+
return createAggregationValuePivot(pivot, itemQueries);
|
|
32
42
|
}
|
|
33
|
-
function create2DPivotQuery(pivot, itemQueries, rows, dateBucket, comparisonInterval) {
|
|
43
|
+
function create2DPivotQuery(pivot, itemQueries, rows, dateBucket, comparisonInterval, distinctStrings) {
|
|
34
44
|
if (!pivot || !pivot.columnField) {
|
|
35
45
|
return undefined;
|
|
36
46
|
}
|
|
37
47
|
// @ts-ignore
|
|
38
48
|
const columnValues = rows.map((row) => row[pivot.columnField]);
|
|
39
|
-
const distinctColumnValues =
|
|
49
|
+
const distinctColumnValues = distinctStrings
|
|
50
|
+
? distinctStrings
|
|
51
|
+
: Array.from(new Set(columnValues)).filter((value) => value !== undefined && value !== null);
|
|
40
52
|
if (distinctColumnValues.length === 0) {
|
|
41
53
|
return undefined;
|
|
42
54
|
}
|
|
43
|
-
if (pivot.rowFieldType
|
|
55
|
+
if (['string', 'varchar'].includes(pivot.rowFieldType) ||
|
|
56
|
+
!pivot.rowFieldType) {
|
|
44
57
|
return create2DStringPivotQuery(pivot, itemQueries, distinctColumnValues);
|
|
45
58
|
}
|
|
46
59
|
return create2DDatePivotQuery(pivot, itemQueries, distinctColumnValues, dateBucket, comparisonInterval);
|
|
@@ -90,7 +103,8 @@ function create2DDatePivotQuery(pivot, itemQueries, distinctColumnValues, dateBu
|
|
|
90
103
|
${joinQuery} ORDER BY qt."${pivot.rowField}"`;
|
|
91
104
|
}
|
|
92
105
|
function create1DPivotQuery(pivot, itemQueries, dateBucket = 'month', comparisonInterval) {
|
|
93
|
-
if (pivot.rowFieldType
|
|
106
|
+
if (['string', 'varchar'].includes(pivot.rowFieldType) ||
|
|
107
|
+
!pivot.rowFieldType) {
|
|
94
108
|
return create1DStringPivotQuery(pivot, itemQueries);
|
|
95
109
|
}
|
|
96
110
|
return create1DDatePivotQuery(pivot, itemQueries, dateBucket, comparisonInterval);
|
|
@@ -127,3 +141,23 @@ function create1DDatePivotQuery(pivot, itemQueries, dateBucket = 'month', compar
|
|
|
127
141
|
SELECT * FROM quill_qt_agg qt
|
|
128
142
|
${joinQuery} ORDER BY qt."${pivot.rowField}"`;
|
|
129
143
|
}
|
|
144
|
+
function createAggregationValuePivot(pivot, itemQueries) {
|
|
145
|
+
let aggregationType = processAggType(pivot.aggregationType);
|
|
146
|
+
if (pivot.aggregationType === 'count') {
|
|
147
|
+
aggregationType = 'COUNT';
|
|
148
|
+
}
|
|
149
|
+
if (!pivot.valueField)
|
|
150
|
+
return undefined;
|
|
151
|
+
const compareCTE = itemQueries[1]
|
|
152
|
+
? `, quill_ct as (${itemQueries[1]?.replaceAll(';', '')})`
|
|
153
|
+
: '';
|
|
154
|
+
const compareAggregation = itemQueries[1]
|
|
155
|
+
? `, quill_ct_cw as (SELECT ${aggregationType}(${pivot.valueField}) as comparison_${pivot.valueField} FROM quill_ct)`
|
|
156
|
+
: '';
|
|
157
|
+
const joinQuery = itemQueries[1] ? `CROSS JOIN quill_ct_cw ct` : '';
|
|
158
|
+
return `WITH quill_qt AS (${itemQueries[0]?.replaceAll(';', '')}),
|
|
159
|
+
quill_qt_agg AS (SELECT ${aggregationType}(${pivot.valueField}) as ${pivot.valueField} FROM quill_qt)
|
|
160
|
+
${compareCTE} ${compareAggregation}
|
|
161
|
+
SELECT * FROM quill_qt_agg qt
|
|
162
|
+
${joinQuery}`;
|
|
163
|
+
}
|
|
@@ -1,8 +1,30 @@
|
|
|
1
|
+
import { QuillReport } from '../Dashboard';
|
|
1
2
|
import { Column } from '../models/Columns';
|
|
3
|
+
export interface AdditionalProcessing {
|
|
4
|
+
sort?: {
|
|
5
|
+
field: string;
|
|
6
|
+
direction: string;
|
|
7
|
+
};
|
|
8
|
+
page?: {
|
|
9
|
+
currentPage: number;
|
|
10
|
+
rowsPerPage: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
2
13
|
export declare const hasColumnAlias: (columns: Column[], referencedColumns: string[]) => boolean;
|
|
3
14
|
export declare const getUniqueValuesByColumns: (columns: Column[], query: string, rows: any, client: any, customFields: any[]) => Promise<{
|
|
4
15
|
[column: string]: {
|
|
5
16
|
[value: string]: boolean;
|
|
6
17
|
};
|
|
7
18
|
} | null>;
|
|
19
|
+
export declare const getDateRangeByColumns: (columns: Column[], query: string, client: any, customFields: any[]) => Promise<{
|
|
20
|
+
[column: string]: {
|
|
21
|
+
dateRange: {
|
|
22
|
+
start: Date;
|
|
23
|
+
end: Date;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
} | null>;
|
|
27
|
+
export declare const getPaginatedRows: (report: QuillReport, client: any, processing?: any, filters?: any, customFields?: any) => Promise<{
|
|
28
|
+
[field: string]: any;
|
|
29
|
+
}>;
|
|
8
30
|
//# sourceMappingURL=tableProcessing.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tableProcessing.d.ts","sourceRoot":"","sources":["../../../src/utils/tableProcessing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tableProcessing.d.ts","sourceRoot":"","sources":["../../../src/utils/tableProcessing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAS3C,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,IAAI,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAED,eAAO,MAAM,cAAc,YAChB,MAAM,EAAE,qBACE,MAAM,EAAE,KAC1B,OAUF,CAAC;AAEF,eAAO,MAAM,wBAAwB,YAC1B,MAAM,EAAE,SACV,MAAM,QACP,GAAG,UACD,GAAG,gBACG,GAAG,EAAE;;;;SA6DpB,CAAC;AAkDF,eAAO,MAAM,qBAAqB,YACvB,MAAM,EAAE,SACV,MAAM,UACL,GAAG,gBACG,GAAG,EAAE;;mBAEY;YAAE,KAAK,EAAE,IAAI,CAAC;YAAC,GAAG,EAAE,IAAI,CAAA;SAAE;;SAc1D,CAAC;AAqDF,eAAO,MAAM,gBAAgB,WACnB,WAAW,UACX,GAAG,eACE,GAAG,YACN,GAAG,iBACE,GAAG;;EA4CnB,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getData } from './dataFetcher';
|
|
2
|
-
import {
|
|
2
|
+
import { processFilterErrorList } from './errorProcessing';
|
|
3
|
+
import { mergeComparisonRange } from './merge';
|
|
4
|
+
import { generateDistinctQuery, generateMinMaxRangeQueries, } from './queryConstructor';
|
|
3
5
|
export const hasColumnAlias = (columns, referencedColumns) => {
|
|
4
6
|
if (!referencedColumns) {
|
|
5
7
|
return true;
|
|
@@ -92,3 +94,85 @@ const fetchDistinctStrings = async (query, client, customFields) => {
|
|
|
92
94
|
return null;
|
|
93
95
|
}
|
|
94
96
|
};
|
|
97
|
+
export const getDateRangeByColumns = async (columns, query, client, customFields) => {
|
|
98
|
+
const columnNames = columns.map((column) => column.field);
|
|
99
|
+
const distinctValueQuery = generateMinMaxRangeQueries(columnNames, query, client.databaseType);
|
|
100
|
+
const dateRanges = await fetchDateRanges(distinctValueQuery, client, customFields);
|
|
101
|
+
return dateRanges;
|
|
102
|
+
};
|
|
103
|
+
const fetchDateRanges = async (query, client, customFields) => {
|
|
104
|
+
try {
|
|
105
|
+
const hostedBody = {
|
|
106
|
+
metadata: {
|
|
107
|
+
query,
|
|
108
|
+
task: 'query',
|
|
109
|
+
orgId: client.customerId || '*',
|
|
110
|
+
clientId: client.publicKey,
|
|
111
|
+
databaseType: client?.databaseType,
|
|
112
|
+
customFieldsByTable: customFields,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
const cloudBody = { query };
|
|
116
|
+
const data = await getData(client, 'dashquery', 'same-origin', hostedBody, cloudBody);
|
|
117
|
+
if (data.errorMessage) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
const results = data.rows.reduce((acc, currentValue) => {
|
|
121
|
+
acc[currentValue.field] = {
|
|
122
|
+
dateRange: {
|
|
123
|
+
start: new Date(currentValue.min_range),
|
|
124
|
+
end: new Date(currentValue.max_range),
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
return acc;
|
|
128
|
+
}, {});
|
|
129
|
+
return results;
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
console.error(e);
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
export const getPaginatedRows = async (report, client, processing, filters, customFields) => {
|
|
137
|
+
let updatedProcessing = { ...processing };
|
|
138
|
+
if (processing && processing.sort && !updatedProcessing.page) {
|
|
139
|
+
updatedProcessing.page = {};
|
|
140
|
+
updatedProcessing.page.currentPage = 0;
|
|
141
|
+
}
|
|
142
|
+
const minimalFilters = Object.values(filters).length
|
|
143
|
+
? Object.values(filters).map((filter) => {
|
|
144
|
+
const newFilter = { ...filter };
|
|
145
|
+
if (newFilter.filterType === 'date_range') {
|
|
146
|
+
delete newFilter['field'];
|
|
147
|
+
delete newFilter['options'];
|
|
148
|
+
delete newFilter['selectedValue'];
|
|
149
|
+
}
|
|
150
|
+
return newFilter;
|
|
151
|
+
})
|
|
152
|
+
: [];
|
|
153
|
+
const hostedBody = {
|
|
154
|
+
metadata: {
|
|
155
|
+
dashboardItemId: report.id,
|
|
156
|
+
orgId: client?.customerId || '*',
|
|
157
|
+
task: 'item',
|
|
158
|
+
filters: minimalFilters,
|
|
159
|
+
clientId: client?.publicKey,
|
|
160
|
+
databaseType: client?.databaseType,
|
|
161
|
+
additionalProcessing: updatedProcessing,
|
|
162
|
+
forcePagination: true,
|
|
163
|
+
customFields,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
const cloudBody = {
|
|
167
|
+
id: report.id,
|
|
168
|
+
filters: [],
|
|
169
|
+
};
|
|
170
|
+
const resp = await getData(client, 'itempost', 'omit', hostedBody, cloudBody);
|
|
171
|
+
processFilterErrorList(resp);
|
|
172
|
+
if (resp && resp.name !== 'error') {
|
|
173
|
+
if (resp.compareRows) {
|
|
174
|
+
mergeComparisonRange(resp);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return resp.rows;
|
|
178
|
+
};
|