chore: Replaces the select for a dropdown button in the CSS editor (#16043)

This commit is contained in:
Michael S. Molina 2021-08-06 07:59:15 -03:00 committed by GitHub
parent e59f318ef9
commit 6edc1ee3bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 38 deletions

View File

@ -17,7 +17,7 @@
* under the License.
*/
import React from 'react';
import { render, screen } from 'spec/helpers/testing-library';
import { render, screen, waitFor } from 'spec/helpers/testing-library';
import { CssEditor as AceCssEditor } from 'src/components/AsyncAceEditor';
import { AceEditorProps } from 'react-ace';
import userEvent from '@testing-library/user-event';
@ -32,6 +32,12 @@ 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;' },
];
AceCssEditor.preload = () => new Promise(() => {});
test('renders with default props', () => {
@ -46,14 +52,15 @@ test('renders with initial CSS', () => {
expect(screen.getByText(initialCss)).toBeInTheDocument();
});
test('renders with templates', () => {
const templates = ['Template A', 'Template B', 'Template C'];
test('renders with templates', async () => {
render(<CssEditor triggerNode={<>Click</>} templates={templates} />);
userEvent.click(screen.getByRole('button', { name: 'Click' }));
userEvent.click(screen.getByText('Load a CSS template'));
templates.forEach(template =>
expect(screen.getByText(template)).toBeInTheDocument(),
);
userEvent.hover(screen.getByText('Load a CSS template'));
await waitFor(() => {
templates.forEach(template =>
expect(screen.getByText(template.label)).toBeInTheDocument(),
);
});
});
test('triggers onChange when using the editor', () => {
@ -73,9 +80,8 @@ test('triggers onChange when using the editor', () => {
expect(onChange).toHaveBeenLastCalledWith(initialCss.concat(additionalCss));
});
test('triggers onChange when selecting a template', () => {
test('triggers onChange when selecting a template', async () => {
const onChange = jest.fn();
const templates = ['Template A', 'Template B', 'Template C'];
render(
<CssEditor
triggerNode={<>Click</>}
@ -86,6 +92,6 @@ test('triggers onChange when selecting a template', () => {
userEvent.click(screen.getByRole('button', { name: 'Click' }));
userEvent.click(screen.getByText('Load a CSS template'));
expect(onChange).not.toHaveBeenCalled();
userEvent.click(screen.getByText('Template A'));
userEvent.click(await screen.findByText('Template A'));
expect(onChange).toHaveBeenCalledTimes(1);
});

View File

@ -18,11 +18,30 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import Select from 'src/components/Select';
import { t } from '@superset-ui/core';
import { Menu, Dropdown } from 'src/common/components';
import Button from 'src/components/Button';
import { t, styled } from '@superset-ui/core';
import ModalTrigger from 'src/components/ModalTrigger';
import { CssEditor as AceCssEditor } from 'src/components/AsyncAceEditor';
const StyledWrapper = styled.div`
${({ theme }) => `
.css-editor-header {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: ${theme.gridUnit * 2}px;
h5 {
margin-top: ${theme.gridUnit}px;
}
}
.css-editor {
border: 1px solid ${theme.colors.grayscale.light1};
}
`}
`;
const propTypes = {
initialCss: PropTypes.string,
triggerNode: PropTypes.node.isRequired,
@ -55,21 +74,24 @@ class CssEditor extends React.PureComponent {
});
}
changeCssTemplate(opt) {
this.changeCss(opt.css);
changeCssTemplate({ key }) {
this.changeCss(key);
}
renderTemplateSelector() {
if (this.props.templates) {
const menu = (
<Menu onClick={this.changeCssTemplate}>
{this.props.templates.map(template => (
<Menu.Item key={template.css}>{template.label}</Menu.Item>
))}
</Menu>
);
return (
<div style={{ zIndex: 10 }}>
<h5>{t('Load a template')}</h5>
<Select
options={this.props.templates}
placeholder={t('Load a CSS template')}
onChange={this.changeCssTemplate}
/>
</div>
<Dropdown overlay={menu} placement="bottomRight">
<Button>{t('Load a CSS template')}</Button>
</Dropdown>
);
}
return null;
@ -81,24 +103,23 @@ class CssEditor extends React.PureComponent {
triggerNode={this.props.triggerNode}
modalTitle={t('CSS')}
modalBody={
<div>
{this.renderTemplateSelector()}
<div style={{ zIndex: 1 }}>
<StyledWrapper>
<div className="css-editor-header">
<h5>{t('Live CSS editor')}</h5>
<div style={{ border: 'solid 1px grey' }}>
<AceCssEditor
minLines={12}
maxLines={30}
onChange={this.changeCss}
height="200px"
width="100%"
editorProps={{ $blockScrolling: true }}
enableLiveAutocompletion
value={this.state.css || ''}
/>
</div>
{this.renderTemplateSelector()}
</div>
</div>
<AceCssEditor
className="css-editor"
minLines={12}
maxLines={30}
onChange={this.changeCss}
height="200px"
width="100%"
editorProps={{ $blockScrolling: true }}
enableLiveAutocompletion
value={this.state.css || ''}
/>
</StyledWrapper>
}
/>
);