mirror of
https://github.com/apache/superset.git
synced 2024-09-16 10:39:55 -04:00
feat(sqllab): Make LeftBar width resizable (#21300)
This commit is contained in:
parent
38782bb98a
commit
2d70ef670e
@ -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,
|
||||
|
@ -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}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
82
superset-frontend/src/components/ResizableSidebar/index.tsx
Normal file
82
superset-frontend/src/components/ResizableSidebar/index.tsx
Normal file
@ -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;
|
@ -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);
|
@ -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;
|
||||
}
|
@ -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)
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
@ -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,
|
||||
]);
|
||||
|
@ -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}>
|
||||
|
@ -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>;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user