This is an automated email from the ASF dual-hosted git repository.
yjc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 2d70ef670e feat(sqllab): Make LeftBar width resizable (#21300)
2d70ef670e is described below
commit 2d70ef670ef81179916d9ab558a7ce6e4b84b82e
Author: JUST.in DO IT <[email protected]>
AuthorDate: Thu Sep 1 21:26:20 2022 -0700
feat(sqllab): Make LeftBar width resizable (#21300)
---
.../src/SqlLab/components/SqlEditor/index.jsx | 54 +++++++++----
.../SqlLab/components/TabbedSqlEditors/index.jsx | 1 -
superset-frontend/src/SqlLab/constants.ts | 1 +
superset-frontend/src/SqlLab/main.less | 4 +-
.../src/components/ResizableSidebar/index.tsx | 82 ++++++++++++++++++++
.../useStoredSidebarWidth.test.ts} | 41 +++++-----
.../ResizableSidebar/useStoredSidebarWidth.ts} | 28 +++----
.../src/components/TableSelector/index.tsx | 5 +-
.../DashboardBuilder/DashboardBuilder.test.tsx | 12 +--
.../DashboardBuilder/DashboardBuilder.tsx | 88 ++++++++--------------
superset-frontend/src/utils/localStorageHelpers.ts | 2 +
11 files changed, 206 insertions(+), 112 deletions(-)
diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx
b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx
index d813b3b52d..c48594d304 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx
@@ -31,6 +31,7 @@ import StyledModal from 'src/components/Modal';
import Mousetrap from 'mousetrap';
import Button from 'src/components/Button';
import Timer from 'src/components/Timer';
+import ResizableSidebar from 'src/components/ResizableSidebar';
import { AntdDropdown, AntdSwitch } from 'src/components';
import { Input } from 'src/components/Input';
import { Menu } from 'src/components/Menu';
@@ -60,6 +61,7 @@ import {
SQL_EDITOR_GUTTER_HEIGHT,
SQL_EDITOR_GUTTER_MARGIN,
SQL_TOOLBAR_HEIGHT,
+ SQL_EDITOR_LEFTBAR_WIDTH,
} from 'src/SqlLab/constants';
import {
getItem,
@@ -127,6 +129,15 @@ const StyledToolbar = styled.div`
}
`;
+const StyledSidebar = styled.div`
+ flex: 0 0 ${({ width }) => width}px;
+ width: ${({ width }) => width}px;
+ padding: ${({ hide }) => (hide ? 0 : 10)}px;
+ border-right: 1px solid
+ ${({ theme, hide }) =>
+ hide ? 'transparent' : theme.colors.grayscale.light2};
+`;
+
const propTypes = {
actions: PropTypes.object.isRequired,
database: PropTypes.object,
@@ -674,7 +685,6 @@ class SqlEditor extends React.PureComponent {
this.state.createAs === CtasEnum.VIEW
? 'Specify name to CREATE VIEW AS schema in: public'
: 'Specify name to CREATE TABLE AS schema in: public';
-
const leftBarStateClass = this.props.hideLeftBar
? 'schemaPane-exit-done'
: 'schemaPane-enter-done';
@@ -685,15 +695,28 @@ class SqlEditor extends React.PureComponent {
in={!this.props.hideLeftBar}
timeout={300}
>
- <div className={`schemaPane ${leftBarStateClass}`}>
- <SqlEditorLeftBar
- database={this.props.database}
- queryEditor={this.props.queryEditor}
- tables={this.props.tables}
- actions={this.props.actions}
- setEmptyState={this.setEmptyState}
- />
- </div>
+ <ResizableSidebar
+ id={`sqllab:${this.props.queryEditor.id}`}
+ minWidth={SQL_EDITOR_LEFTBAR_WIDTH}
+ initialWidth={SQL_EDITOR_LEFTBAR_WIDTH}
+ enable={!this.props.hideLeftBar}
+ >
+ {adjustedWidth => (
+ <StyledSidebar
+ className={`schemaPane ${leftBarStateClass}`}
+ width={adjustedWidth}
+ hide={this.props.hideLeftBar}
+ >
+ <SqlEditorLeftBar
+ database={this.props.database}
+ queryEditor={this.props.queryEditor}
+ tables={this.props.tables}
+ actions={this.props.actions}
+ setEmptyState={this.setEmptyState}
+ />
+ </StyledSidebar>
+ )}
+ </ResizableSidebar>
</CSSTransition>
{this.state.showEmptyState ? (
<EmptyStateBig
@@ -754,17 +777,22 @@ SqlEditor.defaultProps = defaultProps;
SqlEditor.propTypes = propTypes;
function mapStateToProps({ sqlLab }, { queryEditor }) {
- let { latestQueryId, dbId } = queryEditor;
+ let { latestQueryId, dbId, hideLeftBar } = queryEditor;
if (sqlLab.unsavedQueryEditor.id === queryEditor.id) {
- const { latestQueryId: unsavedQID, dbId: unsavedDBID } =
- sqlLab.unsavedQueryEditor;
+ const {
+ latestQueryId: unsavedQID,
+ dbId: unsavedDBID,
+ hideLeftBar: unsavedHideLeftBar,
+ } = sqlLab.unsavedQueryEditor;
latestQueryId = unsavedQID || latestQueryId;
dbId = unsavedDBID || dbId;
+ hideLeftBar = unsavedHideLeftBar || hideLeftBar;
}
const database = sqlLab.databases[dbId];
const latestQuery = sqlLab.queries[latestQueryId];
return {
+ hideLeftBar,
queryEditors: sqlLab.queryEditors,
latestQuery,
database,
diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx
b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx
index 7c53181866..e25f179716 100644
--- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx
+++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.jsx
@@ -305,7 +305,6 @@ class TabbedSqlEditors extends React.PureComponent {
editorQueries={this.state.queriesArray}
dataPreviewQueries={this.state.dataPreviewQueries}
actions={this.props.actions}
- hideLeftBar={qe.hideLeftBar}
defaultQueryLimit={this.props.defaultQueryLimit}
maxRow={this.props.maxRow}
displayLimit={this.props.displayLimit}
diff --git a/superset-frontend/src/SqlLab/constants.ts
b/superset-frontend/src/SqlLab/constants.ts
index 7d0ea09c18..11d990032d 100644
--- a/superset-frontend/src/SqlLab/constants.ts
+++ b/superset-frontend/src/SqlLab/constants.ts
@@ -48,6 +48,7 @@ export const TIME_OPTIONS = [
export const SQL_EDITOR_GUTTER_HEIGHT = 5;
export const SQL_EDITOR_GUTTER_MARGIN = 3;
export const SQL_TOOLBAR_HEIGHT = 51;
+export const SQL_EDITOR_LEFTBAR_WIDTH = 400;
// kilobyte storage
export const KB_STORAGE = 1024;
diff --git a/superset-frontend/src/SqlLab/main.less
b/superset-frontend/src/SqlLab/main.less
index 098bb30d45..549f465195 100644
--- a/superset-frontend/src/SqlLab/main.less
+++ b/superset-frontend/src/SqlLab/main.less
@@ -283,16 +283,14 @@ div.Workspace {
display: flex;
flex-direction: row;
height: 100%;
- padding: 10px;
.schemaPane {
- flex: 0 0 400px;
transition: transform @timing-normal ease-in-out;
}
.queryPane {
flex: 1 1 auto;
- padding-left: 10px;
+ padding: 10px;
overflow-y: none;
overflow-x: scroll;
}
diff --git a/superset-frontend/src/components/ResizableSidebar/index.tsx
b/superset-frontend/src/components/ResizableSidebar/index.tsx
new file mode 100644
index 0000000000..4abe56e526
--- /dev/null
+++ b/superset-frontend/src/components/ResizableSidebar/index.tsx
@@ -0,0 +1,82 @@
+/**
+ * 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 { Resizable } from 're-resizable';
+import { styled } from '@superset-ui/core';
+import useStoredSidebarWidth from './useStoredSidebarWidth';
+
+const ResizableWrapper = styled.div`
+ position: absolute;
+ height: 100%;
+
+ :hover .sidebar-resizer::after {
+ background-color: ${({ theme }) => theme.colors.primary.base};
+ }
+
+ .sidebar-resizer {
+ // @z-index-above-sticky-header (100) + 1 = 101
+ z-index: 101;
+ }
+
+ .sidebar-resizer::after {
+ display: block;
+ content: '';
+ width: 1px;
+ height: 100%;
+ margin: 0 auto;
+ }
+`;
+
+type Props = {
+ id: string;
+ initialWidth: number;
+ enable: boolean;
+ minWidth?: number;
+ maxWidth?: number;
+ children: (width: number) => React.ReactNode;
+};
+
+const ResizableSidebar: React.FC<Props> = ({
+ id,
+ initialWidth,
+ minWidth,
+ maxWidth,
+ enable,
+ children,
+}) => {
+ const [width, setWidth] = useStoredSidebarWidth(id, initialWidth);
+
+ return (
+ <>
+ <ResizableWrapper>
+ <Resizable
+ enable={{ right: enable }}
+ handleClasses={{ right: 'sidebar-resizer' }}
+ size={{ width, height: '100%' }}
+ minWidth={minWidth}
+ maxWidth={maxWidth}
+ onResizeStop={(e, direction, ref, d) => setWidth(width + d.width)}
+ />
+ </ResizableWrapper>
+ {children(width)}
+ </>
+ );
+};
+
+export default ResizableSidebar;
diff --git
a/superset-frontend/src/dashboard/components/DashboardBuilder/useStoredFilterBarWidth.test.ts
b/superset-frontend/src/components/ResizableSidebar/useStoredSidebarWidth.test.ts
similarity index 68%
rename from
superset-frontend/src/dashboard/components/DashboardBuilder/useStoredFilterBarWidth.test.ts
rename to
superset-frontend/src/components/ResizableSidebar/useStoredSidebarWidth.test.ts
index 1a9da6658a..347cfd8b9a 100644
---
a/superset-frontend/src/dashboard/components/DashboardBuilder/useStoredFilterBarWidth.test.ts
+++
b/superset-frontend/src/components/ResizableSidebar/useStoredSidebarWidth.test.ts
@@ -22,10 +22,11 @@ import {
setItem,
getItem,
} from 'src/utils/localStorageHelpers';
-import { OPEN_FILTER_BAR_WIDTH } from 'src/dashboard/constants';
-import useStoredFilterBarWidth from './useStoredFilterBarWidth';
+import useStoredSidebarWidth from './useStoredSidebarWidth';
-describe('useStoredFilterBarWidth', () => {
+const INITIAL_WIDTH = 300;
+
+describe('useStoredSidebarWidth', () => {
beforeEach(() => {
localStorage.clear();
});
@@ -34,22 +35,26 @@ describe('useStoredFilterBarWidth', () => {
localStorage.clear();
});
- it('returns a default filterBar width by OPEN_FILTER_BAR_WIDTH', () => {
- const dashboardId = '123';
- const { result } = renderHook(() => useStoredFilterBarWidth(dashboardId));
+ it('returns a default filterBar width by initialWidth', () => {
+ const id = '123';
+ const { result } = renderHook(() =>
+ useStoredSidebarWidth(id, INITIAL_WIDTH),
+ );
const [actualWidth] = result.current;
- expect(actualWidth).toEqual(OPEN_FILTER_BAR_WIDTH);
+ expect(actualWidth).toEqual(INITIAL_WIDTH);
});
it('returns a stored filterBar width from localStorage', () => {
- const dashboardId = '123';
+ const id = '123';
const expectedWidth = 378;
- setItem(LocalStorageKeys.dashboard__custom_filter_bar_widths, {
- [dashboardId]: expectedWidth,
+ setItem(LocalStorageKeys.common__resizable_sidebar_widths, {
+ [id]: expectedWidth,
'456': 250,
});
- const { result } = renderHook(() => useStoredFilterBarWidth(dashboardId));
+ const { result } = renderHook(() =>
+ useStoredSidebarWidth(id, INITIAL_WIDTH),
+ );
const [actualWidth] = result.current;
expect(actualWidth).toEqual(expectedWidth);
@@ -57,15 +62,17 @@ describe('useStoredFilterBarWidth', () => {
});
it('returns a setter for filterBar width that stores the state in
localStorage together', () => {
- const dashboardId = '123';
+ const id = '123';
const expectedWidth = 378;
const otherDashboardId = '456';
const otherDashboardWidth = 253;
- setItem(LocalStorageKeys.dashboard__custom_filter_bar_widths, {
- [dashboardId]: 300,
+ setItem(LocalStorageKeys.common__resizable_sidebar_widths, {
+ [id]: 300,
[otherDashboardId]: otherDashboardWidth,
});
- const { result } = renderHook(() => useStoredFilterBarWidth(dashboardId));
+ const { result } = renderHook(() =>
+ useStoredSidebarWidth(id, INITIAL_WIDTH),
+ );
const [prevWidth, setter] = result.current;
expect(prevWidth).toEqual(300);
@@ -74,10 +81,10 @@ describe('useStoredFilterBarWidth', () => {
const updatedWidth = result.current[0];
const widthsMap = getItem(
- LocalStorageKeys.dashboard__custom_filter_bar_widths,
+ LocalStorageKeys.common__resizable_sidebar_widths,
{},
);
- expect(widthsMap[dashboardId]).toEqual(expectedWidth);
+ expect(widthsMap[id]).toEqual(expectedWidth);
expect(widthsMap[otherDashboardId]).toEqual(otherDashboardWidth);
expect(updatedWidth).toEqual(expectedWidth);
expect(updatedWidth).not.toEqual(250);
diff --git
a/superset-frontend/src/dashboard/components/DashboardBuilder/useStoredFilterBarWidth.ts
b/superset-frontend/src/components/ResizableSidebar/useStoredSidebarWidth.ts
similarity index 62%
rename from
superset-frontend/src/dashboard/components/DashboardBuilder/useStoredFilterBarWidth.ts
rename to
superset-frontend/src/components/ResizableSidebar/useStoredSidebarWidth.ts
index 0cbdc74182..4448d2ec52 100644
---
a/superset-frontend/src/dashboard/components/DashboardBuilder/useStoredFilterBarWidth.ts
+++ b/superset-frontend/src/components/ResizableSidebar/useStoredSidebarWidth.ts
@@ -22,30 +22,30 @@ import {
setItem,
getItem,
} from 'src/utils/localStorageHelpers';
-import { OPEN_FILTER_BAR_WIDTH } from 'src/dashboard/constants';
-export default function useStoredFilterBarWidth(dashboardId: string) {
+export default function useStoredSidebarWidth(
+ id: string,
+ initialWidth: number,
+) {
const widthsMapRef = useRef<Record<string, number>>();
- const [filterBarWidth, setFilterBarWidth] = useState<number>(
- OPEN_FILTER_BAR_WIDTH,
- );
+ const [sidebarWidth, setSidebarWidth] = useState<number>(initialWidth);
useEffect(() => {
widthsMapRef.current =
widthsMapRef.current ??
- getItem(LocalStorageKeys.dashboard__custom_filter_bar_widths, {});
- if (widthsMapRef.current[dashboardId]) {
- setFilterBarWidth(widthsMapRef.current[dashboardId]);
+ getItem(LocalStorageKeys.common__resizable_sidebar_widths, {});
+ if (widthsMapRef.current[id]) {
+ setSidebarWidth(widthsMapRef.current[id]);
}
- }, [dashboardId]);
+ }, [id]);
- function setStoredFilterBarWidth(updatedWidth: number) {
- setFilterBarWidth(updatedWidth);
- setItem(LocalStorageKeys.dashboard__custom_filter_bar_widths, {
+ function setStoredSidebarWidth(updatedWidth: number) {
+ setSidebarWidth(updatedWidth);
+ setItem(LocalStorageKeys.common__resizable_sidebar_widths, {
...widthsMapRef.current,
- [dashboardId]: updatedWidth,
+ [id]: updatedWidth,
});
}
- return [filterBarWidth, setStoredFilterBarWidth] as const;
+ return [sidebarWidth, setStoredSidebarWidth] as const;
}
diff --git a/superset-frontend/src/components/TableSelector/index.tsx
b/superset-frontend/src/components/TableSelector/index.tsx
index a4291690c7..d285b61a4c 100644
--- a/superset-frontend/src/components/TableSelector/index.tsx
+++ b/superset-frontend/src/components/TableSelector/index.tsx
@@ -39,12 +39,14 @@ import { useToasts } from
'src/components/MessageToasts/withToasts';
import { SchemaOption } from 'src/SqlLab/types';
import { useTables, Table } from 'src/hooks/apiResources';
+const REFRESH_WIDTH = 30;
+
const TableSelectorWrapper = styled.div`
${({ theme }) => `
.refresh {
display: flex;
align-items: center;
- width: 30px;
+ width: ${REFRESH_WIDTH}px;
margin-left: ${theme.gridUnit}px;
margin-top: ${theme.gridUnit * 5}px;
}
@@ -66,6 +68,7 @@ const TableSelectorWrapper = styled.div`
.select {
flex: 1;
+ max-width: calc(100% - ${theme.gridUnit + REFRESH_WIDTH}px)
}
`}
`;
diff --git
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.test.tsx
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.test.tsx
index b64a961092..97d7b2a50e 100644
---
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.test.tsx
+++
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.test.tsx
@@ -23,7 +23,7 @@ import { render } from 'spec/helpers/testing-library';
import { fireEvent, within } from '@testing-library/react';
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
import DashboardBuilder from
'src/dashboard/components/DashboardBuilder/DashboardBuilder';
-import useStoredFilterBarWidth from
'src/dashboard/components/DashboardBuilder/useStoredFilterBarWidth';
+import useStoredSidebarWidth from
'src/components/ResizableSidebar/useStoredSidebarWidth';
import {
fetchFaveStar,
setActiveTabs,
@@ -46,7 +46,7 @@ jest.mock('src/dashboard/actions/dashboardState', () => ({
setDirectPathToChild: jest.fn(),
}));
jest.mock('src/featureFlags');
-jest.mock('src/dashboard/components/DashboardBuilder/useStoredFilterBarWidth');
+jest.mock('src/components/ResizableSidebar/useStoredSidebarWidth');
// mock following dependant components to fix the prop warnings
jest.mock('src/components/Icons/Icon', () => () => (
@@ -98,7 +98,7 @@ describe('DashboardBuilder', () => {
activeTabsStub = (setActiveTabs as jest.Mock).mockReturnValue({
type: 'mock-action',
});
- (useStoredFilterBarWidth as jest.Mock).mockImplementation(() => [
+ (useStoredSidebarWidth as jest.Mock).mockImplementation(() => [
100,
jest.fn(),
]);
@@ -108,7 +108,7 @@ describe('DashboardBuilder', () => {
afterAll(() => {
favStarStub.mockReset();
activeTabsStub.mockReset();
- (useStoredFilterBarWidth as jest.Mock).mockReset();
+ (useStoredSidebarWidth as jest.Mock).mockReset();
});
function setup(overrideState = {}, overrideStore?: Store) {
@@ -259,10 +259,10 @@ describe('DashboardBuilder', () => {
(isFeatureEnabled as jest.Mock).mockReset();
});
- it('should set FilterBar width by useStoredFilterBarWidth', () => {
+ it('should set FilterBar width by useStoredSidebarWidth', () => {
const expectedValue = 200;
const setter = jest.fn();
- (useStoredFilterBarWidth as jest.Mock).mockImplementation(() => [
+ (useStoredSidebarWidth as jest.Mock).mockImplementation(() => [
expectedValue,
setter,
]);
diff --git
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
index fb062490b3..85e42d9032 100644
---
a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
+++
b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx
@@ -26,7 +26,6 @@ import React, {
useMemo,
useRef,
} from 'react';
-import { Resizable } from 're-resizable';
import { JsonObject, styled, css, t } from '@superset-ui/core';
import { Global } from '@emotion/react';
import { useDispatch, useSelector } from 'react-redux';
@@ -62,6 +61,7 @@ import FilterBar from
'src/dashboard/components/nativeFilters/FilterBar';
import Loading from 'src/components/Loading';
import { EmptyStateBig } from 'src/components/EmptyState';
import { useUiConfig } from 'src/components/UiConfigContext';
+import ResizableSidebar from 'src/components/ResizableSidebar';
import {
BUILDER_SIDEPANEL_WIDTH,
CLOSED_FILTER_BAR_WIDTH,
@@ -74,7 +74,6 @@ import {
import { shouldFocusTabs, getRootLevelTabsComponent } from './utils';
import DashboardContainer from './DashboardContainer';
import { useNativeFilters } from './state';
-import useStoredFilterBarWidth from './useStoredFilterBarWidth';
type DashboardBuilderProps = {};
@@ -220,27 +219,6 @@ const StyledDashboardContent = styled.div<{
}
`;
-const ResizableFilterBarWrapper = styled.div`
- position: absolute;
-
- :hover .filterbar-resizer::after {
- background-color: ${({ theme }) => theme.colors.primary.base};
- }
-
- .filterbar-resizer {
- // @z-index-above-sticky-header (100) + 1 = 101
- z-index: 101;
- }
-
- .filterbar-resizer::after {
- display: block;
- content: '';
- width: 1px;
- height: 100%;
- margin: 0 auto;
- }
-`;
-
const DashboardBuilder: FC<DashboardBuilderProps> = () => {
const dispatch = useDispatch();
const uiConfig = useUiConfig();
@@ -327,13 +305,6 @@ const DashboardBuilder: FC<DashboardBuilderProps> = () => {
nativeFiltersEnabled,
} = useNativeFilters();
- const [adjustedFilterBarWidth, setAdjustedFilterBarWidth] =
- useStoredFilterBarWidth(dashboardId);
-
- const filterBarWidth = dashboardFiltersOpen
- ? adjustedFilterBarWidth
- : CLOSED_FILTER_BAR_WIDTH;
-
const [containerRef, isSticky] = useElementOnScreen<HTMLDivElement>({
threshold: [1],
});
@@ -425,35 +396,38 @@ const DashboardBuilder: FC<DashboardBuilderProps> = () =>
{
<StyledDiv>
{nativeFiltersEnabled && !editMode && (
<>
- <ResizableFilterBarWrapper>
- <Resizable
- enable={{ right: dashboardFiltersOpen }}
- handleClasses={{ right: 'filterbar-resizer' }}
- size={{ width: filterBarWidth, height: '100vh' }}
- minWidth={OPEN_FILTER_BAR_WIDTH}
- maxWidth={OPEN_FILTER_BAR_MAX_WIDTH}
- onResizeStop={(e, direction, ref, d) =>
- setAdjustedFilterBarWidth(filterBarWidth + d.width)
- }
- />
- </ResizableFilterBarWrapper>
- <FiltersPanel
- width={filterBarWidth}
- data-test="dashboard-filters-panel"
+ <ResizableSidebar
+ id={`dashboard:${dashboardId}`}
+ enable={dashboardFiltersOpen}
+ minWidth={OPEN_FILTER_BAR_WIDTH}
+ maxWidth={OPEN_FILTER_BAR_MAX_WIDTH}
+ initialWidth={OPEN_FILTER_BAR_WIDTH}
>
- <StickyPanel ref={containerRef} width={filterBarWidth}>
- <ErrorBoundary>
- <FilterBar
- filtersOpen={dashboardFiltersOpen}
- toggleFiltersBar={toggleDashboardFiltersOpen}
- directPathToChild={directPathToChild}
+ {adjustedWidth => {
+ const filterBarWidth = dashboardFiltersOpen
+ ? adjustedWidth
+ : CLOSED_FILTER_BAR_WIDTH;
+ return (
+ <FiltersPanel
width={filterBarWidth}
- height={filterBarHeight}
- offset={filterBarOffset}
- />
- </ErrorBoundary>
- </StickyPanel>
- </FiltersPanel>
+ data-test="dashboard-filters-panel"
+ >
+ <StickyPanel ref={containerRef} width={filterBarWidth}>
+ <ErrorBoundary>
+ <FilterBar
+ filtersOpen={dashboardFiltersOpen}
+ toggleFiltersBar={toggleDashboardFiltersOpen}
+ directPathToChild={directPathToChild}
+ width={filterBarWidth}
+ height={filterBarHeight}
+ offset={filterBarOffset}
+ />
+ </ErrorBoundary>
+ </StickyPanel>
+ </FiltersPanel>
+ );
+ }}
+ </ResizableSidebar>
</>
)}
<StyledHeader ref={headerRef}>
diff --git a/superset-frontend/src/utils/localStorageHelpers.ts
b/superset-frontend/src/utils/localStorageHelpers.ts
index ba9f1015cb..b6dad501f5 100644
--- a/superset-frontend/src/utils/localStorageHelpers.ts
+++ b/superset-frontend/src/utils/localStorageHelpers.ts
@@ -55,6 +55,7 @@ export enum LocalStorageKeys {
explore__data_table_original_formatted_time_columns =
'explore__data_table_original_formatted_time_columns',
dashboard__custom_filter_bar_widths = 'dashboard__custom_filter_bar_widths',
dashboard__explore_context = 'dashboard__explore_context',
+ common__resizable_sidebar_widths = 'common__resizable_sidebar_widths',
}
export type LocalStorageValues = {
@@ -73,6 +74,7 @@ export type LocalStorageValues = {
explore__data_table_original_formatted_time_columns: Record<string,
string[]>;
dashboard__custom_filter_bar_widths: Record<string, number>;
dashboard__explore_context: Record<string, DashboardContextForExplore>;
+ common__resizable_sidebar_widths: Record<string, number>;
};
/*