mirror of
https://github.com/apache/superset.git
synced 2024-09-12 08:39:45 -04:00
test: Add tests for Dashboard Header and HeaderActionsDropdown components (#13973)
* Add tests for HeaderActionsDropdown - WIP * Fix trigger node * Add types * Clean up * Add tests for Header * Delete obsolete tests * Add factory and clean up * Add opposite case * Fix file name * Include latest changes
This commit is contained in:
parent
a548b69201
commit
474f1e2044
@ -1,174 +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 React from 'react';
|
|
||||||
import { shallow } from 'enzyme';
|
|
||||||
import { Menu, NoAnimationDropdown } from 'src/common/components';
|
|
||||||
import RefreshIntervalModal from 'src/dashboard/components/RefreshIntervalModal';
|
|
||||||
import HeaderActionsDropdown from 'src/dashboard/components/HeaderActionsDropdown';
|
|
||||||
import SaveModal from 'src/dashboard/components/SaveModal';
|
|
||||||
import CssEditor from 'src/dashboard/components/CssEditor';
|
|
||||||
import fetchMock from 'fetch-mock';
|
|
||||||
import ShareMenuItems from 'src/dashboard/components/menu/ShareMenuItems';
|
|
||||||
|
|
||||||
fetchMock.get('glob:*/csstemplateasyncmodelview/api/read', {});
|
|
||||||
|
|
||||||
describe('HeaderActionsDropdown', () => {
|
|
||||||
const props = {
|
|
||||||
addSuccessToast: () => {},
|
|
||||||
addDangerToast: () => {},
|
|
||||||
customCss: '',
|
|
||||||
dashboardId: 1,
|
|
||||||
dashboardInfo: {},
|
|
||||||
dashboardTitle: 'Title',
|
|
||||||
editMode: false,
|
|
||||||
expandedSlices: {},
|
|
||||||
filters: {},
|
|
||||||
forceRefreshAllCharts: () => {},
|
|
||||||
hasUnsavedChanges: false,
|
|
||||||
isLoading: false,
|
|
||||||
layout: {},
|
|
||||||
onChange: () => {},
|
|
||||||
onSave: () => {},
|
|
||||||
refreshFrequency: 200,
|
|
||||||
setRefreshFrequency: () => {},
|
|
||||||
shouldPersistRefreshFrequency: true,
|
|
||||||
showPropertiesModal: () => {},
|
|
||||||
startPeriodicRender: () => {},
|
|
||||||
updateCss: () => {},
|
|
||||||
userCanEdit: false,
|
|
||||||
userCanSave: false,
|
|
||||||
lastModifiedTime: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
function setup(overrideProps) {
|
|
||||||
const wrapper = shallow(
|
|
||||||
<HeaderActionsDropdown {...props} {...overrideProps} />,
|
|
||||||
);
|
|
||||||
const menu = shallow(
|
|
||||||
<div>{wrapper.find(NoAnimationDropdown).props().overlay}</div>,
|
|
||||||
);
|
|
||||||
return { wrapper, menu };
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('readonly-user', () => {
|
|
||||||
const overrideProps = { userCanSave: false, userCanShare: false };
|
|
||||||
|
|
||||||
it('should render the DropdownButton', () => {
|
|
||||||
const { wrapper } = setup(overrideProps);
|
|
||||||
expect(wrapper.find(NoAnimationDropdown)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not render the SaveModal', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(SaveModal)).not.toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render available Menu items', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(Menu.Item)).toHaveLength(4);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the RefreshIntervalModal', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(RefreshIntervalModal)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not render the ShareMenuItems', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(ShareMenuItems)).not.toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not render the CssEditor', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(CssEditor)).not.toExist();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('write-user', () => {
|
|
||||||
const overrideProps = { userCanSave: true, userCanShare: true };
|
|
||||||
|
|
||||||
it('should render the DropdownButton', () => {
|
|
||||||
const { wrapper } = setup(overrideProps);
|
|
||||||
expect(wrapper.find(NoAnimationDropdown)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the SaveModal', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(SaveModal)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render available Menu items', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(Menu.Item)).toHaveLength(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the RefreshIntervalModal', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(RefreshIntervalModal)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the ShareMenuItems', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(ShareMenuItems)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not render the CssEditor', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(CssEditor)).not.toExist();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('write-user-with-edit-mode', () => {
|
|
||||||
const overrideProps = {
|
|
||||||
userCanSave: true,
|
|
||||||
editMode: true,
|
|
||||||
userCanShare: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should render the DropdownButton', () => {
|
|
||||||
const { wrapper } = setup(overrideProps);
|
|
||||||
expect(wrapper.find(NoAnimationDropdown)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the SaveModal', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(SaveModal)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render available MenuItems', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(Menu.Item)).toHaveLength(6);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the RefreshIntervalModal', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(RefreshIntervalModal)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the ShareMenuItems', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(ShareMenuItems)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the CssEditor', () => {
|
|
||||||
const { menu } = setup(overrideProps);
|
|
||||||
expect(menu.find(CssEditor)).toExist();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,244 +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 React from 'react';
|
|
||||||
import { styledMount as mount } from 'spec/helpers/theming';
|
|
||||||
import Header from 'src/dashboard/components/Header';
|
|
||||||
import EditableTitle from 'src/components/EditableTitle';
|
|
||||||
import FaveStar from 'src/components/FaveStar';
|
|
||||||
import PublishedStatus from 'src/dashboard/components/PublishedStatus';
|
|
||||||
import HeaderActionsDropdown from 'src/dashboard/components/HeaderActionsDropdown';
|
|
||||||
import Button from 'src/components/Button';
|
|
||||||
import UndoRedoKeyListeners from 'src/dashboard/components/UndoRedoKeyListeners';
|
|
||||||
|
|
||||||
describe('Header', () => {
|
|
||||||
const props = {
|
|
||||||
addSuccessToast: () => {},
|
|
||||||
addDangerToast: () => {},
|
|
||||||
addWarningToast: () => {},
|
|
||||||
dashboardInfo: {
|
|
||||||
id: 1,
|
|
||||||
dash_edit_perm: true,
|
|
||||||
dash_save_perm: true,
|
|
||||||
userId: 1,
|
|
||||||
metadata: {},
|
|
||||||
common: {
|
|
||||||
conf: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
dashboardTitle: 'title',
|
|
||||||
charts: {},
|
|
||||||
layout: {},
|
|
||||||
filters: {},
|
|
||||||
expandedSlices: {},
|
|
||||||
css: '',
|
|
||||||
customCss: '',
|
|
||||||
isStarred: false,
|
|
||||||
isLoading: false,
|
|
||||||
lastModifiedTime: 0,
|
|
||||||
refreshFrequency: 0,
|
|
||||||
shouldPersistRefreshFrequency: false,
|
|
||||||
onSave: () => {},
|
|
||||||
onChange: () => {},
|
|
||||||
fetchFaveStar: () => {},
|
|
||||||
fetchCharts: () => {},
|
|
||||||
saveFaveStar: () => {},
|
|
||||||
savePublished: () => {},
|
|
||||||
isPublished: false,
|
|
||||||
updateDashboardTitle: () => {},
|
|
||||||
editMode: false,
|
|
||||||
setEditMode: () => {},
|
|
||||||
showBuilderPane: () => {},
|
|
||||||
updateCss: () => {},
|
|
||||||
setColorSchemeAndUnsavedChanges: () => {},
|
|
||||||
logEvent: () => {},
|
|
||||||
setRefreshFrequency: () => {},
|
|
||||||
hasUnsavedChanges: false,
|
|
||||||
maxUndoHistoryExceeded: false,
|
|
||||||
|
|
||||||
// redux
|
|
||||||
onUndo: () => {},
|
|
||||||
onRedo: () => {},
|
|
||||||
undoLength: 0,
|
|
||||||
redoLength: 0,
|
|
||||||
setMaxUndoHistoryExceeded: () => {},
|
|
||||||
maxUndoHistoryToast: () => {},
|
|
||||||
dashboardInfoChanged: () => {},
|
|
||||||
dashboardTitleChanged: () => {},
|
|
||||||
};
|
|
||||||
|
|
||||||
function setup(overrideProps) {
|
|
||||||
const wrapper = mount(<Header {...props} {...overrideProps} />);
|
|
||||||
return wrapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('read-only-user', () => {
|
|
||||||
const overrideProps = {
|
|
||||||
dashboardInfo: {
|
|
||||||
...props.dashboardInfo,
|
|
||||||
id: 1,
|
|
||||||
dash_edit_perm: false,
|
|
||||||
dash_save_perm: false,
|
|
||||||
userId: 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should render the EditableTitle', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(EditableTitle)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the PublishedStatus', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(PublishedStatus)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the FaveStar', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(FaveStar)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the HeaderActionsDropdown', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(HeaderActionsDropdown)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not set up undo/redo', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(UndoRedoKeyListeners)).not.toExist();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('write-user', () => {
|
|
||||||
const overrideProps = {
|
|
||||||
editMode: false,
|
|
||||||
dashboardInfo: {
|
|
||||||
...props.dashboardInfo,
|
|
||||||
id: 1,
|
|
||||||
dash_edit_perm: true,
|
|
||||||
dash_save_perm: true,
|
|
||||||
userId: 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should render the EditableTitle', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(EditableTitle)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the PublishedStatus', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(PublishedStatus)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the FaveStar', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(FaveStar)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the HeaderActionsDropdown', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(HeaderActionsDropdown)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not set up undo/redo', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(UndoRedoKeyListeners)).not.toExist();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('write-user-with-edit-mode', () => {
|
|
||||||
const overrideProps = {
|
|
||||||
editMode: true,
|
|
||||||
dashboardInfo: {
|
|
||||||
...props.dashboardInfo,
|
|
||||||
id: 1,
|
|
||||||
dash_edit_perm: true,
|
|
||||||
dash_save_perm: true,
|
|
||||||
userId: 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should render the EditableTitle', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(EditableTitle)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the FaveStar', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(FaveStar)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the PublishedStatus', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(PublishedStatus)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the HeaderActionsDropdown', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(HeaderActionsDropdown)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render five Buttons', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(Button)).toHaveLength(4);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set up undo/redo', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(UndoRedoKeyListeners)).toExist();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('logged-out-user', () => {
|
|
||||||
const overrideProps = {
|
|
||||||
dashboardInfo: {
|
|
||||||
...props.dashboardInfo,
|
|
||||||
id: 1,
|
|
||||||
dash_edit_perm: false,
|
|
||||||
dash_save_perm: false,
|
|
||||||
userId: null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should render the EditableTitle', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(EditableTitle)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the PublishedStatus', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(PublishedStatus)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not render the FaveStar', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(FaveStar)).not.toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render the HeaderActionsDropdown', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(HeaderActionsDropdown)).toExist();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not set up undo/redo', () => {
|
|
||||||
const wrapper = setup(overrideProps);
|
|
||||||
expect(wrapper.find(UndoRedoKeyListeners)).not.toExist();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -0,0 +1,288 @@
|
|||||||
|
/**
|
||||||
|
* 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 { render, screen, fireEvent } from 'spec/helpers/testing-library';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import fetchMock from 'fetch-mock';
|
||||||
|
import { HeaderProps } from './types';
|
||||||
|
import Header from '.';
|
||||||
|
|
||||||
|
const createProps = () => ({
|
||||||
|
addSuccessToast: jest.fn(),
|
||||||
|
addDangerToast: jest.fn(),
|
||||||
|
addWarningToast: jest.fn(),
|
||||||
|
dashboardInfo: {
|
||||||
|
id: 1,
|
||||||
|
dash_edit_perm: false,
|
||||||
|
dash_save_perm: false,
|
||||||
|
dash_share_perm: false,
|
||||||
|
userId: 1,
|
||||||
|
metadata: {},
|
||||||
|
common: {
|
||||||
|
conf: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dashboardTitle: 'Dashboard Title',
|
||||||
|
charts: {},
|
||||||
|
layout: {},
|
||||||
|
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(),
|
||||||
|
saveFaveStar: jest.fn(),
|
||||||
|
savePublished: jest.fn(),
|
||||||
|
isPublished: false,
|
||||||
|
updateDashboardTitle: jest.fn(),
|
||||||
|
editMode: false,
|
||||||
|
setEditMode: jest.fn(),
|
||||||
|
showBuilderPane: jest.fn(),
|
||||||
|
updateCss: jest.fn(),
|
||||||
|
setColorSchemeAndUnsavedChanges: 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(),
|
||||||
|
});
|
||||||
|
const props = createProps();
|
||||||
|
const editableProps = {
|
||||||
|
...props,
|
||||||
|
editMode: true,
|
||||||
|
dashboardInfo: {
|
||||||
|
...props.dashboardInfo,
|
||||||
|
dash_edit_perm: true,
|
||||||
|
dash_save_perm: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const undoProps = {
|
||||||
|
...editableProps,
|
||||||
|
undoLength: 1,
|
||||||
|
};
|
||||||
|
const redoProps = {
|
||||||
|
...editableProps,
|
||||||
|
redoLength: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchMock.get('glob:*/csstemplateasyncmodelview/api/read', {});
|
||||||
|
|
||||||
|
function setup(props: HeaderProps) {
|
||||||
|
return (
|
||||||
|
<div className="dashboard">
|
||||||
|
<Header {...props} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openActionsDropdown() {
|
||||||
|
const btn = screen.getByRole('img', { name: 'more-horiz' });
|
||||||
|
userEvent.click(btn);
|
||||||
|
expect(await screen.findByRole('menu')).toBeInTheDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
test('should render', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
const { container } = render(setup(mockedProps));
|
||||||
|
expect(container).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the title', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
expect(screen.getByText('Dashboard Title')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the editable title', () => {
|
||||||
|
render(setup(editableProps));
|
||||||
|
expect(screen.getByDisplayValue('Dashboard Title')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should edit the title', () => {
|
||||||
|
render(setup(editableProps));
|
||||||
|
const editableTitle = screen.getByDisplayValue('Dashboard Title');
|
||||||
|
expect(editableProps.onChange).not.toHaveBeenCalled();
|
||||||
|
userEvent.click(editableTitle);
|
||||||
|
userEvent.clear(editableTitle);
|
||||||
|
userEvent.type(editableTitle, 'New Title');
|
||||||
|
userEvent.click(document.body);
|
||||||
|
expect(editableProps.onChange).toHaveBeenCalled();
|
||||||
|
expect(screen.getByDisplayValue('New Title')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the "Draft" status', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
expect(screen.getByText('Draft')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should publish', () => {
|
||||||
|
render(setup(editableProps));
|
||||||
|
const draft = screen.getByText('Draft');
|
||||||
|
expect(editableProps.savePublished).not.toHaveBeenCalled();
|
||||||
|
userEvent.click(draft);
|
||||||
|
expect(editableProps.savePublished).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the "Undo" action as disabled', () => {
|
||||||
|
render(setup(editableProps));
|
||||||
|
expect(screen.getByTitle('Undo').parentElement).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should undo', () => {
|
||||||
|
render(setup(undoProps));
|
||||||
|
const undo = screen.getByTitle('Undo');
|
||||||
|
expect(undoProps.onUndo).not.toHaveBeenCalled();
|
||||||
|
userEvent.click(undo);
|
||||||
|
expect(undoProps.onUndo).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should undo with key listener', () => {
|
||||||
|
undoProps.onUndo.mockReset();
|
||||||
|
render(setup(undoProps));
|
||||||
|
expect(undoProps.onUndo).not.toHaveBeenCalled();
|
||||||
|
fireEvent.keyDown(document.body, { key: 'z', code: 'KeyZ', ctrlKey: true });
|
||||||
|
expect(undoProps.onUndo).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the "Redo" action as disabled', () => {
|
||||||
|
render(setup(editableProps));
|
||||||
|
expect(screen.getByTitle('Redo').parentElement).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should redo', () => {
|
||||||
|
render(setup(redoProps));
|
||||||
|
const redo = screen.getByTitle('Redo');
|
||||||
|
expect(redoProps.onRedo).not.toHaveBeenCalled();
|
||||||
|
userEvent.click(redo);
|
||||||
|
expect(redoProps.onRedo).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should redo with key listener', () => {
|
||||||
|
redoProps.onRedo.mockReset();
|
||||||
|
render(setup(redoProps));
|
||||||
|
expect(redoProps.onRedo).not.toHaveBeenCalled();
|
||||||
|
fireEvent.keyDown(document.body, { key: 'y', code: 'KeyY', ctrlKey: true });
|
||||||
|
expect(redoProps.onRedo).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the "Discard changes" button', () => {
|
||||||
|
render(setup(editableProps));
|
||||||
|
expect(screen.getByText('Discard changes')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the "Save" button as disabled', () => {
|
||||||
|
render(setup(editableProps));
|
||||||
|
expect(screen.getByText('Save').parentElement).toBeDisabled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should save', () => {
|
||||||
|
const unsavedProps = {
|
||||||
|
...editableProps,
|
||||||
|
hasUnsavedChanges: true,
|
||||||
|
};
|
||||||
|
render(setup(unsavedProps));
|
||||||
|
const save = screen.getByText('Save');
|
||||||
|
expect(unsavedProps.onSave).not.toHaveBeenCalled();
|
||||||
|
userEvent.click(save);
|
||||||
|
expect(unsavedProps.onSave).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should NOT render the "Draft" status', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
const publishedProps = {
|
||||||
|
...mockedProps,
|
||||||
|
isPublished: true,
|
||||||
|
};
|
||||||
|
render(setup(publishedProps));
|
||||||
|
expect(screen.queryByText('Draft')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the unselected fave icon', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
expect(mockedProps.fetchFaveStar).toHaveBeenCalled();
|
||||||
|
expect(
|
||||||
|
screen.getByRole('img', { name: 'favorite-unselected' }),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the selected fave icon', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
const favedProps = {
|
||||||
|
...mockedProps,
|
||||||
|
isStarred: true,
|
||||||
|
};
|
||||||
|
render(setup(favedProps));
|
||||||
|
expect(
|
||||||
|
screen.getByRole('img', { name: 'favorite-selected' }),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should fave', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
const fave = screen.getByRole('img', { name: 'favorite-unselected' });
|
||||||
|
expect(mockedProps.saveFaveStar).not.toHaveBeenCalled();
|
||||||
|
userEvent.click(fave);
|
||||||
|
expect(mockedProps.saveFaveStar).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should toggle the edit mode', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
const canEditProps = {
|
||||||
|
...mockedProps,
|
||||||
|
dashboardInfo: {
|
||||||
|
...mockedProps.dashboardInfo,
|
||||||
|
dash_edit_perm: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
render(setup(canEditProps));
|
||||||
|
const editDashboard = screen.getByTitle('Edit dashboard');
|
||||||
|
expect(screen.queryByTitle('Edit dashboard')).toBeInTheDocument();
|
||||||
|
userEvent.click(editDashboard);
|
||||||
|
expect(mockedProps.logEvent).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the dropdown icon', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
expect(screen.getByRole('img', { name: 'more-horiz' })).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should refresh the charts', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
await openActionsDropdown();
|
||||||
|
userEvent.click(screen.getByText('Refresh dashboard'));
|
||||||
|
expect(mockedProps.fetchCharts).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
@ -0,0 +1,200 @@
|
|||||||
|
/**
|
||||||
|
* 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 { render, screen } from 'spec/helpers/testing-library';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import fetchMock from 'fetch-mock';
|
||||||
|
import { HeaderDropdownProps } from 'src/dashboard/components/Header/types';
|
||||||
|
import HeaderActionsDropdown from '.';
|
||||||
|
|
||||||
|
const createProps = () => ({
|
||||||
|
addSuccessToast: jest.fn(),
|
||||||
|
addDangerToast: jest.fn(),
|
||||||
|
customCss: '#save-dash-split-button{margin-left: 100px;}',
|
||||||
|
dashboardId: 1,
|
||||||
|
dashboardInfo: {
|
||||||
|
id: 1,
|
||||||
|
dash_edit_perm: true,
|
||||||
|
dash_save_perm: true,
|
||||||
|
userId: 1,
|
||||||
|
metadata: {},
|
||||||
|
common: {
|
||||||
|
conf: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dashboardTitle: 'Title',
|
||||||
|
editMode: false,
|
||||||
|
expandedSlices: {},
|
||||||
|
forceRefreshAllCharts: jest.fn(),
|
||||||
|
hasUnsavedChanges: false,
|
||||||
|
isLoading: false,
|
||||||
|
layout: {},
|
||||||
|
onChange: jest.fn(),
|
||||||
|
onSave: jest.fn(),
|
||||||
|
refreshFrequency: 200,
|
||||||
|
setRefreshFrequency: jest.fn(),
|
||||||
|
shouldPersistRefreshFrequency: false,
|
||||||
|
showPropertiesModal: jest.fn(),
|
||||||
|
startPeriodicRender: jest.fn(),
|
||||||
|
updateCss: jest.fn(),
|
||||||
|
userCanEdit: false,
|
||||||
|
userCanSave: false,
|
||||||
|
userCanShare: false,
|
||||||
|
lastModifiedTime: 0,
|
||||||
|
});
|
||||||
|
const editModeOnProps = {
|
||||||
|
...createProps(),
|
||||||
|
editMode: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
function setup(props: HeaderDropdownProps) {
|
||||||
|
return (
|
||||||
|
<div className="dashboard">
|
||||||
|
<HeaderActionsDropdown {...props} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchMock.get('glob:*/csstemplateasyncmodelview/api/read', {});
|
||||||
|
|
||||||
|
async function openDropdown() {
|
||||||
|
const btn = screen.getByRole('img', { name: 'more-horiz' });
|
||||||
|
userEvent.click(btn);
|
||||||
|
expect(await screen.findByRole('menu')).toBeInTheDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
test('should render', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
const { container } = render(setup(mockedProps));
|
||||||
|
expect(container).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the dropdown button', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
expect(screen.getByRole('button')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the dropdown icon', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
expect(screen.getByRole('img', { name: 'more-horiz' })).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should open the dropdown', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
await openDropdown();
|
||||||
|
expect(await screen.findByRole('menu')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the menu items', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
await openDropdown();
|
||||||
|
expect(screen.getAllByRole('menuitem')).toHaveLength(4);
|
||||||
|
expect(screen.getByText('Refresh dashboard')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Download as image')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Toggle fullscreen')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the menu items in edit mode', async () => {
|
||||||
|
render(setup(editModeOnProps));
|
||||||
|
await openDropdown();
|
||||||
|
expect(screen.getAllByRole('menuitem')).toHaveLength(5);
|
||||||
|
expect(screen.getByText('Refresh dashboard')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Set filter mapping')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Edit dashboard properties')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Edit CSS')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should show the share actions', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
const canShareProps = {
|
||||||
|
...mockedProps,
|
||||||
|
userCanShare: true,
|
||||||
|
};
|
||||||
|
render(setup(canShareProps));
|
||||||
|
await openDropdown();
|
||||||
|
expect(screen.getByText('Copy dashboard URL')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Share dashboard by email')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the "Save Modal" when user can save', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
const canSaveProps = {
|
||||||
|
...mockedProps,
|
||||||
|
userCanSave: true,
|
||||||
|
};
|
||||||
|
render(setup(canSaveProps));
|
||||||
|
await openDropdown();
|
||||||
|
expect(screen.getByText('Save as')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should NOT render the "Save Modal" menu item when user cannot save', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
await openDropdown();
|
||||||
|
expect(screen.queryByText('Save as')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render the "Refresh dashboard" menu item as disabled when loading', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
const loadingProps = {
|
||||||
|
...mockedProps,
|
||||||
|
isLoading: true,
|
||||||
|
};
|
||||||
|
render(setup(loadingProps));
|
||||||
|
await openDropdown();
|
||||||
|
expect(screen.getByText('Refresh dashboard')).toHaveClass(
|
||||||
|
'ant-dropdown-menu-item-disabled',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should NOT render the "Refresh dashboard" menu item as disabled', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
await openDropdown();
|
||||||
|
expect(screen.getByText('Refresh dashboard')).not.toHaveClass(
|
||||||
|
'ant-dropdown-menu-item-disabled',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render with custom css', () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
expect(screen.getByRole('button')).toHaveStyle('margin-left: 100px');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should refresh the charts', async () => {
|
||||||
|
const mockedProps = createProps();
|
||||||
|
render(setup(mockedProps));
|
||||||
|
await openDropdown();
|
||||||
|
userEvent.click(screen.getByText('Refresh dashboard'));
|
||||||
|
expect(mockedProps.forceRefreshAllCharts).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should show the properties modal', async () => {
|
||||||
|
render(setup(editModeOnProps));
|
||||||
|
await openDropdown();
|
||||||
|
userEvent.click(screen.getByText('Edit dashboard properties'));
|
||||||
|
expect(editModeOnProps.showPropertiesModal).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
@ -25,16 +25,16 @@ import { Menu, NoAnimationDropdown } from 'src/common/components';
|
|||||||
import Icon from 'src/components/Icon';
|
import Icon from 'src/components/Icon';
|
||||||
import { URL_PARAMS } from 'src/constants';
|
import { URL_PARAMS } from 'src/constants';
|
||||||
import ShareMenuItems from 'src/dashboard/components/menu/ShareMenuItems';
|
import ShareMenuItems from 'src/dashboard/components/menu/ShareMenuItems';
|
||||||
import CssEditor from './CssEditor';
|
import CssEditor from 'src/dashboard/components/CssEditor';
|
||||||
import RefreshIntervalModal from './RefreshIntervalModal';
|
import RefreshIntervalModal from 'src/dashboard/components/RefreshIntervalModal';
|
||||||
import SaveModal from './SaveModal';
|
import SaveModal from 'src/dashboard/components/SaveModal';
|
||||||
import injectCustomCss from '../util/injectCustomCss';
|
import injectCustomCss from 'src/dashboard/util/injectCustomCss';
|
||||||
import { SAVE_TYPE_NEWDASHBOARD } from '../util/constants';
|
import { SAVE_TYPE_NEWDASHBOARD } from 'src/dashboard/util/constants';
|
||||||
import FilterScopeModal from './filterscope/FilterScopeModal';
|
import FilterScopeModal from 'src/dashboard/components/filterscope/FilterScopeModal';
|
||||||
import downloadAsImage from '../../utils/downloadAsImage';
|
import downloadAsImage from 'src/utils/downloadAsImage';
|
||||||
import getDashboardUrl from '../util/getDashboardUrl';
|
import getDashboardUrl from 'src/dashboard/util/getDashboardUrl';
|
||||||
import { getActiveFilters } from '../util/activeDashboardFilters';
|
import { getActiveFilters } from 'src/dashboard/util/activeDashboardFilters';
|
||||||
import { getUrlParam } from '../../utils/urlUtils';
|
import { getUrlParam } from 'src/utils/urlUtils';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
addSuccessToast: PropTypes.func.isRequired,
|
addSuccessToast: PropTypes.func.isRequired,
|
@ -34,19 +34,18 @@ import Button from 'src/components/Button';
|
|||||||
import EditableTitle from 'src/components/EditableTitle';
|
import EditableTitle from 'src/components/EditableTitle';
|
||||||
import FaveStar from 'src/components/FaveStar';
|
import FaveStar from 'src/components/FaveStar';
|
||||||
import { safeStringify } from 'src/utils/safeStringify';
|
import { safeStringify } from 'src/utils/safeStringify';
|
||||||
|
import HeaderActionsDropdown from 'src/dashboard/components/Header/HeaderActionsDropdown';
|
||||||
|
import PublishedStatus from 'src/dashboard/components/PublishedStatus';
|
||||||
|
import UndoRedoKeyListeners from 'src/dashboard/components/UndoRedoKeyListeners';
|
||||||
|
import PropertiesModal from 'src/dashboard/components/PropertiesModal';
|
||||||
import { chartPropShape } from 'src/dashboard/util/propShapes';
|
import { chartPropShape } from 'src/dashboard/util/propShapes';
|
||||||
import HeaderActionsDropdown from './HeaderActionsDropdown';
|
|
||||||
import PublishedStatus from './PublishedStatus';
|
|
||||||
import UndoRedoKeyListeners from './UndoRedoKeyListeners';
|
|
||||||
import PropertiesModal from './PropertiesModal';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
UNDO_LIMIT,
|
UNDO_LIMIT,
|
||||||
SAVE_TYPE_OVERWRITE,
|
SAVE_TYPE_OVERWRITE,
|
||||||
DASHBOARD_POSITION_DATA_LIMIT,
|
DASHBOARD_POSITION_DATA_LIMIT,
|
||||||
} from '../util/constants';
|
} from 'src/dashboard/util/constants';
|
||||||
import setPeriodicRunner from '../util/setPeriodicRunner';
|
import setPeriodicRunner from 'src/dashboard/util/setPeriodicRunner';
|
||||||
import { options as PeriodicRefreshOptions } from './RefreshIntervalModal';
|
import { options as PeriodicRefreshOptions } from 'src/dashboard/components/RefreshIntervalModal';
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
addSuccessToast: PropTypes.func.isRequired,
|
addSuccessToast: PropTypes.func.isRequired,
|
98
superset-frontend/src/dashboard/components/Header/types.ts
Normal file
98
superset-frontend/src/dashboard/components/Header/types.ts
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* 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 { Layout } from 'src/dashboard/types';
|
||||||
|
import { ChartState } from 'src/explore/types';
|
||||||
|
|
||||||
|
interface DashboardInfo {
|
||||||
|
id: number;
|
||||||
|
userId: number;
|
||||||
|
dash_edit_perm: boolean;
|
||||||
|
dash_save_perm: boolean;
|
||||||
|
metadata?: Record<string, any>;
|
||||||
|
common?: { conf: Record<string, any> };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeaderDropdownProps {
|
||||||
|
addSuccessToast: () => void;
|
||||||
|
addDangerToast: () => void;
|
||||||
|
customCss: string;
|
||||||
|
colorNamespace?: string;
|
||||||
|
colorScheme?: string;
|
||||||
|
dashboardId: number;
|
||||||
|
dashboardInfo: DashboardInfo;
|
||||||
|
dashboardTitle: string;
|
||||||
|
editMode: boolean;
|
||||||
|
expandedSlices: Record<number, boolean>;
|
||||||
|
forceRefreshAllCharts: () => void;
|
||||||
|
hasUnsavedChanges: boolean;
|
||||||
|
isLoading: boolean;
|
||||||
|
layout: Layout;
|
||||||
|
onChange: () => void;
|
||||||
|
onSave: () => void;
|
||||||
|
refreshFrequency: number;
|
||||||
|
setRefreshFrequency: () => void;
|
||||||
|
shouldPersistRefreshFrequency: boolean;
|
||||||
|
showPropertiesModal: () => void;
|
||||||
|
startPeriodicRender: () => void;
|
||||||
|
updateCss: () => void;
|
||||||
|
userCanEdit: boolean;
|
||||||
|
userCanSave: boolean;
|
||||||
|
lastModifiedTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HeaderProps {
|
||||||
|
addSuccessToast: () => void;
|
||||||
|
addDangerToast: () => void;
|
||||||
|
addWarningToast: () => void;
|
||||||
|
colorNamespace?: string;
|
||||||
|
charts: ChartState | {};
|
||||||
|
colorScheme?: string;
|
||||||
|
customCss: string;
|
||||||
|
dashboardInfo: DashboardInfo;
|
||||||
|
dashboardTitle: string;
|
||||||
|
setColorSchemeAndUnsavedChanges: () => void;
|
||||||
|
isStarred: boolean;
|
||||||
|
isPublished: boolean;
|
||||||
|
onChange: () => void;
|
||||||
|
onSave: () => void;
|
||||||
|
fetchFaveStar: () => void;
|
||||||
|
saveFaveStar: () => void;
|
||||||
|
savePublished: () => void;
|
||||||
|
updateDashboardTitle: () => void;
|
||||||
|
editMode: boolean;
|
||||||
|
setEditMode: () => void;
|
||||||
|
showBuilderPane: () => void;
|
||||||
|
updateCss: () => void;
|
||||||
|
logEvent: () => void;
|
||||||
|
hasUnsavedChanges: boolean;
|
||||||
|
maxUndoHistoryExceeded: boolean;
|
||||||
|
lastModifiedTime: number;
|
||||||
|
onUndo: () => void;
|
||||||
|
onRedo: () => void;
|
||||||
|
undoLength: number;
|
||||||
|
redoLength: number;
|
||||||
|
setMaxUndoHistoryExceeded: () => void;
|
||||||
|
maxUndoHistoryToast: () => void;
|
||||||
|
refreshFrequency: number;
|
||||||
|
shouldPersistRefreshFrequency: boolean;
|
||||||
|
setRefreshFrequency: () => void;
|
||||||
|
dashboardInfoChanged: () => void;
|
||||||
|
dashboardTitleChanged: () => void;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user