chore: Refactor dashboard header to func component (#31029)
This commit is contained in:
parent
832fed1db5
commit
f8adaf66c1
|
|
@ -34,7 +34,7 @@ import { Global } from '@emotion/react';
|
|||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import ErrorBoundary from 'src/components/ErrorBoundary';
|
||||
import BuilderComponentPane from 'src/dashboard/components/BuilderComponentPane';
|
||||
import DashboardHeader from 'src/dashboard/containers/DashboardHeader';
|
||||
import DashboardHeader from 'src/dashboard/components/Header';
|
||||
import Icons from 'src/components/Icons';
|
||||
import IconButton from 'src/dashboard/components/IconButton';
|
||||
import { Droppable } from 'src/dashboard/components/dnd/DragDroppable';
|
||||
|
|
|
|||
|
|
@ -16,19 +16,17 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import * as redux from 'redux';
|
||||
import { render, screen, fireEvent } from 'spec/helpers/testing-library';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import { getExtensionsRegistry } from '@superset-ui/core';
|
||||
import { getExtensionsRegistry, JsonObject } from '@superset-ui/core';
|
||||
import setupExtensions from 'src/setup/setupExtensions';
|
||||
import getOwnerName from 'src/utils/getOwnerName';
|
||||
import { HeaderProps } from './types';
|
||||
import Header from '.';
|
||||
import { DASHBOARD_HEADER_ID } from '../../util/constants';
|
||||
|
||||
const createProps = () => ({
|
||||
addSuccessToast: jest.fn(),
|
||||
addDangerToast: jest.fn(),
|
||||
addWarningToast: jest.fn(),
|
||||
const initialState = {
|
||||
dashboardInfo: {
|
||||
id: 1,
|
||||
dash_edit_perm: false,
|
||||
|
|
@ -69,74 +67,69 @@ const createProps = () => ({
|
|||
userId: 1,
|
||||
username: 'admin',
|
||||
},
|
||||
reports: {},
|
||||
dashboardTitle: 'Dashboard Title',
|
||||
charts: {},
|
||||
layout: {},
|
||||
dashboardState: {
|
||||
sliceIds: [],
|
||||
expandedSlices: {},
|
||||
css: '',
|
||||
customCss: '',
|
||||
isStarred: false,
|
||||
isLoading: false,
|
||||
lastModifiedTime: 0,
|
||||
refreshFrequency: 0,
|
||||
shouldPersistRefreshFrequency: false,
|
||||
onSave: jest.fn(),
|
||||
onChange: jest.fn(),
|
||||
fetchFaveStar: jest.fn(),
|
||||
fetchCharts: jest.fn(),
|
||||
onRefresh: jest.fn(),
|
||||
saveFaveStar: jest.fn(),
|
||||
savePublished: jest.fn(),
|
||||
css: '',
|
||||
isStarred: false,
|
||||
isPublished: false,
|
||||
updateDashboardTitle: jest.fn(),
|
||||
editMode: false,
|
||||
setEditMode: jest.fn(),
|
||||
showBuilderPane: jest.fn(),
|
||||
updateCss: jest.fn(),
|
||||
setColorScheme: jest.fn(),
|
||||
setUnsavedChanges: jest.fn(),
|
||||
logEvent: jest.fn(),
|
||||
setRefreshFrequency: jest.fn(),
|
||||
hasUnsavedChanges: false,
|
||||
maxUndoHistoryExceeded: false,
|
||||
onUndo: jest.fn(),
|
||||
onRedo: jest.fn(),
|
||||
undoLength: 0,
|
||||
redoLength: 0,
|
||||
setMaxUndoHistoryExceeded: jest.fn(),
|
||||
maxUndoHistoryToast: jest.fn(),
|
||||
dashboardInfoChanged: jest.fn(),
|
||||
dashboardTitleChanged: jest.fn(),
|
||||
showMenuDropdown: true,
|
||||
});
|
||||
const props = createProps();
|
||||
const editableProps = {
|
||||
...props,
|
||||
editMode: false,
|
||||
lastModifiedTime: 0,
|
||||
},
|
||||
charts: {},
|
||||
dashboardLayout: {
|
||||
present: {
|
||||
[DASHBOARD_HEADER_ID]: {
|
||||
meta: {
|
||||
text: 'Dashboard Title',
|
||||
},
|
||||
},
|
||||
},
|
||||
past: [],
|
||||
future: [],
|
||||
},
|
||||
};
|
||||
|
||||
const editableState = {
|
||||
dashboardState: {
|
||||
...initialState.dashboardState,
|
||||
editMode: true,
|
||||
},
|
||||
dashboardInfo: {
|
||||
...props.dashboardInfo,
|
||||
...initialState.dashboardInfo,
|
||||
dash_edit_perm: true,
|
||||
dash_save_perm: true,
|
||||
},
|
||||
};
|
||||
const undoProps = {
|
||||
...editableProps,
|
||||
undoLength: 1,
|
||||
|
||||
const undoState = {
|
||||
...editableState,
|
||||
dashboardLayout: {
|
||||
...initialState.dashboardLayout,
|
||||
past: [{}],
|
||||
},
|
||||
};
|
||||
const redoProps = {
|
||||
...editableProps,
|
||||
redoLength: 1,
|
||||
|
||||
const redoState = {
|
||||
...editableState,
|
||||
dashboardLayout: {
|
||||
...initialState.dashboardLayout,
|
||||
future: [{}],
|
||||
},
|
||||
};
|
||||
|
||||
fetchMock.get('glob:*/csstemplateasyncmodelview/api/read', {});
|
||||
|
||||
function setup(props: HeaderProps, initialState = {}) {
|
||||
function setup(overrideState: JsonObject = {}) {
|
||||
return render(
|
||||
<div className="dashboard">
|
||||
<Header {...props} />
|
||||
<Header />
|
||||
</div>,
|
||||
{ useRedux: true, initialState },
|
||||
{ useRedux: true, initialState: { ...initialState, ...overrideState } },
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -146,173 +139,223 @@ async function openActionsDropdown() {
|
|||
expect(await screen.findByTestId('header-actions-menu')).toBeInTheDocument();
|
||||
}
|
||||
|
||||
const addSuccessToast = jest.fn();
|
||||
const addDangerToast = jest.fn();
|
||||
const addWarningToast = jest.fn();
|
||||
const onUndo = jest.fn();
|
||||
const onRedo = jest.fn();
|
||||
const setEditMode = jest.fn();
|
||||
const setUnsavedChanges = jest.fn();
|
||||
const fetchFaveStar = jest.fn();
|
||||
const saveFaveStar = jest.fn();
|
||||
const savePublished = jest.fn();
|
||||
const fetchCharts = jest.fn();
|
||||
const updateDashboardTitle = jest.fn();
|
||||
const updateCss = jest.fn();
|
||||
const onChange = jest.fn();
|
||||
const onSave = jest.fn();
|
||||
const setMaxUndoHistoryExceeded = jest.fn();
|
||||
const maxUndoHistoryToast = jest.fn();
|
||||
const logEvent = jest.fn();
|
||||
const setRefreshFrequency = jest.fn();
|
||||
const onRefresh = jest.fn();
|
||||
const dashboardInfoChanged = jest.fn();
|
||||
const dashboardTitleChanged = jest.fn();
|
||||
|
||||
beforeAll(() => {
|
||||
jest.spyOn(redux, 'bindActionCreators').mockImplementation(() => ({
|
||||
addSuccessToast,
|
||||
addDangerToast,
|
||||
addWarningToast,
|
||||
onUndo,
|
||||
onRedo,
|
||||
setEditMode,
|
||||
setUnsavedChanges,
|
||||
fetchFaveStar,
|
||||
saveFaveStar,
|
||||
savePublished,
|
||||
fetchCharts,
|
||||
updateDashboardTitle,
|
||||
updateCss,
|
||||
onChange,
|
||||
onSave,
|
||||
setMaxUndoHistoryExceeded,
|
||||
maxUndoHistoryToast,
|
||||
logEvent,
|
||||
setRefreshFrequency,
|
||||
onRefresh,
|
||||
dashboardInfoChanged,
|
||||
dashboardTitleChanged,
|
||||
}));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('should render', () => {
|
||||
const mockedProps = createProps();
|
||||
const { container } = setup(mockedProps);
|
||||
const { container } = setup();
|
||||
expect(container).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render the title', () => {
|
||||
const mockedProps = createProps();
|
||||
setup(mockedProps);
|
||||
setup();
|
||||
expect(screen.getByTestId('editable-title')).toHaveTextContent(
|
||||
'Dashboard Title',
|
||||
);
|
||||
});
|
||||
|
||||
test('should render the editable title', () => {
|
||||
setup(editableProps);
|
||||
setup(editableState);
|
||||
expect(screen.getByDisplayValue('Dashboard Title')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should edit the title', () => {
|
||||
setup(editableProps);
|
||||
setup(editableState);
|
||||
const editableTitle = screen.getByDisplayValue('Dashboard Title');
|
||||
expect(editableProps.onChange).not.toHaveBeenCalled();
|
||||
expect(onChange).not.toHaveBeenCalled();
|
||||
userEvent.click(editableTitle);
|
||||
userEvent.clear(editableTitle);
|
||||
userEvent.type(editableTitle, 'New Title');
|
||||
userEvent.click(document.body);
|
||||
expect(editableProps.onChange).toHaveBeenCalled();
|
||||
expect(onChange).toHaveBeenCalled();
|
||||
expect(screen.getByDisplayValue('New Title')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render the "Draft" status', () => {
|
||||
const mockedProps = createProps();
|
||||
setup(mockedProps);
|
||||
setup();
|
||||
expect(screen.getByText('Draft')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should publish', () => {
|
||||
const mockedProps = createProps();
|
||||
const canEditProps = {
|
||||
...mockedProps,
|
||||
const canEditState = {
|
||||
dashboardInfo: {
|
||||
...mockedProps.dashboardInfo,
|
||||
...initialState.dashboardInfo,
|
||||
dash_edit_perm: true,
|
||||
dash_save_perm: true,
|
||||
},
|
||||
};
|
||||
setup(canEditProps);
|
||||
setup(canEditState);
|
||||
const draft = screen.getByText('Draft');
|
||||
expect(mockedProps.savePublished).toHaveBeenCalledTimes(0);
|
||||
expect(savePublished).toHaveBeenCalledTimes(0);
|
||||
userEvent.click(draft);
|
||||
expect(mockedProps.savePublished).toHaveBeenCalledTimes(1);
|
||||
expect(savePublished).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should render metadata', () => {
|
||||
const mockedProps = createProps();
|
||||
setup(mockedProps);
|
||||
setup();
|
||||
expect(
|
||||
screen.getByText(getOwnerName(mockedProps.dashboardInfo.created_by)),
|
||||
screen.getByText(getOwnerName(initialState.dashboardInfo.created_by)),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(mockedProps.dashboardInfo.changed_on_delta_humanized),
|
||||
screen.getByText(initialState.dashboardInfo.changed_on_delta_humanized),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render the "Undo" action as disabled', () => {
|
||||
setup(editableProps);
|
||||
setup(editableState);
|
||||
expect(screen.getByTestId('undo-action').parentElement).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should undo', () => {
|
||||
setup(undoProps);
|
||||
setup(undoState);
|
||||
const undo = screen.getByTestId('undo-action');
|
||||
expect(undoProps.onUndo).not.toHaveBeenCalled();
|
||||
expect(onUndo).not.toHaveBeenCalled();
|
||||
userEvent.click(undo);
|
||||
expect(undoProps.onUndo).toHaveBeenCalledTimes(1);
|
||||
expect(onUndo).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should undo with key listener', () => {
|
||||
undoProps.onUndo.mockReset();
|
||||
setup(undoProps);
|
||||
expect(undoProps.onUndo).not.toHaveBeenCalled();
|
||||
onUndo.mockReset();
|
||||
setup(undoState);
|
||||
expect(onUndo).not.toHaveBeenCalled();
|
||||
fireEvent.keyDown(document.body, { key: 'z', code: 'KeyZ', ctrlKey: true });
|
||||
expect(undoProps.onUndo).toHaveBeenCalledTimes(1);
|
||||
expect(onUndo).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should render the "Redo" action as disabled', () => {
|
||||
setup(editableProps);
|
||||
setup(editableState);
|
||||
expect(screen.getByTestId('redo-action').parentElement).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should redo', () => {
|
||||
setup(redoProps);
|
||||
setup(redoState);
|
||||
const redo = screen.getByTestId('redo-action');
|
||||
expect(redoProps.onRedo).not.toHaveBeenCalled();
|
||||
expect(onRedo).not.toHaveBeenCalled();
|
||||
userEvent.click(redo);
|
||||
expect(redoProps.onRedo).toHaveBeenCalledTimes(1);
|
||||
expect(onRedo).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should redo with key listener', () => {
|
||||
redoProps.onRedo.mockReset();
|
||||
setup(redoProps);
|
||||
expect(redoProps.onRedo).not.toHaveBeenCalled();
|
||||
setup(redoState);
|
||||
expect(onRedo).not.toHaveBeenCalled();
|
||||
fireEvent.keyDown(document.body, { key: 'y', code: 'KeyY', ctrlKey: true });
|
||||
expect(redoProps.onRedo).toHaveBeenCalledTimes(1);
|
||||
expect(onRedo).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should render the "Discard changes" button', () => {
|
||||
setup(editableProps);
|
||||
setup(editableState);
|
||||
expect(screen.getByText('Discard')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render the "Save" button as disabled', () => {
|
||||
setup(editableProps);
|
||||
setup(editableState);
|
||||
expect(screen.getByText('Save').parentElement).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should save', () => {
|
||||
const unsavedProps = {
|
||||
...editableProps,
|
||||
const unsavedState = {
|
||||
...editableState,
|
||||
dashboardState: {
|
||||
...editableState.dashboardState,
|
||||
hasUnsavedChanges: true,
|
||||
},
|
||||
};
|
||||
setup(unsavedProps);
|
||||
setup(unsavedState);
|
||||
const save = screen.getByText('Save');
|
||||
expect(unsavedProps.onSave).not.toHaveBeenCalled();
|
||||
expect(onSave).not.toHaveBeenCalled();
|
||||
userEvent.click(save);
|
||||
expect(unsavedProps.onSave).toHaveBeenCalledTimes(1);
|
||||
expect(onSave).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should NOT render the "Draft" status', () => {
|
||||
const mockedProps = createProps();
|
||||
const publishedProps = {
|
||||
...mockedProps,
|
||||
const publishedState = {
|
||||
...initialState,
|
||||
dashboardState: {
|
||||
...initialState.dashboardState,
|
||||
isPublished: true,
|
||||
},
|
||||
};
|
||||
setup(publishedProps);
|
||||
setup(publishedState);
|
||||
expect(screen.queryByText('Draft')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render the unselected fave icon', () => {
|
||||
const mockedProps = createProps();
|
||||
setup(mockedProps);
|
||||
expect(mockedProps.fetchFaveStar).toHaveBeenCalled();
|
||||
setup();
|
||||
expect(fetchFaveStar).toHaveBeenCalled();
|
||||
expect(
|
||||
screen.getByRole('img', { name: 'favorite-unselected' }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render the selected fave icon', () => {
|
||||
const mockedProps = createProps();
|
||||
const favedProps = {
|
||||
...mockedProps,
|
||||
const favedState = {
|
||||
dashboardState: {
|
||||
...initialState.dashboardState,
|
||||
isStarred: true,
|
||||
},
|
||||
};
|
||||
setup(favedProps);
|
||||
setup(favedState);
|
||||
expect(
|
||||
screen.getByRole('img', { name: 'favorite-selected' }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should NOT render the fave icon on anonymous user', () => {
|
||||
const mockedProps = createProps();
|
||||
const anonymousUserProps = {
|
||||
...mockedProps,
|
||||
const anonymousUserState = {
|
||||
user: undefined,
|
||||
};
|
||||
setup(anonymousUserProps);
|
||||
setup(anonymousUserState);
|
||||
expect(() =>
|
||||
screen.getByRole('img', { name: 'favorite-unselected' }),
|
||||
).toThrow('Unable to find');
|
||||
|
|
@ -322,42 +365,37 @@ test('should NOT render the fave icon on anonymous user', () => {
|
|||
});
|
||||
|
||||
test('should fave', async () => {
|
||||
const mockedProps = createProps();
|
||||
setup(mockedProps);
|
||||
setup();
|
||||
const fave = screen.getByRole('img', { name: 'favorite-unselected' });
|
||||
expect(mockedProps.saveFaveStar).not.toHaveBeenCalled();
|
||||
expect(saveFaveStar).not.toHaveBeenCalled();
|
||||
userEvent.click(fave);
|
||||
expect(mockedProps.saveFaveStar).toHaveBeenCalledTimes(1);
|
||||
expect(saveFaveStar).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should toggle the edit mode', () => {
|
||||
const mockedProps = createProps();
|
||||
const canEditProps = {
|
||||
...mockedProps,
|
||||
const canEditState = {
|
||||
dashboardInfo: {
|
||||
...mockedProps.dashboardInfo,
|
||||
...initialState.dashboardInfo,
|
||||
dash_edit_perm: true,
|
||||
},
|
||||
};
|
||||
setup(canEditProps);
|
||||
setup(canEditState);
|
||||
const editDashboard = screen.getByText('Edit dashboard');
|
||||
expect(screen.queryByText('Edit dashboard')).toBeInTheDocument();
|
||||
userEvent.click(editDashboard);
|
||||
expect(mockedProps.logEvent).toHaveBeenCalled();
|
||||
expect(logEvent).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should render the dropdown icon', () => {
|
||||
const mockedProps = createProps();
|
||||
setup(mockedProps);
|
||||
setup();
|
||||
expect(screen.getByRole('img', { name: 'more-horiz' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should refresh the charts', async () => {
|
||||
const mockedProps = createProps();
|
||||
setup(mockedProps);
|
||||
setup();
|
||||
await openActionsDropdown();
|
||||
userEvent.click(screen.getByText('Refresh dashboard'));
|
||||
expect(mockedProps.onRefresh).toHaveBeenCalledTimes(1);
|
||||
expect(onRefresh).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('should render an extension component if one is supplied', () => {
|
||||
|
|
@ -367,54 +405,48 @@ test('should render an extension component if one is supplied', () => {
|
|||
));
|
||||
setupExtensions();
|
||||
|
||||
const mockedProps = createProps();
|
||||
setup(mockedProps);
|
||||
setup();
|
||||
expect(
|
||||
screen.getByText('dashboard.nav.right extension component'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should NOT render MetadataBar when in edit mode', () => {
|
||||
const mockedProps = {
|
||||
...createProps(),
|
||||
editMode: true,
|
||||
const state = {
|
||||
...editableState,
|
||||
dashboardInfo: {
|
||||
...createProps().dashboardInfo,
|
||||
...initialState.dashboardInfo,
|
||||
userId: '123',
|
||||
},
|
||||
};
|
||||
setup(mockedProps);
|
||||
setup(state);
|
||||
expect(
|
||||
screen.queryByText(mockedProps.dashboardInfo.changed_on_delta_humanized),
|
||||
screen.queryByText(state.dashboardInfo.changed_on_delta_humanized),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should NOT render MetadataBar when embedded', () => {
|
||||
const mockedProps = {
|
||||
...createProps(),
|
||||
editMode: false,
|
||||
const state = {
|
||||
dashboardInfo: {
|
||||
...createProps().dashboardInfo,
|
||||
...initialState.dashboardInfo,
|
||||
userId: undefined,
|
||||
},
|
||||
};
|
||||
setup(mockedProps);
|
||||
setup(state);
|
||||
expect(
|
||||
screen.queryByText(mockedProps.dashboardInfo.changed_on_delta_humanized),
|
||||
screen.queryByText(state.dashboardInfo.changed_on_delta_humanized),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render MetadataBar when not in edit mode and not embedded', () => {
|
||||
const mockedProps = {
|
||||
...createProps(),
|
||||
editMode: false,
|
||||
const state = {
|
||||
dashboardInfo: {
|
||||
...createProps().dashboardInfo,
|
||||
...initialState.dashboardInfo,
|
||||
userId: '123',
|
||||
},
|
||||
};
|
||||
setup(mockedProps);
|
||||
setup(state);
|
||||
expect(
|
||||
screen.getByText(mockedProps.dashboardInfo.changed_on_delta_humanized),
|
||||
screen.getByText(state.dashboardInfo.changed_on_delta_humanized),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,137 +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 { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { updateDataMask } from 'src/dataMask/actions';
|
||||
import DashboardHeader from 'src/dashboard/components/Header';
|
||||
import isDashboardLoading from 'src/dashboard/util/isDashboardLoading';
|
||||
|
||||
import { dashboardInfoChanged } from 'src/dashboard/actions/dashboardInfo';
|
||||
|
||||
import {
|
||||
setEditMode,
|
||||
showBuilderPane,
|
||||
fetchFaveStar,
|
||||
saveFaveStar,
|
||||
savePublished,
|
||||
setColorScheme,
|
||||
setUnsavedChanges,
|
||||
fetchCharts,
|
||||
updateCss,
|
||||
onChange,
|
||||
saveDashboardRequest,
|
||||
setMaxUndoHistoryExceeded,
|
||||
maxUndoHistoryToast,
|
||||
setRefreshFrequency,
|
||||
onRefresh,
|
||||
} from 'src/dashboard/actions/dashboardState';
|
||||
|
||||
import {
|
||||
undoLayoutAction,
|
||||
redoLayoutAction,
|
||||
updateDashboardTitle,
|
||||
dashboardTitleChanged,
|
||||
} from 'src/dashboard/actions/dashboardLayout';
|
||||
import {
|
||||
addSuccessToast,
|
||||
addDangerToast,
|
||||
addWarningToast,
|
||||
} from 'src/components/MessageToasts/actions';
|
||||
|
||||
import { logEvent } from 'src/logger/actions';
|
||||
import { DASHBOARD_HEADER_ID } from 'src/dashboard/util/constants';
|
||||
|
||||
function mapStateToProps({
|
||||
dashboardLayout: undoableLayout,
|
||||
dashboardState,
|
||||
reports,
|
||||
dashboardInfo,
|
||||
charts,
|
||||
dataMask,
|
||||
user,
|
||||
}) {
|
||||
return {
|
||||
dashboardInfo,
|
||||
undoLength: undoableLayout.past.length,
|
||||
redoLength: undoableLayout.future.length,
|
||||
layout: undoableLayout.present,
|
||||
dashboardTitle: (
|
||||
(undoableLayout.present[DASHBOARD_HEADER_ID] || {}).meta || {}
|
||||
).text,
|
||||
expandedSlices: dashboardState.expandedSlices,
|
||||
refreshFrequency: dashboardState.refreshFrequency,
|
||||
shouldPersistRefreshFrequency:
|
||||
!!dashboardState.shouldPersistRefreshFrequency,
|
||||
customCss: dashboardState.css,
|
||||
colorNamespace: dashboardState.colorNamespace,
|
||||
colorScheme: dashboardState.colorScheme,
|
||||
charts,
|
||||
dataMask,
|
||||
user,
|
||||
isStarred: !!dashboardState.isStarred,
|
||||
isPublished: !!dashboardState.isPublished,
|
||||
isLoading: isDashboardLoading(charts),
|
||||
hasUnsavedChanges: !!dashboardState.hasUnsavedChanges,
|
||||
maxUndoHistoryExceeded: !!dashboardState.maxUndoHistoryExceeded,
|
||||
lastModifiedTime: Math.max(
|
||||
dashboardState.lastModifiedTime,
|
||||
dashboardInfo.last_modified_time,
|
||||
),
|
||||
editMode: !!dashboardState.editMode,
|
||||
slug: dashboardInfo.slug,
|
||||
metadata: dashboardInfo.metadata,
|
||||
reports,
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(
|
||||
{
|
||||
addSuccessToast,
|
||||
addDangerToast,
|
||||
addWarningToast,
|
||||
onUndo: undoLayoutAction,
|
||||
onRedo: redoLayoutAction,
|
||||
setEditMode,
|
||||
showBuilderPane,
|
||||
setColorScheme,
|
||||
setUnsavedChanges,
|
||||
fetchFaveStar,
|
||||
saveFaveStar,
|
||||
savePublished,
|
||||
fetchCharts,
|
||||
updateDashboardTitle,
|
||||
updateCss,
|
||||
onChange,
|
||||
onSave: saveDashboardRequest,
|
||||
setMaxUndoHistoryExceeded,
|
||||
maxUndoHistoryToast,
|
||||
logEvent,
|
||||
setRefreshFrequency,
|
||||
onRefresh,
|
||||
dashboardInfoChanged,
|
||||
dashboardTitleChanged,
|
||||
updateDataMask,
|
||||
},
|
||||
dispatch,
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(DashboardHeader);
|
||||
Loading…
Reference in New Issue