mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
fix(dashboard): Only fetch CSS templates for dashboard header menu when in edit mode (#27411)
Co-authored-by: Michael S. Molina <michael.s.molina@gmail.com>
(cherry picked from commit fde93dcf08
)
This commit is contained in:
parent
15557f493d
commit
759863553d
@ -21,6 +21,7 @@ import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import { CssEditor as AceCssEditor } from 'src/components/AsyncAceEditor';
|
||||
import { IAceEditorProps } from 'react-ace';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import fetchMock from 'fetch-mock';
|
||||
import CssEditor from '.';
|
||||
|
||||
jest.mock('src/components/AsyncAceEditor', () => ({
|
||||
@ -33,46 +34,59 @@ jest.mock('src/components/AsyncAceEditor', () => ({
|
||||
}));
|
||||
|
||||
const templates = [
|
||||
{ label: 'Template A', css: 'background-color: red;' },
|
||||
{ label: 'Template B', css: 'background-color: blue;' },
|
||||
{ label: 'Template C', css: 'background-color: yellow;' },
|
||||
{ template_name: 'Template A', css: 'background-color: red;' },
|
||||
{ template_name: 'Template B', css: 'background-color: blue;' },
|
||||
{ template_name: 'Template C', css: 'background-color: yellow;' },
|
||||
];
|
||||
|
||||
fetchMock.get('glob:*/csstemplateasyncmodelview/api/read', {
|
||||
result: templates,
|
||||
});
|
||||
|
||||
AceCssEditor.preload = () => new Promise(() => {});
|
||||
|
||||
test('renders with default props', () => {
|
||||
render(<CssEditor triggerNode={<>Click</>} />);
|
||||
const defaultProps = {
|
||||
triggerNode: <>Click</>,
|
||||
addDangerToast: jest.fn(),
|
||||
};
|
||||
|
||||
test('renders with default props', async () => {
|
||||
await waitFor(() => render(<CssEditor {...defaultProps} />));
|
||||
expect(screen.getByRole('button', { name: 'Click' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders with initial CSS', () => {
|
||||
test('renders with initial CSS', async () => {
|
||||
const initialCss = 'margin: 10px;';
|
||||
render(<CssEditor triggerNode={<>Click</>} initialCss={initialCss} />);
|
||||
await waitFor(() =>
|
||||
render(<CssEditor {...defaultProps} initialCss={initialCss} />),
|
||||
);
|
||||
userEvent.click(screen.getByRole('button', { name: 'Click' }));
|
||||
expect(screen.getByText(initialCss)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders with templates', async () => {
|
||||
render(<CssEditor triggerNode={<>Click</>} templates={templates} />);
|
||||
await waitFor(() => render(<CssEditor {...defaultProps} />));
|
||||
userEvent.click(screen.getByRole('button', { name: 'Click' }));
|
||||
userEvent.hover(screen.getByText('Load a CSS template'));
|
||||
await waitFor(() => {
|
||||
templates.forEach(template =>
|
||||
expect(screen.getByText(template.label)).toBeInTheDocument(),
|
||||
expect(screen.getByText(template.template_name)).toBeInTheDocument(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('triggers onChange when using the editor', () => {
|
||||
test('triggers onChange when using the editor', async () => {
|
||||
const onChange = jest.fn();
|
||||
const initialCss = 'margin: 10px;';
|
||||
const additionalCss = 'color: red;';
|
||||
render(
|
||||
<CssEditor
|
||||
triggerNode={<>Click</>}
|
||||
initialCss={initialCss}
|
||||
onChange={onChange}
|
||||
/>,
|
||||
await waitFor(() =>
|
||||
render(
|
||||
<CssEditor
|
||||
{...defaultProps}
|
||||
initialCss={initialCss}
|
||||
onChange={onChange}
|
||||
/>,
|
||||
),
|
||||
);
|
||||
userEvent.click(screen.getByRole('button', { name: 'Click' }));
|
||||
expect(onChange).not.toHaveBeenCalled();
|
||||
@ -82,12 +96,8 @@ test('triggers onChange when using the editor', () => {
|
||||
|
||||
test('triggers onChange when selecting a template', async () => {
|
||||
const onChange = jest.fn();
|
||||
render(
|
||||
<CssEditor
|
||||
triggerNode={<>Click</>}
|
||||
templates={templates}
|
||||
onChange={onChange}
|
||||
/>,
|
||||
await waitFor(() =>
|
||||
render(<CssEditor {...defaultProps} onChange={onChange} />),
|
||||
);
|
||||
userEvent.click(screen.getByRole('button', { name: 'Click' }));
|
||||
userEvent.click(screen.getByText('Load a CSS template'));
|
||||
|
@ -21,7 +21,7 @@ import PropTypes from 'prop-types';
|
||||
import { AntdDropdown } from 'src/components';
|
||||
import { Menu } from 'src/components/Menu';
|
||||
import Button from 'src/components/Button';
|
||||
import { t, styled } from '@superset-ui/core';
|
||||
import { t, styled, SupersetClient } from '@superset-ui/core';
|
||||
import ModalTrigger from 'src/components/ModalTrigger';
|
||||
import { CssEditor as AceCssEditor } from 'src/components/AsyncAceEditor';
|
||||
|
||||
@ -47,7 +47,7 @@ const propTypes = {
|
||||
initialCss: PropTypes.string,
|
||||
triggerNode: PropTypes.node.isRequired,
|
||||
onChange: PropTypes.func,
|
||||
templates: PropTypes.array,
|
||||
addDangerToast: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
@ -60,6 +60,7 @@ class CssEditor extends React.PureComponent {
|
||||
super(props);
|
||||
this.state = {
|
||||
css: props.initialCss,
|
||||
templates: [],
|
||||
};
|
||||
this.changeCss = this.changeCss.bind(this);
|
||||
this.changeCssTemplate = this.changeCssTemplate.bind(this);
|
||||
@ -67,6 +68,22 @@ class CssEditor extends React.PureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
AceCssEditor.preload();
|
||||
|
||||
SupersetClient.get({ endpoint: '/csstemplateasyncmodelview/api/read' })
|
||||
.then(({ json }) => {
|
||||
const templates = json.result.map(row => ({
|
||||
value: row.template_name,
|
||||
css: row.css,
|
||||
label: row.template_name,
|
||||
}));
|
||||
|
||||
this.setState({ templates });
|
||||
})
|
||||
.catch(() => {
|
||||
this.props.addDangerToast(
|
||||
t('An error occurred while fetching available CSS templates'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
changeCss(css) {
|
||||
@ -80,10 +97,10 @@ class CssEditor extends React.PureComponent {
|
||||
}
|
||||
|
||||
renderTemplateSelector() {
|
||||
if (this.props.templates) {
|
||||
if (this.state.templates) {
|
||||
const menu = (
|
||||
<Menu onClick={this.changeCssTemplate}>
|
||||
{this.props.templates.map(template => (
|
||||
{this.state.templates.map(template => (
|
||||
<Menu.Item key={template.css}>{template.label}</Menu.Item>
|
||||
))}
|
||||
</Menu>
|
||||
|
@ -19,7 +19,7 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { SupersetClient, t } from '@superset-ui/core';
|
||||
import { t } from '@superset-ui/core';
|
||||
import { Menu } from 'src/components/Menu';
|
||||
import { URL_PARAMS } from 'src/constants';
|
||||
import ShareMenuItems from 'src/dashboard/components/menu/ShareMenuItems';
|
||||
@ -99,7 +99,6 @@ class HeaderActionsDropdown extends React.PureComponent {
|
||||
super(props);
|
||||
this.state = {
|
||||
css: props.customCss,
|
||||
cssTemplates: [],
|
||||
showReportSubMenu: null,
|
||||
};
|
||||
|
||||
@ -109,23 +108,6 @@ class HeaderActionsDropdown extends React.PureComponent {
|
||||
this.setShowReportSubMenu = this.setShowReportSubMenu.bind(this);
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
SupersetClient.get({ endpoint: '/csstemplateasyncmodelview/api/read' })
|
||||
.then(({ json }) => {
|
||||
const cssTemplates = json.result.map(row => ({
|
||||
value: row.template_name,
|
||||
css: row.css,
|
||||
label: row.template_name,
|
||||
}));
|
||||
this.setState({ cssTemplates });
|
||||
})
|
||||
.catch(() => {
|
||||
this.props.addDangerToast(
|
||||
t('An error occurred while fetching available CSS templates'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if (this.props.customCss !== nextProps.customCss) {
|
||||
this.setState({ css: nextProps.customCss }, () => {
|
||||
@ -257,8 +239,8 @@ class HeaderActionsDropdown extends React.PureComponent {
|
||||
<CssEditor
|
||||
triggerNode={<span>{t('Edit CSS')}</span>}
|
||||
initialCss={this.state.css}
|
||||
templates={this.state.cssTemplates}
|
||||
onChange={this.changeCss}
|
||||
addDangerToast={addDangerToast}
|
||||
/>
|
||||
</Menu.Item>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user