mirror of
https://github.com/apache/superset.git
synced 2024-09-05 21:37:50 -04:00
chore: Replaces the select for a dropdown button in the CSS editor (#16043)
This commit is contained in:
parent
e59f318ef9
commit
6edc1ee3bb
@ -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'));
|
||||
userEvent.hover(screen.getByText('Load a CSS template'));
|
||||
await waitFor(() => {
|
||||
templates.forEach(template =>
|
||||
expect(screen.getByText(template)).toBeInTheDocument(),
|
||||
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);
|
||||
});
|
||||
|
@ -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,12 +103,13 @@ 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' }}>
|
||||
{this.renderTemplateSelector()}
|
||||
</div>
|
||||
<AceCssEditor
|
||||
className="css-editor"
|
||||
minLines={12}
|
||||
maxLines={30}
|
||||
onChange={this.changeCss}
|
||||
@ -96,9 +119,7 @@ class CssEditor extends React.PureComponent {
|
||||
enableLiveAutocompletion
|
||||
value={this.state.css || ''}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user