refactor(dashboard): [chart-maximize-mode]put chart full-size state in redux (#15384)

* refactor(dashboard): [chart-maximize-mode]put full-size status to redux

* fix: ci
This commit is contained in:
Yaozong Liu 2021-07-02 18:11:00 +08:00 committed by GitHub
parent cbc4aa8dc1
commit 81633e99ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 21 deletions

View File

@ -359,6 +359,11 @@ export function unsetFocusedFilterField(chartId, column) {
return { type: UNSET_FOCUSED_FILTER_FIELD, chartId, column }; return { type: UNSET_FOCUSED_FILTER_FIELD, chartId, column };
} }
export const SET_FULL_SIZE_CHART_ID = 'SET_FULL_SIZE_CHART_ID';
export function setFullSizeChartId(chartId) {
return { type: SET_FULL_SIZE_CHART_ID, chartId };
}
// Undo history --------------------------------------------------------------- // Undo history ---------------------------------------------------------------
export const SET_MAX_UNDO_HISTORY_EXCEEDED = 'SET_MAX_UNDO_HISTORY_EXCEEDED'; export const SET_MAX_UNDO_HISTORY_EXCEEDED = 'SET_MAX_UNDO_HISTORY_EXCEEDED';
export function setMaxUndoHistoryExceeded(maxUndoHistoryExceeded = true) { export function setMaxUndoHistoryExceeded(maxUndoHistoryExceeded = true) {

View File

@ -90,10 +90,12 @@ const StyledHeader = styled.div`
z-index: 2; z-index: 2;
`; `;
const StyledContent = styled.div` const StyledContent = styled.div<{
fullSizeChartId: number | null;
}>`
grid-column: 2; grid-column: 2;
grid-row: 2; grid-row: 2;
z-index: 1; z-index: ${({ fullSizeChartId }) => (fullSizeChartId ? 1000 : 1)};
`; `;
const StyledDashboardContent = styled.div<{ const StyledDashboardContent = styled.div<{
@ -147,6 +149,9 @@ const DashboardBuilder: FC<DashboardBuilderProps> = () => {
const directPathToChild = useSelector<RootState, string[]>( const directPathToChild = useSelector<RootState, string[]>(
state => state.dashboardState.directPathToChild, state => state.dashboardState.directPathToChild,
); );
const fullSizeChartId = useSelector<RootState, number | null>(
state => state.dashboardState.fullSizeChartId,
);
const handleChangeTab = ({ const handleChangeTab = ({
pathToTabIndex, pathToTabIndex,
@ -276,7 +281,7 @@ const DashboardBuilder: FC<DashboardBuilderProps> = () => {
)} )}
</DragDroppable> </DragDroppable>
</StyledHeader> </StyledHeader>
<StyledContent> <StyledContent fullSizeChartId={fullSizeChartId}>
<div <div
data-test="dashboard-content" data-test="dashboard-content"
className={cx('dashboard', editMode && 'dashboard--editing')} className={cx('dashboard', editMode && 'dashboard--editing')}

View File

@ -54,6 +54,7 @@ const propTypes = {
directPathToChild: PropTypes.arrayOf(PropTypes.string), directPathToChild: PropTypes.arrayOf(PropTypes.string),
directPathLastUpdated: PropTypes.number, directPathLastUpdated: PropTypes.number,
focusedFilterScope: PropTypes.object, focusedFilterScope: PropTypes.object,
fullSizeChartId: PropTypes.oneOf([PropTypes.number, null]),
// grid related // grid related
availableColumnCount: PropTypes.number.isRequired, availableColumnCount: PropTypes.number.isRequired,
@ -66,6 +67,7 @@ const propTypes = {
deleteComponent: PropTypes.func.isRequired, deleteComponent: PropTypes.func.isRequired,
updateComponents: PropTypes.func.isRequired, updateComponents: PropTypes.func.isRequired,
handleComponentDrop: PropTypes.func.isRequired, handleComponentDrop: PropTypes.func.isRequired,
setFullSizeChartId: PropTypes.func.isRequired,
}; };
const defaultProps = { const defaultProps = {
@ -189,7 +191,6 @@ class ChartHolder extends React.Component {
outlinedComponentId: null, outlinedComponentId: null,
outlinedColumnName: null, outlinedColumnName: null,
directPathLastUpdated: 0, directPathLastUpdated: 0,
isFullSize: false,
}; };
this.handleChangeFocus = this.handleChangeFocus.bind(this); this.handleChangeFocus = this.handleChangeFocus.bind(this);
@ -244,7 +245,10 @@ class ChartHolder extends React.Component {
} }
handleToggleFullSize() { handleToggleFullSize() {
this.setState(prevState => ({ isFullSize: !prevState.isFullSize })); const { component, fullSizeChartId, setFullSizeChartId } = this.props;
const { chartId } = component.meta;
const isFullSize = fullSizeChartId === chartId;
setFullSizeChartId(isFullSize ? null : chartId);
} }
render() { render() {
@ -263,8 +267,12 @@ class ChartHolder extends React.Component {
editMode, editMode,
isComponentVisible, isComponentVisible,
dashboardId, dashboardId,
fullSizeChartId,
} = this.props; } = this.props;
const { chartId } = component.meta;
const isFullSize = fullSizeChartId === chartId;
// inherit the size of parent columns // inherit the size of parent columns
const widthMultiple = const widthMultiple =
parentComponent.type === COLUMN_TYPE parentComponent.type === COLUMN_TYPE
@ -274,7 +282,7 @@ class ChartHolder extends React.Component {
let chartWidth = 0; let chartWidth = 0;
let chartHeight = 0; let chartHeight = 0;
if (this.state.isFullSize) { if (isFullSize) {
chartWidth = window.innerWidth - CHART_MARGIN; chartWidth = window.innerWidth - CHART_MARGIN;
chartHeight = window.innerHeight - CHART_MARGIN; chartHeight = window.innerHeight - CHART_MARGIN;
} else { } else {
@ -288,8 +296,6 @@ class ChartHolder extends React.Component {
); );
} }
const { chartId } = component.meta;
return ( return (
<DragDroppable <DragDroppable
component={component} component={component}
@ -326,7 +332,7 @@ class ChartHolder extends React.Component {
'dashboard-component', 'dashboard-component',
'dashboard-component-chart-holder', 'dashboard-component-chart-holder',
this.state.outlinedComponentId ? 'fade-in' : 'fade-out', this.state.outlinedComponentId ? 'fade-in' : 'fade-out',
this.state.isFullSize && 'full-size', isFullSize && 'full-size',
)} )}
> >
{!editMode && ( {!editMode && (
@ -351,7 +357,7 @@ class ChartHolder extends React.Component {
updateSliceName={this.handleUpdateSliceName} updateSliceName={this.handleUpdateSliceName}
isComponentVisible={isComponentVisible} isComponentVisible={isComponentVisible}
handleToggleFullSize={this.handleToggleFullSize} handleToggleFullSize={this.handleToggleFullSize}
isFullSize={this.state.isFullSize} isFullSize={isFullSize}
/> />
{editMode && ( {editMode && (
<HoverMenu position="top"> <HoverMenu position="top">

View File

@ -18,7 +18,6 @@
*/ */
import React from 'react'; import React from 'react';
import userEvent from '@testing-library/user-event';
import { waitFor } from '@testing-library/react'; import { waitFor } from '@testing-library/react';
import { sliceId as chartId } from 'spec/fixtures/mockChartQueries'; import { sliceId as chartId } from 'spec/fixtures/mockChartQueries';
import { nativeFiltersInfo } from 'spec/javascripts/dashboard/fixtures/mockNativeFilters'; import { nativeFiltersInfo } from 'spec/javascripts/dashboard/fixtures/mockNativeFilters';
@ -66,6 +65,8 @@ describe('ChartHolder', () => {
isComponentVisible: true, isComponentVisible: true,
dashboardId: 123, dashboardId: 123,
nativeFilters: nativeFiltersInfo.filters, nativeFilters: nativeFiltersInfo.filters,
fullSizeChartId: chartId,
setFullSizeChartId: () => {},
}; };
const mockStore = getMockStore({ const mockStore = getMockStore({
...initialState, ...initialState,
@ -79,19 +80,12 @@ describe('ChartHolder', () => {
</Provider>, </Provider>,
); );
it('toggle full size', async () => { it('should render full size', async () => {
renderWrapper(); renderWrapper();
let chart = (screen.getByTestId('slice-container') const chart = (screen.getByTestId('slice-container')
.firstChild as HTMLElement).style; .firstChild as HTMLElement).style;
expect(chart?.width).toBe('900px');
expect(chart?.height).toBe('26px');
userEvent.click(screen.getByRole('button'));
userEvent.click(screen.getByText('Maximize chart'));
chart = (screen.getByTestId('slice-container').firstChild as HTMLElement)
.style;
await waitFor(() => expect(chart?.width).toBe('992px')); await waitFor(() => expect(chart?.width).toBe('992px'));
expect(chart?.height).toBe('714px'); expect(chart?.height).toBe('714px');
}); });

View File

@ -35,7 +35,11 @@ import {
updateComponents, updateComponents,
handleComponentDrop, handleComponentDrop,
} from '../actions/dashboardLayout'; } from '../actions/dashboardLayout';
import { setDirectPathToChild, setActiveTabs } from '../actions/dashboardState'; import {
setDirectPathToChild,
setActiveTabs,
setFullSizeChartId,
} from '../actions/dashboardState';
const propTypes = { const propTypes = {
id: PropTypes.string, id: PropTypes.string,
@ -83,6 +87,7 @@ function mapStateToProps(
activeTabs: dashboardState.activeTabs, activeTabs: dashboardState.activeTabs,
directPathLastUpdated: dashboardState.directPathLastUpdated, directPathLastUpdated: dashboardState.directPathLastUpdated,
dashboardId: dashboardInfo.id, dashboardId: dashboardInfo.id,
fullSizeChartId: dashboardState.fullSizeChartId,
}; };
// rows and columns need more data about their child dimensions // rows and columns need more data about their child dimensions
@ -112,6 +117,7 @@ function mapDispatchToProps(dispatch) {
updateComponents, updateComponents,
handleComponentDrop, handleComponentDrop,
setDirectPathToChild, setDirectPathToChild,
setFullSizeChartId,
setActiveTabs, setActiveTabs,
logEvent, logEvent,
}, },

View File

@ -36,6 +36,7 @@ import {
SET_FOCUSED_FILTER_FIELD, SET_FOCUSED_FILTER_FIELD,
UNSET_FOCUSED_FILTER_FIELD, UNSET_FOCUSED_FILTER_FIELD,
SET_ACTIVE_TABS, SET_ACTIVE_TABS,
SET_FULL_SIZE_CHART_ID,
} from '../actions/dashboardState'; } from '../actions/dashboardState';
import { HYDRATE_DASHBOARD } from '../actions/hydrate'; import { HYDRATE_DASHBOARD } from '../actions/hydrate';
@ -165,6 +166,12 @@ export default function dashboardStateReducer(state = {}, action) {
focusedFilterField: null, focusedFilterField: null,
}; };
}, },
[SET_FULL_SIZE_CHART_ID]() {
return {
...state,
fullSizeChartId: action.chartId,
};
},
}; };
if (action.type in actionHandlers) { if (action.type in actionHandlers) {

View File

@ -56,6 +56,7 @@ export type DashboardState = {
editMode: boolean; editMode: boolean;
directPathToChild: string[]; directPathToChild: string[];
activeTabs: ActiveTabs; activeTabs: ActiveTabs;
fullSizeChartId: number | null;
}; };
export type DashboardInfo = { export type DashboardInfo = {
common: { common: {