From a9dc5e94af00fb0d19d598a924da6d3013338201 Mon Sep 17 00:00:00 2001 From: Jesse Yang Date: Thu, 5 May 2022 13:36:37 -0700 Subject: [PATCH] chore: convert URLShortLinkButton to typescript (#19954) --- .../components/AnchorLink/AnchorLink.test.jsx | 73 ----------- .../src/components/AnchorLink/index.jsx | 94 -------------- .../components/URLShortLinkButton/index.jsx | 120 ------------------ .../AnchorLink/AnchorLink.stories.tsx | 2 +- .../components/AnchorLink/AnchorLink.test.tsx | 69 ++++++++++ .../dashboard/components/AnchorLink/index.tsx | 78 ++++++++++++ .../URLShortLinkButton.test.tsx | 2 +- .../components/URLShortLinkButton/index.tsx | 97 ++++++++++++++ .../components/gridComponents/ChartHolder.jsx | 27 ++-- .../components/gridComponents/Header.jsx | 16 +-- .../components/gridComponents/Tab.jsx | 16 +-- 11 files changed, 272 insertions(+), 322 deletions(-) delete mode 100644 superset-frontend/src/components/AnchorLink/AnchorLink.test.jsx delete mode 100644 superset-frontend/src/components/AnchorLink/index.jsx delete mode 100644 superset-frontend/src/components/URLShortLinkButton/index.jsx rename superset-frontend/src/{ => dashboard}/components/AnchorLink/AnchorLink.stories.tsx (96%) create mode 100644 superset-frontend/src/dashboard/components/AnchorLink/AnchorLink.test.tsx create mode 100644 superset-frontend/src/dashboard/components/AnchorLink/index.tsx rename superset-frontend/src/{ => dashboard}/components/URLShortLinkButton/URLShortLinkButton.test.tsx (97%) create mode 100644 superset-frontend/src/dashboard/components/URLShortLinkButton/index.tsx diff --git a/superset-frontend/src/components/AnchorLink/AnchorLink.test.jsx b/superset-frontend/src/components/AnchorLink/AnchorLink.test.jsx deleted file mode 100644 index 3f05416b1c0c5..0000000000000 --- a/superset-frontend/src/components/AnchorLink/AnchorLink.test.jsx +++ /dev/null @@ -1,73 +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 { shallow } from 'enzyme'; - -import AnchorLink from 'src/components/AnchorLink'; -import URLShortLinkButton from 'src/components/URLShortLinkButton'; - -describe('AnchorLink', () => { - const props = { - anchorLinkId: 'CHART-123', - dashboardId: 10, - }; - - const globalLocation = window.location; - afterEach(() => { - window.location = globalLocation; - }); - - beforeEach(() => { - delete window.location; - window.location = new URL(`https://path?#${props.anchorLinkId}`); - }); - - afterEach(() => { - delete global.window.location.value; - }); - - it('should scroll the AnchorLink into view upon mount', async () => { - const callback = jest.fn(); - const stub = jest.spyOn(document, 'getElementById').mockReturnValue({ - scrollIntoView: callback, - }); - - shallow(); - await new Promise(r => setTimeout(r, 2000)); - - expect(stub).toHaveBeenCalledTimes(1); - }); - - it('should render anchor link with id', () => { - const wrapper = shallow(); - expect(wrapper.find(`#${props.anchorLinkId}`)).toExist(); - expect(wrapper.find(URLShortLinkButton)).not.toExist(); - }); - - it('should render URLShortLinkButton', () => { - const wrapper = shallow(); - expect(wrapper.find(URLShortLinkButton)).toExist(); - expect(wrapper.find(URLShortLinkButton)).toHaveProp({ placement: 'right' }); - - const anchorLinkId = wrapper.find(URLShortLinkButton).prop('anchorLinkId'); - const dashboardId = wrapper.find(URLShortLinkButton).prop('dashboardId'); - expect(anchorLinkId).toBe(props.anchorLinkId); - expect(dashboardId).toBe(props.dashboardId); - }); -}); diff --git a/superset-frontend/src/components/AnchorLink/index.jsx b/superset-frontend/src/components/AnchorLink/index.jsx deleted file mode 100644 index 71ba76dff7a07..0000000000000 --- a/superset-frontend/src/components/AnchorLink/index.jsx +++ /dev/null @@ -1,94 +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 PropTypes from 'prop-types'; -import { t } from '@superset-ui/core'; - -import URLShortLinkButton from 'src/components/URLShortLinkButton'; -import getLocationHash from 'src/dashboard/util/getLocationHash'; - -const propTypes = { - anchorLinkId: PropTypes.string.isRequired, - dashboardId: PropTypes.number, - filters: PropTypes.object, - showShortLinkButton: PropTypes.bool, - inFocus: PropTypes.bool, - placement: PropTypes.oneOf(['right', 'left', 'top', 'bottom']), -}; - -const defaultProps = { - inFocus: false, - showShortLinkButton: false, - placement: 'right', - filters: {}, -}; - -class AnchorLink extends React.PureComponent { - componentDidMount() { - const hash = getLocationHash(); - const { anchorLinkId } = this.props; - - if (hash && anchorLinkId === hash) { - this.scrollToView(); - } - } - - UNSAFE_componentWillReceiveProps(nextProps) { - const { inFocus = false } = nextProps; - if (inFocus) { - this.scrollToView(); - } - } - - scrollToView(delay = 0) { - const { anchorLinkId } = this.props; - const directLinkComponent = document.getElementById(anchorLinkId); - if (directLinkComponent) { - setTimeout(() => { - directLinkComponent.scrollIntoView({ - block: 'center', - behavior: 'smooth', - }); - }, delay); - } - } - - render() { - const { anchorLinkId, dashboardId, showShortLinkButton, placement } = - this.props; - return ( - - {showShortLinkButton && ( - - )} - - ); - } -} - -AnchorLink.propTypes = propTypes; -AnchorLink.defaultProps = defaultProps; - -export default AnchorLink; diff --git a/superset-frontend/src/components/URLShortLinkButton/index.jsx b/superset-frontend/src/components/URLShortLinkButton/index.jsx deleted file mode 100644 index 4a03e02d3ea5a..0000000000000 --- a/superset-frontend/src/components/URLShortLinkButton/index.jsx +++ /dev/null @@ -1,120 +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 PropTypes from 'prop-types'; -import { t } from '@superset-ui/core'; -import Popover from 'src/components/Popover'; -import CopyToClipboard from 'src/components/CopyToClipboard'; -import { getDashboardPermalink, getUrlParam } from 'src/utils/urlUtils'; -import withToasts from 'src/components/MessageToasts/withToasts'; -import { URL_PARAMS } from 'src/constants'; -import { getFilterValue } from 'src/dashboard/components/nativeFilters/FilterBar/keyValue'; - -const propTypes = { - addDangerToast: PropTypes.func.isRequired, - anchorLinkId: PropTypes.string, - dashboardId: PropTypes.number, - emailSubject: PropTypes.string, - emailContent: PropTypes.string, - placement: PropTypes.oneOf(['right', 'left', 'top', 'bottom']), -}; - -class URLShortLinkButton extends React.Component { - constructor(props) { - super(props); - this.state = { - shortUrl: '', - }; - this.onShortUrlSuccess = this.onShortUrlSuccess.bind(this); - this.getCopyUrl = this.getCopyUrl.bind(this); - } - - onShortUrlSuccess(shortUrl) { - this.setState(() => ({ - shortUrl, - })); - } - - getCopyUrl(e) { - e.stopPropagation(); - const nativeFiltersKey = getUrlParam(URL_PARAMS.nativeFiltersKey); - if (this.props.dashboardId) { - getFilterValue(this.props.dashboardId, nativeFiltersKey) - .then(filterState => - getDashboardPermalink({ - dashboardId: this.props.dashboardId, - filterState, - hash: this.props.anchorLinkId, - }) - .then(this.onShortUrlSuccess) - .catch(this.props.addDangerToast), - ) - .catch(this.props.addDangerToast); - } - } - - renderPopover() { - const emailBody = t('%s%s', this.props.emailContent, this.state.shortUrl); - return ( -
- - } - /> -    - - - -
- ); - } - - render() { - return ( - - - -   - - - ); - } -} - -URLShortLinkButton.defaultProps = { - placement: 'left', - emailSubject: '', - emailContent: '', -}; - -URLShortLinkButton.propTypes = propTypes; - -export default withToasts(URLShortLinkButton); diff --git a/superset-frontend/src/components/AnchorLink/AnchorLink.stories.tsx b/superset-frontend/src/dashboard/components/AnchorLink/AnchorLink.stories.tsx similarity index 96% rename from superset-frontend/src/components/AnchorLink/AnchorLink.stories.tsx rename to superset-frontend/src/dashboard/components/AnchorLink/AnchorLink.stories.tsx index 33a47e6c96a10..ccb50a2cb64f7 100644 --- a/superset-frontend/src/components/AnchorLink/AnchorLink.stories.tsx +++ b/superset-frontend/src/dashboard/components/AnchorLink/AnchorLink.stories.tsx @@ -25,7 +25,7 @@ export default { }; export const InteractiveAnchorLink = (args: any) => ( - + ); const PLACEMENTS = ['right', 'left', 'top', 'bottom']; diff --git a/superset-frontend/src/dashboard/components/AnchorLink/AnchorLink.test.tsx b/superset-frontend/src/dashboard/components/AnchorLink/AnchorLink.test.tsx new file mode 100644 index 0000000000000..9669a5d6a3f1f --- /dev/null +++ b/superset-frontend/src/dashboard/components/AnchorLink/AnchorLink.test.tsx @@ -0,0 +1,69 @@ +/** + * 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, act } from 'spec/helpers/testing-library'; +import AnchorLink from 'src/dashboard/components/AnchorLink'; + +describe('AnchorLink', () => { + const props = { + id: 'CHART-123', + dashboardId: 10, + }; + + const globalLocation = window.location; + afterEach(() => { + window.location = globalLocation; + }); + + it('should scroll the AnchorLink into view upon mount if id matches hash', async () => { + const callback = jest.fn(); + jest.spyOn(document, 'getElementById').mockReturnValue({ + scrollIntoView: callback, + } as unknown as HTMLElement); + + window.location.hash = props.id; + await act(async () => { + render(, { useRedux: true }); + }); + expect(callback).toHaveBeenCalledTimes(1); + + window.location.hash = 'random'; + await act(async () => { + render(, { useRedux: true }); + }); + expect(callback).toHaveBeenCalledTimes(1); + }); + + it('should render anchor link without short link button', () => { + const { container, queryByRole } = render( + , + { useRedux: true }, + ); + expect(container.querySelector(`#${props.id}`)).toBeInTheDocument(); + expect(queryByRole('button')).toBe(null); + }); + + it('should render short link button', () => { + const { getByRole } = render( + , + { useRedux: true }, + ); + expect(getByRole('button')).toBeInTheDocument(); + }); +}); diff --git a/superset-frontend/src/dashboard/components/AnchorLink/index.tsx b/superset-frontend/src/dashboard/components/AnchorLink/index.tsx new file mode 100644 index 0000000000000..cfabaf51b7daf --- /dev/null +++ b/superset-frontend/src/dashboard/components/AnchorLink/index.tsx @@ -0,0 +1,78 @@ +/** + * 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, { useEffect } from 'react'; +import { t } from '@superset-ui/core'; + +import URLShortLinkButton, { + URLShortLinkButtonProps, +} from 'src/dashboard/components/URLShortLinkButton'; +import getLocationHash from 'src/dashboard/util/getLocationHash'; + +export type AnchorLinkProps = { + id: string; + scrollIntoView?: boolean; + showShortLinkButton?: boolean; +} & Pick; + +export default function AnchorLink({ + id, + dashboardId, + placement = 'right', + scrollIntoView = false, + showShortLinkButton = true, +}: AnchorLinkProps) { + const scrollAnchorIntoView = (elementId: string) => { + const element = document.getElementById(elementId); + if (element) { + element.scrollIntoView({ + block: 'center', + behavior: 'smooth', + }); + } + }; + + // will always scroll element into view if element id and url hash match + const hash = getLocationHash(); + useEffect(() => { + if (hash && id === hash) { + scrollAnchorIntoView(id); + } + }, [hash, id]); + + // force scroll into view + useEffect(() => { + if (scrollIntoView) { + scrollAnchorIntoView(id); + } + }, [id, scrollIntoView]); + + return ( + + {showShortLinkButton && dashboardId && ( + + )} + + ); +} diff --git a/superset-frontend/src/components/URLShortLinkButton/URLShortLinkButton.test.tsx b/superset-frontend/src/dashboard/components/URLShortLinkButton/URLShortLinkButton.test.tsx similarity index 97% rename from superset-frontend/src/components/URLShortLinkButton/URLShortLinkButton.test.tsx rename to superset-frontend/src/dashboard/components/URLShortLinkButton/URLShortLinkButton.test.tsx index 36ffc9e339432..e4701d0354a3b 100644 --- a/superset-frontend/src/components/URLShortLinkButton/URLShortLinkButton.test.tsx +++ b/superset-frontend/src/dashboard/components/URLShortLinkButton/URLShortLinkButton.test.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { render, screen } from 'spec/helpers/testing-library'; import userEvent from '@testing-library/user-event'; import fetchMock from 'fetch-mock'; -import URLShortLinkButton from 'src/components/URLShortLinkButton'; +import URLShortLinkButton from 'src/dashboard/components/URLShortLinkButton'; import ToastContainer from 'src/components/MessageToasts/ToastContainer'; const DASHBOARD_ID = 10; diff --git a/superset-frontend/src/dashboard/components/URLShortLinkButton/index.tsx b/superset-frontend/src/dashboard/components/URLShortLinkButton/index.tsx new file mode 100644 index 0000000000000..f2af7af1dcbca --- /dev/null +++ b/superset-frontend/src/dashboard/components/URLShortLinkButton/index.tsx @@ -0,0 +1,97 @@ +/** + * 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, { useState } from 'react'; +import { t } from '@superset-ui/core'; +import Popover, { PopoverProps } from 'src/components/Popover'; +import CopyToClipboard from 'src/components/CopyToClipboard'; +import { getDashboardPermalink, getUrlParam } from 'src/utils/urlUtils'; +import { useToasts } from 'src/components/MessageToasts/withToasts'; +import { URL_PARAMS } from 'src/constants'; +import { getFilterValue } from 'src/dashboard/components/nativeFilters/FilterBar/keyValue'; + +export type URLShortLinkButtonProps = { + dashboardId: number; + anchorLinkId?: string; + emailSubject?: string; + emailContent?: string; + placement?: PopoverProps['placement']; +}; + +export default function URLShortLinkButton({ + dashboardId, + anchorLinkId, + placement = 'right', + emailContent = '', + emailSubject = '', +}: URLShortLinkButtonProps) { + const [shortUrl, setShortUrl] = useState(''); + const { addDangerToast } = useToasts(); + + const getCopyUrl = async () => { + const nativeFiltersKey = getUrlParam(URL_PARAMS.nativeFiltersKey); + try { + const filterState = await getFilterValue(dashboardId, nativeFiltersKey); + const url = await getDashboardPermalink({ + dashboardId, + filterState, + hash: anchorLinkId, + }); + setShortUrl(url); + } catch (error) { + addDangerToast(error); + } + }; + + const emailBody = `${emailContent}${shortUrl || ''}`; + const emailLink = `mailto:?Subject=${emailSubject}%20&Body=${emailBody}`; + + return ( + + + } + /> +    + + + + + } + > + { + e.stopPropagation(); + getCopyUrl(); + }} + > + +   + + + ); +} diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx index 95fb967c777b2..a08102094b4d5 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx @@ -23,22 +23,21 @@ import { useTheme } from '@superset-ui/core'; import { useSelector, connect } from 'react-redux'; import { getChartIdsInFilterBoxScope } from 'src/dashboard/util/activeDashboardFilters'; -import Chart from '../../containers/Chart'; -import AnchorLink from '../../../components/AnchorLink'; -import DeleteComponentButton from '../DeleteComponentButton'; -import DragDroppable from '../dnd/DragDroppable'; -import HoverMenu from '../menu/HoverMenu'; -import ResizableContainer from '../resizable/ResizableContainer'; -import getChartAndLabelComponentIdFromPath from '../../util/getChartAndLabelComponentIdFromPath'; -import { componentShape } from '../../util/propShapes'; -import { COLUMN_TYPE, ROW_TYPE } from '../../util/componentTypes'; - +import Chart from 'src/dashboard/containers/Chart'; +import AnchorLink from 'src/dashboard/components/AnchorLink'; +import DeleteComponentButton from 'src/dashboard/components/DeleteComponentButton'; +import DragDroppable from 'src/dashboard/components/dnd/DragDroppable'; +import HoverMenu from 'src/dashboard/components/menu/HoverMenu'; +import ResizableContainer from 'src/dashboard/components/resizable/ResizableContainer'; +import getChartAndLabelComponentIdFromPath from 'src/dashboard/util/getChartAndLabelComponentIdFromPath'; +import { componentShape } from 'src/dashboard/util/propShapes'; +import { COLUMN_TYPE, ROW_TYPE } from 'src/dashboard/util/componentTypes'; import { GRID_BASE_UNIT, GRID_GUTTER_SIZE, GRID_MIN_COLUMN_COUNT, GRID_MIN_ROW_UNITS, -} from '../../util/constants'; +} from 'src/dashboard/util/constants'; const CHART_MARGIN = 32; @@ -350,8 +349,10 @@ class ChartHolder extends React.Component { > {!editMode && ( )} {!!this.state.outlinedComponentId && diff --git a/superset-frontend/src/dashboard/components/gridComponents/Header.jsx b/superset-frontend/src/dashboard/components/gridComponents/Header.jsx index 7ee2f44136d63..938a48bf099d9 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Header.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Header.jsx @@ -20,15 +20,15 @@ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; +import PopoverDropdown from 'src/components/PopoverDropdown'; +import EditableTitle from 'src/components/EditableTitle'; import DragDroppable from 'src/dashboard/components/dnd/DragDroppable'; import DragHandle from 'src/dashboard/components/dnd/DragHandle'; -import EditableTitle from 'src/components/EditableTitle'; -import AnchorLink from 'src/components/AnchorLink'; +import AnchorLink from 'src/dashboard/components/AnchorLink'; import HoverMenu from 'src/dashboard/components/menu/HoverMenu'; import WithPopoverMenu from 'src/dashboard/components/menu/WithPopoverMenu'; import BackgroundStyleDropdown from 'src/dashboard/components/menu/BackgroundStyleDropdown'; import DeleteComponentButton from 'src/dashboard/components/DeleteComponentButton'; -import PopoverDropdown from 'src/components/PopoverDropdown'; import headerStyleOptions from 'src/dashboard/util/headerStyleOptions'; import backgroundStyleOptions from 'src/dashboard/util/backgroundStyleOptions'; import { componentShape } from 'src/dashboard/util/propShapes'; @@ -39,13 +39,13 @@ import { const propTypes = { id: PropTypes.string.isRequired, + dashboardId: PropTypes.string.isRequired, parentId: PropTypes.string.isRequired, component: componentShape.isRequired, depth: PropTypes.number.isRequired, parentComponent: componentShape.isRequired, index: PropTypes.number.isRequired, editMode: PropTypes.bool.isRequired, - filters: PropTypes.object.isRequired, // redux handleComponentDrop: PropTypes.func.isRequired, @@ -100,13 +100,13 @@ class Header extends React.PureComponent { const { isFocused } = this.state; const { + dashboardId, component, depth, parentComponent, index, handleComponentDrop, editMode, - filters, } = this.props; const headerStyle = headerStyleOptions.find( @@ -176,11 +176,7 @@ class Header extends React.PureComponent { showTooltip={false} /> {!editMode && ( - + )} diff --git a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx index 77156278504d6..f240d6f525587 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx @@ -23,12 +23,12 @@ import { connect } from 'react-redux'; import { styled, t } from '@superset-ui/core'; import { EmptyStateMedium } from 'src/components/EmptyState'; +import EditableTitle from 'src/components/EditableTitle'; import { setEditMode } from 'src/dashboard/actions/dashboardState'; -import DashboardComponent from '../../containers/DashboardComponent'; -import DragDroppable from '../dnd/DragDroppable'; -import EditableTitle from '../../../components/EditableTitle'; -import AnchorLink from '../../../components/AnchorLink'; -import { componentShape } from '../../util/propShapes'; +import DashboardComponent from 'src/dashboard/containers/DashboardComponent'; +import AnchorLink from 'src/dashboard/components/AnchorLink'; +import DragDroppable from 'src/dashboard/components/dnd/DragDroppable'; +import { componentShape } from 'src/dashboard/util/propShapes'; export const RENDER_TAB = 'RENDER_TAB'; export const RENDER_TAB_CONTENT = 'RENDER_TAB_CONTENT'; @@ -45,7 +45,6 @@ const propTypes = { onDropOnTab: PropTypes.func, editMode: PropTypes.bool.isRequired, canEdit: PropTypes.bool.isRequired, - filters: PropTypes.object.isRequired, // grid related availableColumnCount: PropTypes.number, @@ -251,7 +250,6 @@ class Tab extends React.PureComponent { index, depth, editMode, - filters, isFocused, isHighlighted, } = this.props; @@ -283,10 +281,8 @@ class Tab extends React.PureComponent { /> {!editMode && ( = 5 ? 'left' : 'right'} /> )}