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'}
/>
)}