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.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
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 { CssEditor as AceCssEditor } from 'src/components/AsyncAceEditor';
|
||||||
import { AceEditorProps } from 'react-ace';
|
import { AceEditorProps } from 'react-ace';
|
||||||
import userEvent from '@testing-library/user-event';
|
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(() => {});
|
AceCssEditor.preload = () => new Promise(() => {});
|
||||||
|
|
||||||
test('renders with default props', () => {
|
test('renders with default props', () => {
|
||||||
@ -46,14 +52,15 @@ test('renders with initial CSS', () => {
|
|||||||
expect(screen.getByText(initialCss)).toBeInTheDocument();
|
expect(screen.getByText(initialCss)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders with templates', () => {
|
test('renders with templates', async () => {
|
||||||
const templates = ['Template A', 'Template B', 'Template C'];
|
|
||||||
render(<CssEditor triggerNode={<>Click</>} templates={templates} />);
|
render(<CssEditor triggerNode={<>Click</>} templates={templates} />);
|
||||||
userEvent.click(screen.getByRole('button', { name: 'Click' }));
|
userEvent.click(screen.getByRole('button', { name: 'Click' }));
|
||||||
userEvent.click(screen.getByText('Load a CSS template'));
|
userEvent.hover(screen.getByText('Load a CSS template'));
|
||||||
templates.forEach(template =>
|
await waitFor(() => {
|
||||||
expect(screen.getByText(template)).toBeInTheDocument(),
|
templates.forEach(template =>
|
||||||
);
|
expect(screen.getByText(template.label)).toBeInTheDocument(),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('triggers onChange when using the editor', () => {
|
test('triggers onChange when using the editor', () => {
|
||||||
@ -73,9 +80,8 @@ test('triggers onChange when using the editor', () => {
|
|||||||
expect(onChange).toHaveBeenLastCalledWith(initialCss.concat(additionalCss));
|
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 onChange = jest.fn();
|
||||||
const templates = ['Template A', 'Template B', 'Template C'];
|
|
||||||
render(
|
render(
|
||||||
<CssEditor
|
<CssEditor
|
||||||
triggerNode={<>Click</>}
|
triggerNode={<>Click</>}
|
||||||
@ -86,6 +92,6 @@ test('triggers onChange when selecting a template', () => {
|
|||||||
userEvent.click(screen.getByRole('button', { name: 'Click' }));
|
userEvent.click(screen.getByRole('button', { name: 'Click' }));
|
||||||
userEvent.click(screen.getByText('Load a CSS template'));
|
userEvent.click(screen.getByText('Load a CSS template'));
|
||||||
expect(onChange).not.toHaveBeenCalled();
|
expect(onChange).not.toHaveBeenCalled();
|
||||||
userEvent.click(screen.getByText('Template A'));
|
userEvent.click(await screen.findByText('Template A'));
|
||||||
expect(onChange).toHaveBeenCalledTimes(1);
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
@ -18,11 +18,30 @@
|
|||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Select from 'src/components/Select';
|
import { Menu, Dropdown } from 'src/common/components';
|
||||||
import { t } from '@superset-ui/core';
|
import Button from 'src/components/Button';
|
||||||
|
import { t, styled } from '@superset-ui/core';
|
||||||
import ModalTrigger from 'src/components/ModalTrigger';
|
import ModalTrigger from 'src/components/ModalTrigger';
|
||||||
import { CssEditor as AceCssEditor } from 'src/components/AsyncAceEditor';
|
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 = {
|
const propTypes = {
|
||||||
initialCss: PropTypes.string,
|
initialCss: PropTypes.string,
|
||||||
triggerNode: PropTypes.node.isRequired,
|
triggerNode: PropTypes.node.isRequired,
|
||||||
@ -55,21 +74,24 @@ class CssEditor extends React.PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeCssTemplate(opt) {
|
changeCssTemplate({ key }) {
|
||||||
this.changeCss(opt.css);
|
this.changeCss(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTemplateSelector() {
|
renderTemplateSelector() {
|
||||||
if (this.props.templates) {
|
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 (
|
return (
|
||||||
<div style={{ zIndex: 10 }}>
|
<Dropdown overlay={menu} placement="bottomRight">
|
||||||
<h5>{t('Load a template')}</h5>
|
<Button>{t('Load a CSS template')}</Button>
|
||||||
<Select
|
</Dropdown>
|
||||||
options={this.props.templates}
|
|
||||||
placeholder={t('Load a CSS template')}
|
|
||||||
onChange={this.changeCssTemplate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -81,24 +103,23 @@ class CssEditor extends React.PureComponent {
|
|||||||
triggerNode={this.props.triggerNode}
|
triggerNode={this.props.triggerNode}
|
||||||
modalTitle={t('CSS')}
|
modalTitle={t('CSS')}
|
||||||
modalBody={
|
modalBody={
|
||||||
<div>
|
<StyledWrapper>
|
||||||
{this.renderTemplateSelector()}
|
<div className="css-editor-header">
|
||||||
<div style={{ zIndex: 1 }}>
|
|
||||||
<h5>{t('Live CSS editor')}</h5>
|
<h5>{t('Live CSS editor')}</h5>
|
||||||
<div style={{ border: 'solid 1px grey' }}>
|
{this.renderTemplateSelector()}
|
||||||
<AceCssEditor
|
|
||||||
minLines={12}
|
|
||||||
maxLines={30}
|
|
||||||
onChange={this.changeCss}
|
|
||||||
height="200px"
|
|
||||||
width="100%"
|
|
||||||
editorProps={{ $blockScrolling: true }}
|
|
||||||
enableLiveAutocompletion
|
|
||||||
value={this.state.css || ''}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</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>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user