chore: Remove Cross Filter scoping modal (#23216)
This commit is contained in:
parent
b99d38dfef
commit
82cadccced
|
|
@ -42,7 +42,8 @@ describe('Dashboard load', () => {
|
|||
cy.get('#app-menu').should('not.exist');
|
||||
});
|
||||
|
||||
it('should send log data', () => {
|
||||
// TODO flaky test. skipping to unblock CI
|
||||
it.skip('should send log data', () => {
|
||||
interceptLog();
|
||||
cy.visit(WORLD_HEALTH_DASHBOARD);
|
||||
cy.wait('@logs', { timeout: 15000 });
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ KIND, either express or implied. See the License for the
|
|||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.59961 17.8C9.59961 18.3523 10.0473 18.8 10.5996 18.8H13.3996C13.9519 18.8 14.3996 18.3523 14.3996 17.8V17.8C14.3996 17.2477 13.9519 16.8 13.3996 16.8H10.5996C10.0473 16.8 9.59961 17.2477 9.59961 17.8V17.8ZM2.59961 4C2.04732 4 1.59961 4.44772 1.59961 5V5C1.59961 5.55228 2.04732 6 2.59961 6H21.3996C21.9519 6 22.3996 5.55228 22.3996 5V5C22.3996 4.44772 21.9519 4 21.3996 4H2.59961ZM6.39961 11.4C6.39961 11.9523 6.84732 12.4 7.39961 12.4H16.5996C17.1519 12.4 17.5996 11.9523 17.5996 11.4V11.4C17.5996 10.8477 17.1519 10.4 16.5996 10.4H7.39961C6.84732 10.4 6.39961 10.8477 6.39961 11.4V11.4Z" fill="currentColor"/>
|
||||
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.69241 18.976C9.69241 19.895 10.417 20.64 11.3109 20.64H12.9293C13.8232 20.64 14.5478 19.895 14.5478 18.976C14.5478 18.057 13.8232 17.312 12.9293 17.312H11.3109C10.417 17.312 9.69241 18.057 9.69241 18.976ZM3.21856 4C2.32472 4 1.6001 4.74501 1.6001 5.664C1.6001 6.58299 2.32472 7.328 3.21856 7.328H21.0216C21.9155 7.328 22.6401 6.58299 22.6401 5.664C22.6401 4.74501 21.9155 4 21.0216 4H3.21856ZM6.45548 12.32C6.45548 13.239 7.1801 13.984 8.07394 13.984H16.1663C17.0601 13.984 17.7847 13.239 17.7847 12.32C17.7847 11.401 17.0601 10.656 16.1663 10.656H8.07394C7.1801 10.656 6.45548 11.401 6.45548 12.32Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
|
@ -1,60 +0,0 @@
|
|||
/**
|
||||
* 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 React from 'react';
|
||||
import { render } from 'spec/helpers/testing-library';
|
||||
import FilterScope from 'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope';
|
||||
import CrossFilterScopingForm from '.';
|
||||
|
||||
jest.mock(
|
||||
'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope',
|
||||
() => jest.fn(() => null),
|
||||
);
|
||||
|
||||
const createProps = () => {
|
||||
const getFieldValue = jest.fn();
|
||||
getFieldValue.mockImplementation(name => name);
|
||||
return {
|
||||
chartId: 123,
|
||||
scope: 'Scope',
|
||||
form: { getFieldValue },
|
||||
};
|
||||
};
|
||||
|
||||
test('Should send correct props', () => {
|
||||
const props = createProps();
|
||||
render(<CrossFilterScopingForm {...(props as any)} />);
|
||||
|
||||
expect(FilterScope).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
chartId: 123,
|
||||
filterScope: 'Scope',
|
||||
formFilterScope: 'scope',
|
||||
formScopingType: 'scoping',
|
||||
}),
|
||||
{},
|
||||
);
|
||||
});
|
||||
|
||||
test('Should get correct fields', () => {
|
||||
const props = createProps();
|
||||
render(<CrossFilterScopingForm {...(props as any)} />);
|
||||
expect(props.form.getFieldValue).toBeCalledTimes(2);
|
||||
expect(props.form.getFieldValue).toHaveBeenNthCalledWith(1, 'scope');
|
||||
expect(props.form.getFieldValue).toHaveBeenNthCalledWith(2, 'scoping');
|
||||
});
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
* 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 React, { FC } from 'react';
|
||||
import { FormInstance } from 'src/components';
|
||||
import { NativeFilterScope } from '@superset-ui/core';
|
||||
import FilterScope from 'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/FilterScope';
|
||||
import { setCrossFilterFieldValues } from 'src/dashboard/components/CrossFilterScopingModal/utils';
|
||||
import { useForceUpdate } from 'src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigForm/utils';
|
||||
import { CrossFilterScopingFormType } from 'src/dashboard/components/CrossFilterScopingModal/types';
|
||||
|
||||
type CrossFilterScopingFormProps = {
|
||||
chartId: number;
|
||||
scope: NativeFilterScope;
|
||||
form: FormInstance<CrossFilterScopingFormType>;
|
||||
};
|
||||
|
||||
const CrossFilterScopingForm: FC<CrossFilterScopingFormProps> = ({
|
||||
form,
|
||||
scope,
|
||||
chartId,
|
||||
}) => {
|
||||
const forceUpdate = useForceUpdate();
|
||||
const formScope = form.getFieldValue('scope');
|
||||
const formScoping = form.getFieldValue('scoping');
|
||||
return (
|
||||
<FilterScope
|
||||
updateFormValues={(values: any) => {
|
||||
setCrossFilterFieldValues(form, {
|
||||
...values,
|
||||
});
|
||||
}}
|
||||
filterScope={scope}
|
||||
chartId={chartId}
|
||||
formFilterScope={formScope}
|
||||
forceUpdate={forceUpdate}
|
||||
formScopingType={formScoping}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CrossFilterScopingForm;
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
/**
|
||||
* 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 { t } from '@superset-ui/core';
|
||||
import React, { FC } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { StyledModal } from 'src/components/Modal';
|
||||
import Button from 'src/components/Button';
|
||||
import { AntdForm } from 'src/components';
|
||||
import { setChartConfiguration } from 'src/dashboard/actions/dashboardInfo';
|
||||
import { ChartConfiguration } from 'src/dashboard/reducers/types';
|
||||
import { ChartsState, Layout, RootState } from 'src/dashboard/types';
|
||||
import { getChartIdsInFilterScope } from 'src/dashboard/util/getChartIdsInFilterScope';
|
||||
import CrossFilterScopingForm from './CrossFilterScopingForm';
|
||||
import { CrossFilterScopingFormType } from './types';
|
||||
import { StyledForm } from '../nativeFilters/FiltersConfigModal/FiltersConfigModal';
|
||||
|
||||
type CrossFilterScopingModalProps = {
|
||||
chartId: number;
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
const CrossFilterScopingModal: FC<CrossFilterScopingModalProps> = ({
|
||||
isOpen,
|
||||
chartId,
|
||||
onClose,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [form] = AntdForm.useForm<CrossFilterScopingFormType>();
|
||||
const chartConfig = useSelector<any, ChartConfiguration>(
|
||||
({ dashboardInfo }) => dashboardInfo?.metadata?.chart_configuration,
|
||||
);
|
||||
const charts = useSelector<RootState, ChartsState>(state => state.charts);
|
||||
const layout = useSelector<RootState, Layout>(
|
||||
state => state.dashboardLayout.present,
|
||||
);
|
||||
const scope = chartConfig?.[chartId]?.crossFilters?.scope;
|
||||
const handleSave = () => {
|
||||
const chartsInScope = getChartIdsInFilterScope(
|
||||
form.getFieldValue('scope'),
|
||||
charts,
|
||||
layout,
|
||||
);
|
||||
|
||||
dispatch(
|
||||
setChartConfiguration({
|
||||
...chartConfig,
|
||||
[chartId]: {
|
||||
id: chartId,
|
||||
crossFilters: { scope: form.getFieldValue('scope'), chartsInScope },
|
||||
},
|
||||
}),
|
||||
);
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledModal
|
||||
visible={isOpen}
|
||||
maskClosable={false}
|
||||
title={t('Cross Filter Scoping')}
|
||||
width="55%"
|
||||
destroyOnClose
|
||||
onCancel={onClose}
|
||||
onOk={handleSave}
|
||||
centered
|
||||
data-test="cross-filter-scoping-modal"
|
||||
footer={
|
||||
<>
|
||||
<Button
|
||||
key="cancel"
|
||||
buttonStyle="secondary"
|
||||
data-test="cross-filter-scoping-modal-cancel-button"
|
||||
onClick={onClose}
|
||||
>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
key="submit"
|
||||
buttonStyle="primary"
|
||||
onClick={handleSave}
|
||||
data-test="cross-filter-scoping-modal-save-button"
|
||||
>
|
||||
{t('Save')}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<StyledForm preserve={false} form={form} layout="vertical">
|
||||
<CrossFilterScopingForm form={form} scope={scope} chartId={chartId} />
|
||||
</StyledForm>
|
||||
</StyledModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CrossFilterScopingModal;
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/**
|
||||
* 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 { NativeFilterScope } from '@superset-ui/core';
|
||||
|
||||
export type CrossFilterScopingFormType = {
|
||||
scope: NativeFilterScope;
|
||||
};
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/**
|
||||
* 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 { FormInstance } from 'src/components';
|
||||
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const setCrossFilterFieldValues = (
|
||||
form: FormInstance,
|
||||
values: object,
|
||||
) => {
|
||||
form.setFieldsValue({
|
||||
...values,
|
||||
});
|
||||
};
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/**
|
||||
* 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 { setCrossFilterFieldValues } from '.';
|
||||
|
||||
test('setValues', () => {
|
||||
const from = { setFieldsValue: jest.fn() };
|
||||
const values = {
|
||||
val01: 'val01',
|
||||
val02: 'val02',
|
||||
val03: 'val03',
|
||||
val04: 'val04',
|
||||
};
|
||||
setCrossFilterFieldValues(from as any, values);
|
||||
|
||||
expect(from.setFieldsValue).toBeCalledTimes(1);
|
||||
expect(from.setFieldsValue).toBeCalledWith(values);
|
||||
});
|
||||
|
|
@ -105,9 +105,9 @@ describe('FiltersBadge', () => {
|
|||
store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
|
||||
const wrapper = setup(store);
|
||||
expect(wrapper.find('DetailsPanelPopover')).toExist();
|
||||
expect(wrapper.find('[data-test="applied-filter-count"]')).toHaveText(
|
||||
'1',
|
||||
);
|
||||
expect(
|
||||
wrapper.find('[data-test="applied-filter-count"] .current'),
|
||||
).toHaveText('1');
|
||||
expect(wrapper.find('WarningFilled')).not.toExist();
|
||||
});
|
||||
});
|
||||
|
|
@ -153,9 +153,9 @@ describe('FiltersBadge', () => {
|
|||
store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
|
||||
const wrapper = setup(store);
|
||||
expect(wrapper.find('DetailsPanelPopover')).toExist();
|
||||
expect(wrapper.find('[data-test="applied-filter-count"]')).toHaveText(
|
||||
'1',
|
||||
);
|
||||
expect(
|
||||
wrapper.find('[data-test="applied-filter-count"] .current'),
|
||||
).toHaveText('1');
|
||||
expect(wrapper.find('WarningFilled')).not.toExist();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { uniqWith } from 'lodash';
|
||||
import cx from 'classnames';
|
||||
import { DataMaskStateWithId, Filters } from '@superset-ui/core';
|
||||
import { DataMaskStateWithId, Filters, styled } from '@superset-ui/core';
|
||||
import Icons from 'src/components/Icons';
|
||||
import { usePrevious } from 'src/hooks/usePrevious';
|
||||
import { setDirectPathToChild } from 'src/dashboard/actions/dashboardState';
|
||||
import Badge from 'src/components/Badge';
|
||||
import DetailsPanelPopover from './DetailsPanel';
|
||||
import { Pill } from './Styles';
|
||||
import {
|
||||
Indicator,
|
||||
IndicatorStatus,
|
||||
|
|
@ -43,6 +43,48 @@ export interface FiltersBadgeProps {
|
|||
chartId: number;
|
||||
}
|
||||
|
||||
const StyledFilterCount = styled.div`
|
||||
${({ theme }) => `
|
||||
display: flex;
|
||||
justify-items: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
margin-right: ${theme.gridUnit}px;
|
||||
padding-left: ${theme.gridUnit * 2}px;
|
||||
padding-right: ${theme.gridUnit * 2}px;
|
||||
background: ${theme.colors.grayscale.light4};
|
||||
border-radius: 4px;
|
||||
height: 100%;
|
||||
.anticon {
|
||||
vertical-align: middle;
|
||||
color: ${theme.colors.grayscale.base};
|
||||
&:hover {
|
||||
color: ${theme.colors.grayscale.light1}
|
||||
}
|
||||
}
|
||||
|
||||
.incompatible-count {
|
||||
font-size: ${theme.typography.sizes.s}px;
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
const StyledBadge = styled(Badge)`
|
||||
${({ theme }) => `
|
||||
vertical-align: middle;
|
||||
margin-left: ${theme.gridUnit * 2}px;
|
||||
&>sup {
|
||||
padding: 0 ${theme.gridUnit}px;
|
||||
min-width: ${theme.gridUnit * 4}px;
|
||||
height: ${theme.gridUnit * 4}px;
|
||||
line-height: 1.5;
|
||||
font-weight: ${theme.typography.weights.medium};
|
||||
font-size: ${theme.typography.sizes.s - 1}px;
|
||||
box-shadow: none;
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
const sortByStatus = (indicators: Indicator[]): Indicator[] => {
|
||||
const statuses = [
|
||||
IndicatorStatus.Applied,
|
||||
|
|
@ -222,17 +264,20 @@ export const FiltersBadge = ({ chartId }: FiltersBadgeProps) => {
|
|||
appliedIndicators={appliedIndicators}
|
||||
onHighlightFilterSource={onHighlightFilterSource}
|
||||
>
|
||||
<Pill
|
||||
<StyledFilterCount
|
||||
className={cx(
|
||||
'filter-counts',
|
||||
!!appliedCrossFilterIndicators.length && 'has-cross-filters',
|
||||
)}
|
||||
>
|
||||
<Icons.Filter iconSize="m" />
|
||||
<span data-test="applied-filter-count">
|
||||
{appliedIndicators.length + appliedCrossFilterIndicators.length}
|
||||
</span>
|
||||
</Pill>
|
||||
<StyledBadge
|
||||
data-test="applied-filter-count"
|
||||
className="applied-count"
|
||||
count={appliedIndicators.length + appliedCrossFilterIndicators.length}
|
||||
showZero
|
||||
/>
|
||||
</StyledFilterCount>
|
||||
</DetailsPanelPopover>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ import React, {
|
|||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { css, styled, SupersetTheme, t } from '@superset-ui/core';
|
||||
import { css, styled, t } from '@superset-ui/core';
|
||||
import { useUiConfig } from 'src/components/UiConfigContext';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useSelector } from 'react-redux';
|
||||
import EditableTitle from 'src/components/EditableTitle';
|
||||
import SliceHeaderControls, {
|
||||
SliceHeaderControlsProps,
|
||||
|
|
@ -37,8 +37,6 @@ import Icons from 'src/components/Icons';
|
|||
import { RootState } from 'src/dashboard/types';
|
||||
import { getSliceHeaderTooltip } from 'src/dashboard/util/getSliceHeaderTooltip';
|
||||
import { DashboardPageIdContext } from 'src/dashboard/containers/DashboardPage';
|
||||
import { clearDataMask } from 'src/dataMask/actions';
|
||||
import { getFilterValueForDisplay } from '../nativeFilters/FilterBar/FilterSets/utils';
|
||||
|
||||
type SliceHeaderProps = SliceHeaderControlsProps & {
|
||||
innerRef?: string;
|
||||
|
|
@ -56,11 +54,12 @@ type SliceHeaderProps = SliceHeaderControlsProps & {
|
|||
|
||||
const annotationsLoading = t('Annotation layers are still loading.');
|
||||
const annotationsError = t('One ore more annotation layers failed loading.');
|
||||
const CrossFilterIcon = styled(Icons.CursorTarget)`
|
||||
cursor: pointer;
|
||||
color: ${({ theme }) => theme.colors.primary.base};
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
const CrossFilterIcon = styled(Icons.ApartmentOutlined)`
|
||||
${({ theme }) => `
|
||||
cursor: default;
|
||||
color: ${theme.colors.primary.base};
|
||||
line-height: 1.8;
|
||||
`}
|
||||
`;
|
||||
|
||||
const ChartHeaderStyles = styled.div`
|
||||
|
|
@ -89,6 +88,8 @@ const ChartHeaderStyles = styled.div`
|
|||
|
||||
& > .header-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
|
||||
& > * {
|
||||
margin-left: ${theme.gridUnit * 2}px;
|
||||
|
|
@ -159,7 +160,6 @@ const SliceHeader: FC<SliceHeaderProps> = ({
|
|||
width,
|
||||
height,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const uiConfig = useUiConfig();
|
||||
const dashboardPageId = useContext(DashboardPageIdContext);
|
||||
const [headerTooltip, setHeaderTooltip] = useState<ReactNode | null>(null);
|
||||
|
|
@ -241,25 +241,11 @@ const SliceHeader: FC<SliceHeaderProps> = ({
|
|||
{crossFilterValue && (
|
||||
<Tooltip
|
||||
placement="top"
|
||||
title={
|
||||
<div>
|
||||
<span>{t('Emitted values: ')}</span>
|
||||
<span>{getFilterValueForDisplay(crossFilterValue)}</span>
|
||||
<div
|
||||
css={(theme: SupersetTheme) =>
|
||||
css`
|
||||
margin-top: ${theme.gridUnit * 2}px;
|
||||
`
|
||||
}
|
||||
>
|
||||
{t('Click to clear emitted filters')}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
title={t(
|
||||
'This chart emits/applies cross-filters to other charts that use the same dataset',
|
||||
)}
|
||||
>
|
||||
<CrossFilterIcon
|
||||
onClick={() => dispatch(clearDataMask(slice?.slice_id))}
|
||||
/>
|
||||
<CrossFilterIcon iconSize="m" />
|
||||
</Tooltip>
|
||||
)}
|
||||
{!uiConfig.hideChartControls && (
|
||||
|
|
|
|||
|
|
@ -30,21 +30,12 @@ import {
|
|||
withRouter,
|
||||
} from 'react-router-dom';
|
||||
import moment from 'moment';
|
||||
import {
|
||||
Behavior,
|
||||
css,
|
||||
getChartMetadataRegistry,
|
||||
QueryFormData,
|
||||
styled,
|
||||
t,
|
||||
useTheme,
|
||||
} from '@superset-ui/core';
|
||||
import { css, QueryFormData, styled, t, useTheme } from '@superset-ui/core';
|
||||
import { Menu } from 'src/components/Menu';
|
||||
import { NoAnimationDropdown } from 'src/components/Dropdown';
|
||||
import ShareMenuItems from 'src/dashboard/components/menu/ShareMenuItems';
|
||||
import downloadAsImage from 'src/utils/downloadAsImage';
|
||||
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
|
||||
import CrossFilterScopingModal from 'src/dashboard/components/CrossFilterScopingModal/CrossFilterScopingModal';
|
||||
import { getSliceHeaderTooltip } from 'src/dashboard/util/getSliceHeaderTooltip';
|
||||
import { Tooltip } from 'src/components/Tooltip';
|
||||
import Icons from 'src/components/Icons';
|
||||
|
|
@ -57,7 +48,6 @@ import { DrillDetailMenuItems } from 'src/components/Chart/DrillDetail';
|
|||
import { LOG_ACTIONS_CHART_DOWNLOAD_AS_IMAGE } from 'src/logger/LogUtils';
|
||||
|
||||
const MENU_KEYS = {
|
||||
CROSS_FILTER_SCOPING: 'cross_filter_scoping',
|
||||
DOWNLOAD_AS_IMAGE: 'download_as_image',
|
||||
EXPLORE_CHART: 'explore_chart',
|
||||
EXPORT_CSV: 'export_csv',
|
||||
|
|
@ -157,7 +147,6 @@ type SliceHeaderControlsPropsWithRouter = SliceHeaderControlsProps &
|
|||
RouteComponentProps;
|
||||
interface State {
|
||||
showControls: boolean;
|
||||
showCrossFilterScopingModal: boolean;
|
||||
}
|
||||
|
||||
const dropdownIconsStyles = css`
|
||||
|
|
@ -256,7 +245,6 @@ class SliceHeaderControls extends React.PureComponent<
|
|||
|
||||
this.state = {
|
||||
showControls: false,
|
||||
showCrossFilterScopingModal: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -287,9 +275,6 @@ class SliceHeaderControls extends React.PureComponent<
|
|||
this.refreshChart();
|
||||
this.props.addSuccessToast(t('Data refreshed'));
|
||||
break;
|
||||
case MENU_KEYS.CROSS_FILTER_SCOPING:
|
||||
this.setState({ showCrossFilterScopingModal: true });
|
||||
break;
|
||||
case MENU_KEYS.TOGGLE_CHART_DESCRIPTION:
|
||||
// eslint-disable-next-line no-unused-expressions
|
||||
this.props.toggleExpandSlice?.(this.props.slice.slice_id);
|
||||
|
|
@ -346,17 +331,8 @@ class SliceHeaderControls extends React.PureComponent<
|
|||
addDangerToast = () => {},
|
||||
supersetCanShare = false,
|
||||
isCached = [],
|
||||
crossFiltersEnabled,
|
||||
} = this.props;
|
||||
const crossFilterItems = getChartMetadataRegistry().items;
|
||||
const isTable = slice.viz_type === 'table';
|
||||
const isCrossFilter = Object.entries(crossFilterItems)
|
||||
// @ts-ignore
|
||||
.filter(([, { value }]) =>
|
||||
value.behaviors?.includes(Behavior.INTERACTIVE_CHART),
|
||||
)
|
||||
.find(([key]) => key === slice.viz_type);
|
||||
|
||||
const cachedWhen = (cachedDttm || []).map(itemCachedDttm =>
|
||||
moment.utc(itemCachedDttm).fromNow(),
|
||||
);
|
||||
|
|
@ -477,17 +453,6 @@ class SliceHeaderControls extends React.PureComponent<
|
|||
<Menu.Divider />
|
||||
)}
|
||||
|
||||
{isFeatureEnabled(FeatureFlag.DASHBOARD_CROSS_FILTERS) &&
|
||||
isCrossFilter &&
|
||||
crossFiltersEnabled && (
|
||||
<>
|
||||
<Menu.Item key={MENU_KEYS.CROSS_FILTER_SCOPING}>
|
||||
{t('Cross-filter scoping')}
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
</>
|
||||
)}
|
||||
|
||||
{supersetCanShare && (
|
||||
<Menu.SubMenu title={t('Share')}>
|
||||
<ShareMenuItems
|
||||
|
|
@ -538,11 +503,6 @@ class SliceHeaderControls extends React.PureComponent<
|
|||
|
||||
return (
|
||||
<>
|
||||
<CrossFilterScopingModal
|
||||
chartId={slice.slice_id}
|
||||
isOpen={this.state.showCrossFilterScopingModal}
|
||||
onClose={() => this.setState({ showCrossFilterScopingModal: false })}
|
||||
/>
|
||||
{isFullSize && (
|
||||
<Icons.FullscreenExitOutlined
|
||||
style={{ fontSize: 22 }}
|
||||
|
|
@ -557,6 +517,10 @@ class SliceHeaderControls extends React.PureComponent<
|
|||
placement="bottomRight"
|
||||
>
|
||||
<span
|
||||
css={css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`}
|
||||
id={`slice_${slice.slice_id}-controls`}
|
||||
role="button"
|
||||
aria-label="More Options"
|
||||
|
|
|
|||
Loading…
Reference in New Issue