mirror of
https://github.com/apache/superset.git
synced 2026-04-19 16:14:52 +00:00
refactor(monorepo): move superset-ui to superset(stage 2) (#17552)
This commit is contained in:
198
superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
Normal file
198
superset-frontend/plugins/plugin-chart-table/src/buildQuery.ts
Normal file
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import {
|
||||
buildQueryContext,
|
||||
ensureIsArray,
|
||||
getMetricLabel,
|
||||
QueryMode,
|
||||
QueryObject,
|
||||
removeDuplicates,
|
||||
} from '@superset-ui/core';
|
||||
import { PostProcessingRule } from '@superset-ui/core/src/query/types/PostProcessing';
|
||||
import { BuildQuery } from '@superset-ui/core/src/chart/registries/ChartBuildQueryRegistrySingleton';
|
||||
import { TableChartFormData } from './types';
|
||||
import { updateExternalFormData } from './DataTable/utils/externalAPIs';
|
||||
|
||||
/**
|
||||
* Infer query mode from form data. If `all_columns` is set, then raw records mode,
|
||||
* otherwise defaults to aggregation mode.
|
||||
*
|
||||
* The same logic is used in `controlPanel` with control values as well.
|
||||
*/
|
||||
export function getQueryMode(formData: TableChartFormData) {
|
||||
const { query_mode: mode } = formData;
|
||||
if (mode === QueryMode.aggregate || mode === QueryMode.raw) {
|
||||
return mode;
|
||||
}
|
||||
const rawColumns = formData?.all_columns;
|
||||
const hasRawColumns = rawColumns && rawColumns.length > 0;
|
||||
return hasRawColumns ? QueryMode.raw : QueryMode.aggregate;
|
||||
}
|
||||
|
||||
const buildQuery: BuildQuery<TableChartFormData> = (
|
||||
formData: TableChartFormData,
|
||||
options,
|
||||
) => {
|
||||
const { percent_metrics: percentMetrics, order_desc: orderDesc = false } =
|
||||
formData;
|
||||
const queryMode = getQueryMode(formData);
|
||||
const sortByMetric = ensureIsArray(formData.timeseries_limit_metric)[0];
|
||||
let formDataCopy = formData;
|
||||
// never include time in raw records mode
|
||||
if (queryMode === QueryMode.raw) {
|
||||
formDataCopy = {
|
||||
...formData,
|
||||
include_time: false,
|
||||
};
|
||||
}
|
||||
|
||||
return buildQueryContext(formDataCopy, baseQueryObject => {
|
||||
let { metrics, orderby = [] } = baseQueryObject;
|
||||
let postProcessing: PostProcessingRule[] = [];
|
||||
|
||||
if (queryMode === QueryMode.aggregate) {
|
||||
metrics = metrics || [];
|
||||
// orverride orderby with timeseries metric when in aggregation mode
|
||||
if (sortByMetric) {
|
||||
orderby = [[sortByMetric, !orderDesc]];
|
||||
} else if (metrics?.length > 0) {
|
||||
// default to ordering by first metric in descending order
|
||||
// when no "sort by" metric is set (regargless if "SORT DESC" is set to true)
|
||||
orderby = [[metrics[0], false]];
|
||||
}
|
||||
// add postprocessing for percent metrics only when in aggregation mode
|
||||
if (percentMetrics && percentMetrics.length > 0) {
|
||||
const percentMetricLabels = removeDuplicates(
|
||||
percentMetrics.map(getMetricLabel),
|
||||
);
|
||||
metrics = removeDuplicates(
|
||||
metrics.concat(percentMetrics),
|
||||
getMetricLabel,
|
||||
);
|
||||
postProcessing = [
|
||||
{
|
||||
operation: 'contribution',
|
||||
options: {
|
||||
columns: percentMetricLabels,
|
||||
rename_columns: percentMetricLabels.map(x => `%${x}`),
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
const moreProps: Partial<QueryObject> = {};
|
||||
const ownState = options?.ownState ?? {};
|
||||
if (formDataCopy.server_pagination) {
|
||||
moreProps.row_limit =
|
||||
ownState.pageSize ?? formDataCopy.server_page_length;
|
||||
moreProps.row_offset =
|
||||
(ownState.currentPage ?? 0) * (ownState.pageSize ?? 0);
|
||||
}
|
||||
|
||||
let queryObject = {
|
||||
...baseQueryObject,
|
||||
orderby,
|
||||
metrics,
|
||||
post_processing: postProcessing,
|
||||
...moreProps,
|
||||
};
|
||||
|
||||
if (
|
||||
formData.server_pagination &&
|
||||
options?.extras?.cachedChanges?.[formData.slice_id] &&
|
||||
JSON.stringify(options?.extras?.cachedChanges?.[formData.slice_id]) !==
|
||||
JSON.stringify(queryObject.filters)
|
||||
) {
|
||||
queryObject = { ...queryObject, row_offset: 0 };
|
||||
updateExternalFormData(
|
||||
options?.hooks?.setDataMask,
|
||||
0,
|
||||
queryObject.row_limit ?? 0,
|
||||
);
|
||||
}
|
||||
// Because we use same buildQuery for all table on the page we need split them by id
|
||||
options?.hooks?.setCachedChanges({
|
||||
[formData.slice_id]: queryObject.filters,
|
||||
});
|
||||
|
||||
const extraQueries: QueryObject[] = [];
|
||||
if (
|
||||
metrics?.length &&
|
||||
formData.show_totals &&
|
||||
queryMode === QueryMode.aggregate
|
||||
) {
|
||||
extraQueries.push({
|
||||
...queryObject,
|
||||
columns: [],
|
||||
row_limit: 0,
|
||||
row_offset: 0,
|
||||
post_processing: [],
|
||||
});
|
||||
}
|
||||
|
||||
const interactiveGroupBy = formData.extra_form_data?.interactive_groupby;
|
||||
if (interactiveGroupBy && queryObject.columns) {
|
||||
queryObject.columns = [
|
||||
...new Set([...queryObject.columns, ...interactiveGroupBy]),
|
||||
];
|
||||
}
|
||||
|
||||
if (formData.server_pagination) {
|
||||
return [
|
||||
{ ...queryObject },
|
||||
{
|
||||
...queryObject,
|
||||
row_limit: 0,
|
||||
row_offset: 0,
|
||||
post_processing: [],
|
||||
is_rowcount: true,
|
||||
},
|
||||
...extraQueries,
|
||||
];
|
||||
}
|
||||
|
||||
return [queryObject, ...extraQueries];
|
||||
});
|
||||
};
|
||||
|
||||
// Use this closure to cache changing of external filters, if we have server pagination we need reset page to 0, after
|
||||
// external filter changed
|
||||
export const cachedBuildQuery = (): BuildQuery<TableChartFormData> => {
|
||||
let cachedChanges: any = {};
|
||||
const setCachedChanges = (newChanges: any) => {
|
||||
cachedChanges = { ...cachedChanges, ...newChanges };
|
||||
};
|
||||
|
||||
return (formData, options) =>
|
||||
buildQuery(
|
||||
{ ...formData },
|
||||
{
|
||||
extras: { cachedChanges },
|
||||
ownState: options?.ownState ?? {},
|
||||
hooks: {
|
||||
...options?.hooks,
|
||||
setDataMask: () => {},
|
||||
setCachedChanges,
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export default cachedBuildQuery();
|
||||
Reference in New Issue
Block a user