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>;
 };
 
 /*

Reply via email to