mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
feat: Drill by open in Explore (#23575)
This commit is contained in:
parent
9d2f43d312
commit
117360cd57
@ -27,14 +27,17 @@ import {
|
|||||||
} from './Operator';
|
} from './Operator';
|
||||||
import { TimeGranularity } from '../../time-format';
|
import { TimeGranularity } from '../../time-format';
|
||||||
|
|
||||||
interface BaseSimpleAdhocFilter {
|
interface BaseAdhocFilter {
|
||||||
expressionType: 'SIMPLE';
|
|
||||||
clause: 'WHERE' | 'HAVING';
|
clause: 'WHERE' | 'HAVING';
|
||||||
subject: string;
|
|
||||||
timeGrain?: TimeGranularity;
|
timeGrain?: TimeGranularity;
|
||||||
isExtra?: boolean;
|
isExtra?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BaseSimpleAdhocFilter extends BaseAdhocFilter {
|
||||||
|
expressionType: 'SIMPLE';
|
||||||
|
subject: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type UnaryAdhocFilter = BaseSimpleAdhocFilter & {
|
export type UnaryAdhocFilter = BaseSimpleAdhocFilter & {
|
||||||
operator: UnaryOperator;
|
operator: UnaryOperator;
|
||||||
};
|
};
|
||||||
@ -54,9 +57,8 @@ export type SimpleAdhocFilter =
|
|||||||
| BinaryAdhocFilter
|
| BinaryAdhocFilter
|
||||||
| SetAdhocFilter;
|
| SetAdhocFilter;
|
||||||
|
|
||||||
export interface FreeFormAdhocFilter {
|
export interface FreeFormAdhocFilter extends BaseAdhocFilter {
|
||||||
expressionType: 'SQL';
|
expressionType: 'SQL';
|
||||||
clause: 'WHERE' | 'HAVING';
|
|
||||||
sqlExpression: string;
|
sqlExpression: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,30 +40,10 @@ const fetchWithNoData = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const setup = (overrides: Record<string, any> = {}) => {
|
const setup = (overrides: Record<string, any> = {}) =>
|
||||||
const props = {
|
render(<DrillByChart formData={{ ...chart.form_data, ...overrides }} />, {
|
||||||
column: { column_name: 'state' },
|
|
||||||
formData: { ...chart.form_data, viz_type: 'pie' },
|
|
||||||
groupbyFieldName: 'groupby',
|
|
||||||
...overrides,
|
|
||||||
};
|
|
||||||
return render(
|
|
||||||
<DrillByChart
|
|
||||||
filters={[
|
|
||||||
{
|
|
||||||
col: 'gender',
|
|
||||||
op: '==',
|
|
||||||
val: 'boy',
|
|
||||||
formattedVal: 'boy',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
{...props}
|
|
||||||
/>,
|
|
||||||
{
|
|
||||||
useRedux: true,
|
useRedux: true,
|
||||||
},
|
});
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const waitForRender = (overrides: Record<string, any> = {}) =>
|
const waitForRender = (overrides: Record<string, any> = {}) =>
|
||||||
waitFor(() => setup(overrides));
|
waitFor(() => setup(overrides));
|
||||||
|
@ -17,52 +17,20 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import {
|
import { BaseFormData, Behavior, css, SuperChart } from '@superset-ui/core';
|
||||||
Behavior,
|
|
||||||
BinaryQueryObjectFilterClause,
|
|
||||||
Column,
|
|
||||||
css,
|
|
||||||
SuperChart,
|
|
||||||
} from '@superset-ui/core';
|
|
||||||
import { simpleFilterToAdhoc } from 'src/utils/simpleFilterToAdhoc';
|
|
||||||
import { getChartDataRequest } from 'src/components/Chart/chartAction';
|
import { getChartDataRequest } from 'src/components/Chart/chartAction';
|
||||||
import Loading from 'src/components/Loading';
|
import Loading from 'src/components/Loading';
|
||||||
|
|
||||||
interface DrillByChartProps {
|
interface DrillByChartProps {
|
||||||
column?: Column;
|
formData: BaseFormData & { [key: string]: any };
|
||||||
filters?: BinaryQueryObjectFilterClause[];
|
|
||||||
formData: { [key: string]: any; viz_type: string };
|
|
||||||
groupbyFieldName?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DrillByChart({
|
export default function DrillByChart({ formData }: DrillByChartProps) {
|
||||||
column,
|
|
||||||
filters,
|
|
||||||
formData,
|
|
||||||
groupbyFieldName = 'groupby',
|
|
||||||
}: DrillByChartProps) {
|
|
||||||
let updatedFormData = formData;
|
|
||||||
let groupbyField: any = [];
|
|
||||||
const [chartDataResult, setChartDataResult] = useState();
|
const [chartDataResult, setChartDataResult] = useState();
|
||||||
|
|
||||||
if (column) {
|
|
||||||
groupbyField = Array.isArray(formData[groupbyFieldName])
|
|
||||||
? [column.column_name]
|
|
||||||
: column.column_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filters) {
|
|
||||||
const adhocFilters = filters.map(filter => simpleFilterToAdhoc(filter));
|
|
||||||
updatedFormData = {
|
|
||||||
...formData,
|
|
||||||
adhoc_filters: [...formData.adhoc_filters, ...adhocFilters],
|
|
||||||
[groupbyFieldName]: groupbyField,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getChartDataRequest({
|
getChartDataRequest({
|
||||||
formData: updatedFormData,
|
formData,
|
||||||
}).then(({ json }) => {
|
}).then(({ json }) => {
|
||||||
setChartDataResult(json.result);
|
setChartDataResult(json.result);
|
||||||
});
|
});
|
||||||
@ -81,7 +49,7 @@ export default function DrillByChart({
|
|||||||
behaviors={[Behavior.INTERACTIVE_CHART]}
|
behaviors={[Behavior.INTERACTIVE_CHART]}
|
||||||
chartType={formData.viz_type}
|
chartType={formData.viz_type}
|
||||||
enableNoResults
|
enableNoResults
|
||||||
formData={updatedFormData}
|
formData={formData}
|
||||||
queriesData={chartDataResult}
|
queriesData={chartDataResult}
|
||||||
height="100%"
|
height="100%"
|
||||||
width="100%"
|
width="100%"
|
||||||
|
@ -18,23 +18,26 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import fetchMock from 'fetch-mock';
|
||||||
|
import { omit, isUndefined, omitBy } from 'lodash';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import { waitFor } from '@testing-library/react';
|
||||||
import { render, screen } from 'spec/helpers/testing-library';
|
import { render, screen } from 'spec/helpers/testing-library';
|
||||||
import chartQueries, { sliceId } from 'spec/fixtures/mockChartQueries';
|
import chartQueries, { sliceId } from 'spec/fixtures/mockChartQueries';
|
||||||
import mockState from 'spec/fixtures/mockState';
|
import mockState from 'spec/fixtures/mockState';
|
||||||
import fetchMock from 'fetch-mock';
|
import { DashboardPageIdContext } from 'src/dashboard/containers/DashboardPage';
|
||||||
import DrillByModal from './DrillByModal';
|
import DrillByModal from './DrillByModal';
|
||||||
|
|
||||||
const CHART_DATA_ENDPOINT =
|
const CHART_DATA_ENDPOINT = 'glob:*/api/v1/chart/data*';
|
||||||
'glob:*api/v1/chart/data?form_data=%7B%22slice_id%22%3A18%7D';
|
const FORM_DATA_KEY_ENDPOINT = 'glob:*/api/v1/explore/form_data';
|
||||||
|
|
||||||
fetchMock.post(CHART_DATA_ENDPOINT, { body: {} }, {});
|
|
||||||
|
|
||||||
const { form_data: formData } = chartQueries[sliceId];
|
const { form_data: formData } = chartQueries[sliceId];
|
||||||
const { slice_name: chartName } = formData;
|
const { slice_name: chartName } = formData;
|
||||||
const drillByModalState = {
|
const drillByModalState = {
|
||||||
...mockState,
|
...mockState,
|
||||||
dashboardLayout: {
|
dashboardLayout: {
|
||||||
|
past: [],
|
||||||
|
present: {
|
||||||
CHART_ID: {
|
CHART_ID: {
|
||||||
id: 'CHART_ID',
|
id: 'CHART_ID',
|
||||||
meta: {
|
meta: {
|
||||||
@ -43,6 +46,8 @@ const drillByModalState = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
future: [],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const dataset = {
|
const dataset = {
|
||||||
changed_on_humanized: '01-01-2001',
|
changed_on_humanized: '01-01-2001',
|
||||||
@ -56,12 +61,13 @@ const dataset = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const renderModal = async (state?: object) => {
|
|
||||||
|
const renderModal = async () => {
|
||||||
const DrillByModalWrapper = () => {
|
const DrillByModalWrapper = () => {
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<DashboardPageIdContext.Provider value="1">
|
||||||
<button type="button" onClick={() => setShowModal(true)}>
|
<button type="button" onClick={() => setShowModal(true)}>
|
||||||
Show modal
|
Show modal
|
||||||
</button>
|
</button>
|
||||||
@ -71,23 +77,29 @@ const renderModal = async (state?: object) => {
|
|||||||
onHideModal={() => setShowModal(false)}
|
onHideModal={() => setShowModal(false)}
|
||||||
dataset={dataset}
|
dataset={dataset}
|
||||||
/>
|
/>
|
||||||
</>
|
</DashboardPageIdContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
render(<DrillByModalWrapper />, {
|
render(<DrillByModalWrapper />, {
|
||||||
useDnd: true,
|
useDnd: true,
|
||||||
useRedux: true,
|
useRedux: true,
|
||||||
useRouter: true,
|
useRouter: true,
|
||||||
initialState: state,
|
initialState: drillByModalState,
|
||||||
});
|
});
|
||||||
|
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Show modal' }));
|
userEvent.click(screen.getByRole('button', { name: 'Show modal' }));
|
||||||
await screen.findByRole('dialog', { name: `Drill by: ${chartName}` });
|
await screen.findByRole('dialog', { name: `Drill by: ${chartName}` });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fetchMock
|
||||||
|
.post(CHART_DATA_ENDPOINT, { body: {} }, {})
|
||||||
|
.post(FORM_DATA_KEY_ENDPOINT, { key: '123' });
|
||||||
|
});
|
||||||
afterEach(fetchMock.restore);
|
afterEach(fetchMock.restore);
|
||||||
|
|
||||||
test('should render the title', async () => {
|
test('should render the title', async () => {
|
||||||
await renderModal(drillByModalState);
|
await renderModal();
|
||||||
expect(screen.getByText(`Drill by: ${chartName}`)).toBeInTheDocument();
|
expect(screen.getByText(`Drill by: ${chartName}`)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -105,3 +117,30 @@ test('should close the modal', async () => {
|
|||||||
userEvent.click(screen.getAllByRole('button', { name: 'Close' })[1]);
|
userEvent.click(screen.getAllByRole('button', { name: 'Close' })[1]);
|
||||||
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should generate Explore url', async () => {
|
||||||
|
await renderModal();
|
||||||
|
await waitFor(() => fetchMock.called(FORM_DATA_KEY_ENDPOINT));
|
||||||
|
const expectedRequestPayload = {
|
||||||
|
form_data: {
|
||||||
|
...omitBy(
|
||||||
|
omit(formData, ['slice_id', 'slice_name', 'dashboards']),
|
||||||
|
isUndefined,
|
||||||
|
),
|
||||||
|
slice_id: 0,
|
||||||
|
},
|
||||||
|
datasource_id: Number(formData.datasource.split('__')[0]),
|
||||||
|
datasource_type: formData.datasource.split('__')[1],
|
||||||
|
};
|
||||||
|
|
||||||
|
const parsedRequestPayload = JSON.parse(
|
||||||
|
fetchMock.lastCall()?.[1]?.body as string,
|
||||||
|
);
|
||||||
|
parsedRequestPayload.form_data = JSON.parse(parsedRequestPayload.form_data);
|
||||||
|
|
||||||
|
expect(parsedRequestPayload).toEqual(expectedRequestPayload);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await screen.findByRole('link', { name: 'Edit chart' }),
|
||||||
|
).toHaveAttribute('href', '/explore/?form_data_key=123&dashboard_page_id=1');
|
||||||
|
});
|
||||||
|
@ -17,31 +17,62 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
|
BaseFormData,
|
||||||
BinaryQueryObjectFilterClause,
|
BinaryQueryObjectFilterClause,
|
||||||
Column,
|
Column,
|
||||||
css,
|
css,
|
||||||
|
ensureIsArray,
|
||||||
t,
|
t,
|
||||||
useTheme,
|
useTheme,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import Modal from 'src/components/Modal';
|
import Modal from 'src/components/Modal';
|
||||||
import Button from 'src/components/Button';
|
import Button from 'src/components/Button';
|
||||||
import { useSelector } from 'react-redux';
|
|
||||||
import { DashboardLayout, RootState } from 'src/dashboard/types';
|
import { DashboardLayout, RootState } from 'src/dashboard/types';
|
||||||
|
import { DashboardPageIdContext } from 'src/dashboard/containers/DashboardPage';
|
||||||
|
import { postFormData } from 'src/explore/exploreUtils/formData';
|
||||||
|
import { noOp } from 'src/utils/common';
|
||||||
|
import { simpleFilterToAdhoc } from 'src/utils/simpleFilterToAdhoc';
|
||||||
import { useDatasetMetadataBar } from 'src/features/datasets/metadataBar/useDatasetMetadataBar';
|
import { useDatasetMetadataBar } from 'src/features/datasets/metadataBar/useDatasetMetadataBar';
|
||||||
import { Dataset } from '../types';
|
import { Dataset } from '../types';
|
||||||
import DrillByChart from './DrillByChart';
|
import DrillByChart from './DrillByChart';
|
||||||
|
|
||||||
interface ModalFooterProps {
|
interface ModalFooterProps {
|
||||||
exploreChart: () => void;
|
formData: BaseFormData;
|
||||||
closeModal?: () => void;
|
closeModal?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ModalFooter = ({ exploreChart, closeModal }: ModalFooterProps) => (
|
const ModalFooter = ({ formData, closeModal }: ModalFooterProps) => {
|
||||||
|
const [url, setUrl] = useState('');
|
||||||
|
const dashboardPageId = useContext(DashboardPageIdContext);
|
||||||
|
const [datasource_id, datasource_type] = formData.datasource.split('__');
|
||||||
|
useEffect(() => {
|
||||||
|
postFormData(Number(datasource_id), datasource_type, formData, 0)
|
||||||
|
.then(key => {
|
||||||
|
setUrl(
|
||||||
|
`/explore/?form_data_key=${key}&dashboard_page_id=${dashboardPageId}`,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
}, [dashboardPageId, datasource_id, datasource_type, formData]);
|
||||||
|
return (
|
||||||
<>
|
<>
|
||||||
<Button buttonStyle="secondary" buttonSize="small" onClick={exploreChart}>
|
<Button buttonStyle="secondary" buttonSize="small" onClick={noOp}>
|
||||||
|
<Link
|
||||||
|
css={css`
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
to={url}
|
||||||
|
>
|
||||||
{t('Edit chart')}
|
{t('Edit chart')}
|
||||||
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
buttonStyle="primary"
|
buttonStyle="primary"
|
||||||
@ -53,11 +84,12 @@ const ModalFooter = ({ exploreChart, closeModal }: ModalFooterProps) => (
|
|||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
interface DrillByModalProps {
|
interface DrillByModalProps {
|
||||||
column?: Column;
|
column?: Column;
|
||||||
filters?: BinaryQueryObjectFilterClause[];
|
filters?: BinaryQueryObjectFilterClause[];
|
||||||
formData: { [key: string]: any; viz_type: string };
|
formData: BaseFormData & { [key: string]: any };
|
||||||
groupbyFieldName?: string;
|
groupbyFieldName?: string;
|
||||||
onHideModal: () => void;
|
onHideModal: () => void;
|
||||||
showModal: boolean;
|
showModal: boolean;
|
||||||
@ -68,7 +100,7 @@ export default function DrillByModal({
|
|||||||
column,
|
column,
|
||||||
filters,
|
filters,
|
||||||
formData,
|
formData,
|
||||||
groupbyFieldName,
|
groupbyFieldName = 'groupby',
|
||||||
onHideModal,
|
onHideModal,
|
||||||
showModal,
|
showModal,
|
||||||
dataset,
|
dataset,
|
||||||
@ -82,7 +114,32 @@ export default function DrillByModal({
|
|||||||
);
|
);
|
||||||
const chartName =
|
const chartName =
|
||||||
chartLayoutItem?.meta.sliceNameOverride || chartLayoutItem?.meta.sliceName;
|
chartLayoutItem?.meta.sliceNameOverride || chartLayoutItem?.meta.sliceName;
|
||||||
const exploreChart = () => {};
|
|
||||||
|
const updatedFormData = useMemo(() => {
|
||||||
|
let updatedFormData = { ...formData };
|
||||||
|
if (column) {
|
||||||
|
updatedFormData[groupbyFieldName] = Array.isArray(
|
||||||
|
formData[groupbyFieldName],
|
||||||
|
)
|
||||||
|
? [column.column_name]
|
||||||
|
: column.column_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filters) {
|
||||||
|
const adhocFilters = filters.map(filter => simpleFilterToAdhoc(filter));
|
||||||
|
updatedFormData = {
|
||||||
|
...updatedFormData,
|
||||||
|
adhoc_filters: [
|
||||||
|
...ensureIsArray(formData.adhoc_filters),
|
||||||
|
...adhocFilters,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
updatedFormData.slice_id = 0;
|
||||||
|
delete updatedFormData.slice_name;
|
||||||
|
delete updatedFormData.dashboards;
|
||||||
|
return updatedFormData;
|
||||||
|
}, [column, filters, formData, groupbyFieldName]);
|
||||||
|
|
||||||
const { metadataBar } = useDatasetMetadataBar({ dataset });
|
const { metadataBar } = useDatasetMetadataBar({ dataset });
|
||||||
return (
|
return (
|
||||||
@ -95,7 +152,7 @@ export default function DrillByModal({
|
|||||||
show={showModal}
|
show={showModal}
|
||||||
onHide={onHideModal ?? (() => null)}
|
onHide={onHideModal ?? (() => null)}
|
||||||
title={t('Drill by: %s', chartName)}
|
title={t('Drill by: %s', chartName)}
|
||||||
footer={<ModalFooter exploreChart={exploreChart} />}
|
footer={<ModalFooter formData={updatedFormData} />}
|
||||||
responsive
|
responsive
|
||||||
resizable
|
resizable
|
||||||
resizableConfig={{
|
resizableConfig={{
|
||||||
@ -118,12 +175,7 @@ export default function DrillByModal({
|
|||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{metadataBar}
|
{metadataBar}
|
||||||
<DrillByChart
|
<DrillByChart formData={updatedFormData} />
|
||||||
column={column}
|
|
||||||
filters={filters}
|
|
||||||
formData={formData}
|
|
||||||
groupbyFieldName={groupbyFieldName}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
@ -33,6 +33,17 @@ import {
|
|||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { simpleFilterToAdhoc } from 'src/utils/simpleFilterToAdhoc';
|
import { simpleFilterToAdhoc } from 'src/utils/simpleFilterToAdhoc';
|
||||||
|
|
||||||
|
const removeExtraFieldForNewCharts = (
|
||||||
|
filters: AdhocFilter[],
|
||||||
|
isNewChart: boolean,
|
||||||
|
) =>
|
||||||
|
filters.map(filter => {
|
||||||
|
if (filter.isExtra) {
|
||||||
|
return { ...filter, isExtra: !isNewChart };
|
||||||
|
}
|
||||||
|
return filter;
|
||||||
|
});
|
||||||
|
|
||||||
const removeAdhocFilterDuplicates = (filters: AdhocFilter[]) => {
|
const removeAdhocFilterDuplicates = (filters: AdhocFilter[]) => {
|
||||||
const isDuplicate = (
|
const isDuplicate = (
|
||||||
adhocFilter: AdhocFilter,
|
adhocFilter: AdhocFilter,
|
||||||
@ -103,7 +114,6 @@ const mergeNativeFiltersToFormData = (
|
|||||||
) => {
|
) => {
|
||||||
const nativeFiltersData: JsonObject = {};
|
const nativeFiltersData: JsonObject = {};
|
||||||
const extraFormData = dashboardFormData.extra_form_data || {};
|
const extraFormData = dashboardFormData.extra_form_data || {};
|
||||||
|
|
||||||
Object.entries(EXTRA_FORM_DATA_OVERRIDE_REGULAR_MAPPINGS).forEach(
|
Object.entries(EXTRA_FORM_DATA_OVERRIDE_REGULAR_MAPPINGS).forEach(
|
||||||
([srcKey, targetKey]) => {
|
([srcKey, targetKey]) => {
|
||||||
const val = extraFormData[srcKey];
|
const val = extraFormData[srcKey];
|
||||||
@ -193,7 +203,8 @@ export const getFormDataWithDashboardContext = (
|
|||||||
.reduce(
|
.reduce(
|
||||||
(acc, key) => ({
|
(acc, key) => ({
|
||||||
...acc,
|
...acc,
|
||||||
[key]: applyTimeRangeFilters(
|
[key]: removeExtraFieldForNewCharts(
|
||||||
|
applyTimeRangeFilters(
|
||||||
dashboardContextFormData,
|
dashboardContextFormData,
|
||||||
removeAdhocFilterDuplicates([
|
removeAdhocFilterDuplicates([
|
||||||
...ensureIsArray(exploreFormData[key]),
|
...ensureIsArray(exploreFormData[key]),
|
||||||
@ -201,6 +212,8 @@ export const getFormDataWithDashboardContext = (
|
|||||||
...ensureIsArray(nativeFiltersData[key]),
|
...ensureIsArray(nativeFiltersData[key]),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
|
exploreFormData.slice_id === 0,
|
||||||
|
),
|
||||||
}),
|
}),
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user