mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[Discover] SCSS to Emotions migration part 4/4 (#224424)
## Summary Parent issue: [[DataDiscovery] Replace SCSS with CSS-in-JS](https://github.com/elastic/kibana/issues/209807#top) Followed [Emotion standards guide](https://docs.google.com/document/d/1CPflY8yCc3lZDg2BQkaMTgIkZlqiAEyMcAAvZbsjcTc/edit?pli=1&tab=t.0#heading=h.4zj1jq66y5an) Part 4 of SCSS -> Emotion migration. Files included: - `src/platform/plugins/shared/data_view_editor/public/components/_templates.scss` - `src/platform/plugins/shared/data_view_editor/public/components/_variables.scss` - `src/platform/plugins/shared/data_view_editor/public/components/data_view_editor.scss` - `src/platform/plugins/shared/data_view_editor/public/components/flyout_panels/flyout_panels.scss` - `src/platform/plugins/shared/data_view_field_editor/public/components/field_format_editor/samples/samples.scss` - `src/platform/plugins/shared/data_view_field_editor/public/components/flyout_panels/flyout_panels.scss` - `src/platform/plugins/shared/data_view_field_editor/public/components/preview/field_list/field_list.scss` - `src/platform/plugins/shared/data_view_field_editor/public/components/preview/field_preview.scss` - `src/platform/plugins/shared/data_view_management/public/_templates.scss` - `src/platform/plugins/shared/data_view_management/public/_variables.scss` - `src/platform/plugins/shared/data_view_management/public/components/empty_index_list_prompt/empty_index_list_prompt.scss` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
f149325412
commit
9e4798139f
39 changed files with 468 additions and 667 deletions
|
@ -1,11 +0,0 @@
|
|||
%inp-empty-state-footer {
|
||||
background: $euiColorLightestShade;
|
||||
margin: 0 (-$euiSizeL) (-$euiSizeL);
|
||||
padding: $euiSizeL;
|
||||
border-radius: 0 0 $euiBorderRadius $euiBorderRadius;
|
||||
|
||||
// sass-lint:disable-block mixins-before-declarations
|
||||
@include euiBreakpoint('xs', 's') {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
$inpEmptyStateMaxWidth: $euiSizeXXL * 19;
|
|
@ -1,13 +0,0 @@
|
|||
.indexPatternEditor__form {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.fieldEditor__mainFlyoutPanel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.indexPatternEditor__footer {
|
||||
margin-left: -$euiSizeL;
|
||||
margin-right: -$euiSizeL;
|
||||
}
|
|
@ -12,7 +12,6 @@ import { EuiFlyout } from '@elastic/eui';
|
|||
import { DataViewEditorLazy } from './data_view_editor_lazy';
|
||||
import { DataViewEditorContext, DataViewEditorProps } from '../types';
|
||||
import { createKibanaReactContext } from '../shared_imports';
|
||||
import './data_view_editor.scss';
|
||||
|
||||
export interface DataViewEditorPropsWithServices extends DataViewEditorProps {
|
||||
services: DataViewEditorContext;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import {
|
||||
EuiTitle,
|
||||
EuiFlexGroup,
|
||||
|
@ -16,12 +17,13 @@ import {
|
|||
EuiLink,
|
||||
EuiSkeletonRectangle,
|
||||
EuiSkeletonTitle,
|
||||
useEuiTheme,
|
||||
type UseEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import useDebounce from 'react-use/lib/useDebounce';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { INDEX_PATTERN_TYPE } from '@kbn/data-views-plugin/public';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
import {
|
||||
DataView,
|
||||
|
@ -94,11 +96,12 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
showManagementLink,
|
||||
dataViewEditorService,
|
||||
}: Props) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
|
||||
const {
|
||||
services: { application, dataViews, uiSettings, overlays, docLinks },
|
||||
} = useKibana<DataViewEditorContext>();
|
||||
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const canSave = dataViews.getCanSaveSync();
|
||||
|
||||
const { form } = useForm<IndexPatternConfig, FormInternal>({
|
||||
|
@ -214,9 +217,9 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
|
||||
if (isLoadingSources || !existingDataViewNames) {
|
||||
return (
|
||||
<EuiFlexGroup css={{ margin: euiTheme.size.l }}>
|
||||
<EuiFlexGroup css={styles.loadingWrapper}>
|
||||
<EuiFlexItem>
|
||||
<EuiSkeletonTitle size="l" css={{ width: '25vw' }} />
|
||||
<EuiSkeletonTitle size="l" css={styles.skeletonTitle} />
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<EuiSpacer size="xl" />
|
||||
|
@ -261,7 +264,7 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
return (
|
||||
<FlyoutPanels.Group flyoutClassName={'indexPatternEditorFlyout'} maxWidth={1180}>
|
||||
<FlyoutPanels.Item
|
||||
className="fieldEditor__mainFlyoutPanel"
|
||||
css={styles.flyoutPanel}
|
||||
data-test-subj="indexPatternEditorFlyout"
|
||||
border="right"
|
||||
>
|
||||
|
@ -281,7 +284,7 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
)}
|
||||
<Form
|
||||
form={form}
|
||||
className="indexPatternEditor__form"
|
||||
css={styles.patternEditorForm}
|
||||
error={form.getErrors()}
|
||||
isInvalid={form.isSubmitted && !form.isValid && form.getErrors().length}
|
||||
data-validation-error={form.getErrors().length ? '1' : '0'}
|
||||
|
@ -370,4 +373,21 @@ const IndexPatternEditorFlyoutContentComponent = ({
|
|||
);
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
patternEditorForm: css({
|
||||
flexGrow: 1,
|
||||
}),
|
||||
flyoutPanel: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}),
|
||||
loadingWrapper: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
margin: euiTheme.size.l,
|
||||
}),
|
||||
skeletonTitle: css({
|
||||
width: '25vw',
|
||||
}),
|
||||
};
|
||||
|
||||
export const IndexPatternEditorFlyoutContent = React.memo(IndexPatternEditorFlyoutContentComponent);
|
||||
|
|
|
@ -15,8 +15,9 @@ import React, {
|
|||
createContext,
|
||||
useContext,
|
||||
} from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { EuiFlexItem } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiFlexItem, type UseEuiTheme } from '@elastic/eui';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
import { useFlyoutPanelsContext } from './flyout_panels';
|
||||
|
||||
|
@ -47,19 +48,12 @@ export const Panel: React.FC<Props & React.HTMLProps<HTMLDivElement>> = ({
|
|||
border,
|
||||
...rest
|
||||
}) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
const [config, setConfig] = useState<{ hasFooter: boolean; hasContent: boolean }>({
|
||||
hasContent: false,
|
||||
hasFooter: false,
|
||||
});
|
||||
|
||||
const classes = classnames('fieldEditor__flyoutPanel', 'eui-scrollBar', className, {
|
||||
'fieldEditor__flyoutPanel--pageBackground': backgroundColor === 'euiPageBackground',
|
||||
'fieldEditor__flyoutPanel--emptyShade': backgroundColor === 'euiEmptyShade',
|
||||
'fieldEditor__flyoutPanel--leftBorder': border === 'left',
|
||||
'fieldEditor__flyoutPanel--rightBorder': border === 'right',
|
||||
'fieldEditor__flyoutPanel--withContent': config.hasContent,
|
||||
});
|
||||
|
||||
const { addPanel } = useFlyoutPanelsContext();
|
||||
|
||||
const registerContent = useCallback(() => {
|
||||
|
@ -91,16 +85,26 @@ export const Panel: React.FC<Props & React.HTMLProps<HTMLDivElement>> = ({
|
|||
return removePanel;
|
||||
}, [width, addPanel]);
|
||||
|
||||
const styles: CSSProperties = {};
|
||||
const dynamicStyles: CSSProperties = {};
|
||||
|
||||
if (width) {
|
||||
styles.flexBasis = `${width}%`;
|
||||
dynamicStyles.flexBasis = `${width}%`;
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiFlexItem style={styles}>
|
||||
<EuiFlexItem css={styles.flyoutColumn} style={dynamicStyles}>
|
||||
<flyoutPanelContext.Provider value={{ registerContent, registerFooter }}>
|
||||
<div className={classes} {...rest}>
|
||||
<div
|
||||
css={[
|
||||
styles.flyoutPanel,
|
||||
backgroundColor === 'euiPageBackground' && styles.pageBackground,
|
||||
backgroundColor === 'euiEmptyShade' && styles.emptyShade,
|
||||
border === 'left' && styles.leftBorder,
|
||||
border === 'right' && styles.rightBorder,
|
||||
config.hasContent && styles.withContent,
|
||||
]}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</flyoutPanelContext.Provider>
|
||||
|
@ -117,3 +121,38 @@ export const useFlyoutPanelContext = (): Context => {
|
|||
|
||||
return ctx;
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
flyoutColumn: css({
|
||||
height: '100%',
|
||||
overflow: 'hidden',
|
||||
}),
|
||||
flyoutPanel: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
height: '100%',
|
||||
overflowY: 'auto',
|
||||
padding: euiTheme.size.l,
|
||||
}),
|
||||
pageBackground: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
backgroundColor: euiTheme.colors.body,
|
||||
}),
|
||||
emptyShade: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
backgroundColor: euiTheme.colors.emptyShade,
|
||||
}),
|
||||
leftBorder: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
borderLeft: euiTheme.border.thin,
|
||||
}),
|
||||
rightBorder: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
borderRight: euiTheme.border.thin,
|
||||
}),
|
||||
withContent: css({
|
||||
padding: 0,
|
||||
overflowY: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
.fieldEditor__flyoutPanels {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fieldEditor__flyoutPanel {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding: $euiSizeL $euiSizeL 0 $euiSizeL;
|
||||
|
||||
&--pageBackground {
|
||||
background-color: $euiPageBackgroundColor;
|
||||
}
|
||||
&--emptyShade {
|
||||
background-color: $euiColorEmptyShade;
|
||||
}
|
||||
&--leftBorder {
|
||||
border-left: $euiBorderThin;
|
||||
}
|
||||
&--rightBorder {
|
||||
border-right: $euiBorderThin;
|
||||
}
|
||||
&--withContent {
|
||||
padding: 0;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__header {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
&__content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: $euiSizeL;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
flex: 0;
|
||||
}
|
||||
}
|
|
@ -17,10 +17,9 @@ import React, {
|
|||
FC,
|
||||
PropsWithChildren,
|
||||
} from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiFlexGroup, EuiFlexGroupProps } from '@elastic/eui';
|
||||
|
||||
import './flyout_panels.scss';
|
||||
|
||||
interface Panel {
|
||||
width?: number;
|
||||
}
|
||||
|
@ -106,7 +105,7 @@ export const Panels: FC<PropsWithChildren<Props>> = ({ maxWidth, flyoutClassName
|
|||
|
||||
return (
|
||||
<flyoutPanelsContext.Provider value={ctx}>
|
||||
<EuiFlexGroup className="fieldEditor__flyoutPanels" gutterSize="none" {...props} />
|
||||
<EuiFlexGroup css={styles.flyoutPanels} gutterSize="none" {...props} />
|
||||
</flyoutPanelsContext.Provider>
|
||||
);
|
||||
};
|
||||
|
@ -120,3 +119,9 @@ export const useFlyoutPanelsContext = (): Context => {
|
|||
|
||||
return ctx;
|
||||
};
|
||||
|
||||
const styles = {
|
||||
flyoutPanels: css({
|
||||
height: '100%',
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -8,15 +8,28 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect, FC, PropsWithChildren } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import type { UseEuiTheme } from '@elastic/eui';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
import { useFlyoutPanelContext } from './flyout_panel';
|
||||
|
||||
export const PanelContent: FC<PropsWithChildren<unknown>> = (props) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
const { registerContent } = useFlyoutPanelContext();
|
||||
|
||||
useEffect(() => {
|
||||
registerContent();
|
||||
}, [registerContent]);
|
||||
|
||||
return <div className="fieldEditor__flyoutPanel__content" {...props} />;
|
||||
return <div css={styles.content} {...props} />;
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
content: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
flex: 1,
|
||||
overflowY: 'auto',
|
||||
padding: euiTheme.size.l,
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiFlyoutFooter, EuiFlyoutFooterProps } from '@elastic/eui';
|
||||
|
||||
import { useFlyoutPanelContext } from './flyout_panel';
|
||||
|
@ -21,5 +22,11 @@ export const PanelFooter: React.FC<
|
|||
registerFooter();
|
||||
}, [registerFooter]);
|
||||
|
||||
return <EuiFlyoutFooter className="fieldEditor__flyoutPanel__footer" {...props} />;
|
||||
return <EuiFlyoutFooter css={styles.footer} {...props} />;
|
||||
};
|
||||
|
||||
const styles = {
|
||||
footer: css({
|
||||
flex: 0,
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -8,13 +8,19 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiSpacer, EuiFlyoutHeader, EuiFlyoutHeaderProps } from '@elastic/eui';
|
||||
|
||||
export const PanelHeader: React.FunctionComponent<
|
||||
{ children: React.ReactNode } & Omit<EuiFlyoutHeaderProps, 'children'>
|
||||
> = (props) => (
|
||||
<>
|
||||
<EuiFlyoutHeader className="fieldEditor__flyoutPanel__header" {...props} />
|
||||
<EuiFlyoutHeader
|
||||
css={css`
|
||||
padding: 0 !important;
|
||||
`}
|
||||
{...props}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
import {
|
||||
EuiFlyoutFooter,
|
||||
|
@ -16,7 +17,9 @@ import {
|
|||
EuiFlexItem,
|
||||
EuiButtonEmpty,
|
||||
EuiButton,
|
||||
type UseEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
export enum SubmittingType {
|
||||
savingAsAdHoc = 'savingAsAdHoc',
|
||||
|
@ -67,6 +70,7 @@ export const Footer = ({
|
|||
isPersisted,
|
||||
canSave,
|
||||
}: FooterProps) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
const isEditingAdHoc = isEdit && !isPersisted;
|
||||
const submitPersisted = () => {
|
||||
onSubmit(false);
|
||||
|
@ -76,7 +80,7 @@ export const Footer = ({
|
|||
};
|
||||
|
||||
return (
|
||||
<EuiFlyoutFooter className="indexPatternEditor__footer">
|
||||
<EuiFlyoutFooter css={styles.footer}>
|
||||
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty
|
||||
|
@ -135,3 +139,11 @@ export const Footer = ({
|
|||
</EuiFlyoutFooter>
|
||||
);
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
footer: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
marginLeft: -euiTheme.size.l,
|
||||
marginRight: -euiTheme.size.l,
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"@kbn/react-kibana-mount",
|
||||
"@kbn/code-editor",
|
||||
"@kbn/rollup",
|
||||
"@kbn/css-utils",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -260,7 +260,7 @@ exports[`UrlFormatEditor should render normally 1`] = `
|
|||
class="euiFormRow__fieldWrapper"
|
||||
>
|
||||
<div
|
||||
class="euiBasicTable kbnFieldFormatEditor__samples"
|
||||
class="euiBasicTable kbnFieldFormatEditor__samples css-p1tgq2-samples"
|
||||
id="generated-id"
|
||||
>
|
||||
<table
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FormatEditorSamples should render normally 1`] = `
|
||||
<EuiFormRow
|
||||
label={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Samples"
|
||||
id="indexPatternFieldEditor.samplesHeader"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiBasicTable
|
||||
className="kbnFieldFormatEditor__samples"
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"field": "input",
|
||||
"name": "Input",
|
||||
"render": [Function],
|
||||
},
|
||||
Object {
|
||||
"field": "output",
|
||||
"name": "Output",
|
||||
"render": [Function],
|
||||
},
|
||||
]
|
||||
}
|
||||
compressed={true}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"input": "test",
|
||||
"output": "TEST",
|
||||
},
|
||||
Object {
|
||||
"input": 123,
|
||||
"output": "456",
|
||||
},
|
||||
Object {
|
||||
"input": Array [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
"output": "<span>foo</span>, <span>bar</span>",
|
||||
},
|
||||
]
|
||||
}
|
||||
noItemsMessage={
|
||||
<EuiI18n
|
||||
default="No items found"
|
||||
token="euiBasicTable.noItemsMessage"
|
||||
/>
|
||||
}
|
||||
tableLayout="fixed"
|
||||
/>
|
||||
</EuiFormRow>
|
||||
`;
|
||||
|
||||
exports[`FormatEditorSamples should render nothing if there are no samples 1`] = `""`;
|
|
@ -1,5 +0,0 @@
|
|||
.kbnFieldFormatEditor__samples {
|
||||
audio {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
|
@ -8,28 +8,43 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallowWithI18nProvider } from '@kbn/test-jest-helpers';
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { FormatEditorSamples } from './samples';
|
||||
|
||||
describe('FormatEditorSamples', () => {
|
||||
it('should render normally', async () => {
|
||||
const component = shallowWithI18nProvider(
|
||||
<FormatEditorSamples
|
||||
samples={[
|
||||
{ input: 'test', output: 'TEST' },
|
||||
{ input: 123, output: '456' },
|
||||
{ input: ['foo', 'bar'], output: '<span>foo</span>, <span>bar</span>' },
|
||||
]}
|
||||
/>
|
||||
it('should render normally', () => {
|
||||
render(
|
||||
<I18nProvider>
|
||||
<FormatEditorSamples
|
||||
samples={[
|
||||
{ input: 'test', output: 'TEST' },
|
||||
{ input: 123, output: '456' },
|
||||
{ input: ['foo', 'bar'], output: '<span>foo</span>, <span>bar</span>' },
|
||||
]}
|
||||
/>
|
||||
</I18nProvider>
|
||||
);
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
expect(screen.getByRole('table')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('Input')).toBeInTheDocument();
|
||||
expect(screen.getByText('Output')).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByText('test')).toBeInTheDocument();
|
||||
expect(screen.getByText('TEST')).toBeInTheDocument();
|
||||
expect(screen.getByText('123')).toBeInTheDocument();
|
||||
expect(screen.getByText('456')).toBeInTheDocument();
|
||||
expect(screen.getByText('["foo","bar"]')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render nothing if there are no samples', async () => {
|
||||
const component = shallowWithI18nProvider(<FormatEditorSamples samples={[]} />);
|
||||
it('should render nothing if there are no samples', () => {
|
||||
const { container } = render(
|
||||
<I18nProvider>
|
||||
<FormatEditorSamples samples={[]} />
|
||||
</I18nProvider>
|
||||
);
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
expect(container).toBeEmptyDOMElement();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import './samples.scss';
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
import { EuiBasicTable, EuiFormRow } from '@elastic/eui';
|
||||
|
||||
|
@ -69,6 +68,7 @@ export class FormatEditorSamples extends PureComponent<FormatEditorSamplesProps>
|
|||
>
|
||||
<EuiBasicTable<Sample>
|
||||
className="kbnFieldFormatEditor__samples"
|
||||
css={styles.samples}
|
||||
compressed={true}
|
||||
items={samples}
|
||||
columns={columns}
|
||||
|
@ -77,3 +77,11 @@ export class FormatEditorSamples extends PureComponent<FormatEditorSamplesProps>
|
|||
) : null;
|
||||
}
|
||||
}
|
||||
|
||||
const styles = {
|
||||
samples: css`
|
||||
audio {
|
||||
max-width: 100%;
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
|
|
@ -16,8 +16,9 @@ import React, {
|
|||
useContext,
|
||||
useMemo,
|
||||
} from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { EuiFlexItem } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiFlexItem, type UseEuiTheme } from '@elastic/eui';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
import { useFlyoutPanelsContext } from './flyout_panels';
|
||||
|
||||
|
@ -50,21 +51,14 @@ export const Panel: React.FC<Props & React.HTMLProps<HTMLDivElement>> = ({
|
|||
'data-test-subj': dataTestSubj,
|
||||
...rest
|
||||
}) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
const [dynamicStyles, setDynamicStyles] = useState<CSSProperties>({});
|
||||
|
||||
const [config, setConfig] = useState<{ hasFooter: boolean; hasContent: boolean }>({
|
||||
hasContent: false,
|
||||
hasFooter: false,
|
||||
});
|
||||
|
||||
const [styles, setStyles] = useState<CSSProperties>({});
|
||||
|
||||
const classes = classnames('fieldEditor__flyoutPanel', className, {
|
||||
'fieldEditor__flyoutPanel--pageBackground': backgroundColor === 'euiPageBackground',
|
||||
'fieldEditor__flyoutPanel--emptyShade': backgroundColor === 'euiEmptyShade',
|
||||
'fieldEditor__flyoutPanel--leftBorder': border === 'left',
|
||||
'fieldEditor__flyoutPanel--rightBorder': border === 'right',
|
||||
'fieldEditor__flyoutPanel--withContent': config.hasContent,
|
||||
});
|
||||
|
||||
const { addPanel } = useFlyoutPanelsContext();
|
||||
|
||||
const registerContent = useCallback(() => {
|
||||
|
@ -99,7 +93,7 @@ export const Panel: React.FC<Props & React.HTMLProps<HTMLDivElement>> = ({
|
|||
const { removePanel, isFixedWidth } = addPanel({ width });
|
||||
|
||||
if (width) {
|
||||
setStyles((prev) => {
|
||||
setDynamicStyles((prev) => {
|
||||
if (isFixedWidth) {
|
||||
return {
|
||||
...prev,
|
||||
|
@ -118,13 +112,23 @@ export const Panel: React.FC<Props & React.HTMLProps<HTMLDivElement>> = ({
|
|||
|
||||
return (
|
||||
<EuiFlexItem
|
||||
className="fieldEditor__flyoutPanels__column"
|
||||
style={styles}
|
||||
css={styles.flyoutColumn}
|
||||
style={dynamicStyles}
|
||||
grow={false}
|
||||
data-test-subj={dataTestSubj}
|
||||
>
|
||||
<flyoutPanelContext.Provider value={ctx}>
|
||||
<div className={classes} {...rest}>
|
||||
<div
|
||||
css={[
|
||||
styles.flyoutPanel,
|
||||
backgroundColor === 'euiPageBackground' && styles.pageBackground,
|
||||
backgroundColor === 'euiEmptyShade' && styles.emptyShade,
|
||||
border === 'left' && styles.leftBorder,
|
||||
border === 'right' && styles.rightBorder,
|
||||
config.hasContent && styles.withContent,
|
||||
]}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</flyoutPanelContext.Provider>
|
||||
|
@ -141,3 +145,38 @@ export const useFlyoutPanelContext = (): Context => {
|
|||
|
||||
return ctx;
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
flyoutColumn: css({
|
||||
height: '100%',
|
||||
overflow: 'hidden',
|
||||
}),
|
||||
flyoutPanel: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
height: '100%',
|
||||
overflowY: 'auto',
|
||||
padding: euiTheme.size.l,
|
||||
}),
|
||||
pageBackground: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
backgroundColor: euiTheme.colors.body,
|
||||
}),
|
||||
emptyShade: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
backgroundColor: euiTheme.colors.emptyShade,
|
||||
}),
|
||||
leftBorder: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
borderLeft: euiTheme.border.thin,
|
||||
}),
|
||||
rightBorder: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
borderRight: euiTheme.border.thin,
|
||||
}),
|
||||
withContent: css({
|
||||
padding: 0,
|
||||
overflowY: 'hidden',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
.fieldEditor__flyoutPanels {
|
||||
height: 100%;
|
||||
|
||||
&__column {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.fieldEditor__flyoutPanel {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding: $euiSizeL;
|
||||
|
||||
&--pageBackground {
|
||||
background-color: $euiPageBackgroundColor;
|
||||
}
|
||||
&--emptyShade {
|
||||
background-color: $euiColorEmptyShade;
|
||||
}
|
||||
&--leftBorder {
|
||||
border-left: $euiBorderThin;
|
||||
}
|
||||
&--rightBorder {
|
||||
border-right: $euiBorderThin;
|
||||
}
|
||||
&--withContent {
|
||||
padding: 0;
|
||||
overflow-y: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__header {
|
||||
padding: 0 !important;
|
||||
@include euiTextBreakWord;
|
||||
}
|
||||
|
||||
&__content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding: $euiSizeL;
|
||||
}
|
||||
|
||||
&__footer {
|
||||
flex: 0;
|
||||
}
|
||||
}
|
|
@ -15,10 +15,9 @@ import React, {
|
|||
useMemo,
|
||||
useLayoutEffect,
|
||||
} from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiFlexGroup, EuiFlexGroupProps, EuiFlyoutProps } from '@elastic/eui';
|
||||
|
||||
import './flyout_panels.scss';
|
||||
|
||||
interface Panel {
|
||||
width?: number;
|
||||
}
|
||||
|
@ -138,7 +137,7 @@ export const Panels: React.FC<Props> = ({
|
|||
|
||||
return (
|
||||
<flyoutPanelsContext.Provider value={ctx}>
|
||||
<EuiFlexGroup className="fieldEditor__flyoutPanels" gutterSize="none" {...props} />
|
||||
<EuiFlexGroup css={styles.flyoutPanels} gutterSize="none" {...props} />
|
||||
</flyoutPanelsContext.Provider>
|
||||
);
|
||||
};
|
||||
|
@ -152,3 +151,9 @@ export const useFlyoutPanelsContext = (): Context => {
|
|||
|
||||
return ctx;
|
||||
};
|
||||
|
||||
const styles = {
|
||||
flyoutPanels: css({
|
||||
height: '100%',
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -8,10 +8,14 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import type { UseEuiTheme } from '@elastic/eui';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
import { useFlyoutPanelContext } from './flyout_panel';
|
||||
|
||||
export const PanelContent: React.FC<{ children: React.ReactNode }> = (props) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
const { registerContent } = useFlyoutPanelContext();
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -19,7 +23,15 @@ export const PanelContent: React.FC<{ children: React.ReactNode }> = (props) =>
|
|||
}, [registerContent]);
|
||||
|
||||
// Adding a tabIndex prop to the div as it is the body of the flyout which is scrollable.
|
||||
return (
|
||||
<div className="fieldEditor__flyoutPanel__content eui-scrollBar" tabIndex={0} {...props} />
|
||||
);
|
||||
return <div css={styles.content} className="eui-scrollBar" tabIndex={0} {...props} />;
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
content: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
flex: 1,
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
padding: euiTheme.size.l,
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiFlyoutFooter, EuiFlyoutFooterProps } from '@elastic/eui';
|
||||
|
||||
import { useFlyoutPanelContext } from './flyout_panel';
|
||||
|
@ -21,5 +22,11 @@ export const PanelFooter: React.FC<
|
|||
registerFooter();
|
||||
}, [registerFooter]);
|
||||
|
||||
return <EuiFlyoutFooter className="fieldEditor__flyoutPanel__footer" {...props} />;
|
||||
return <EuiFlyoutFooter css={styles.footer} {...props} />;
|
||||
};
|
||||
|
||||
const styles = {
|
||||
footer: css({
|
||||
flex: 0,
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -8,13 +8,20 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiSpacer, EuiFlyoutHeader, EuiFlyoutHeaderProps } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiSpacer, EuiFlyoutHeader, EuiFlyoutHeaderProps, euiTextBreakWord } from '@elastic/eui';
|
||||
|
||||
export const PanelHeader: React.FunctionComponent<
|
||||
{ children: React.ReactNode } & Omit<EuiFlyoutHeaderProps, 'children'>
|
||||
> = (props) => (
|
||||
<>
|
||||
<EuiFlyoutHeader className="fieldEditor__flyoutPanel__header" {...props} />
|
||||
<EuiFlyoutHeader
|
||||
css={css`
|
||||
padding: 0 !important;
|
||||
${euiTextBreakWord()}
|
||||
`}
|
||||
{...props}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
export const ITEM_HEIGHT = 40;
|
||||
export const SHOW_MORE_HEIGHT = 40;
|
||||
export const INITIAL_MAX_NUMBER_OF_FIELDS = 7;
|
|
@ -1,52 +0,0 @@
|
|||
/**
|
||||
[1] This corresponds to the ITEM_HEIGHT declared in "field_list.tsx"
|
||||
[2] This corresponds to the SHOW_MORE_HEIGHT declared in "field_list.tsx"
|
||||
[3] We need the tooltip <span /> to be 100% to display the text ellipsis of the field value
|
||||
*/
|
||||
|
||||
$previewFieldItemHeight: 40px; /* [1] */
|
||||
$previewShowMoreHeight: 40px; /* [2] */
|
||||
|
||||
.indexPatternFieldEditor__previewFieldList {
|
||||
position: relative;
|
||||
|
||||
&--ligthWeight {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&__item {
|
||||
border-bottom: $euiBorderThin;
|
||||
height: $previewFieldItemHeight;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
|
||||
&__key, &__value {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
flex-basis: 24px !important;
|
||||
}
|
||||
|
||||
&__value .euiToolTipAnchor {
|
||||
width: 100%; /* [3] */
|
||||
}
|
||||
|
||||
&__key__wrapper, &__value__wrapper {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__showMore {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: $previewShowMoreHeight;
|
||||
bottom: $previewShowMoreHeight * -1;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
}
|
|
@ -10,8 +10,17 @@
|
|||
import React, { useState, useMemo, useCallback, useRef } from 'react';
|
||||
import { FixedSizeList as VirtualList, areEqual } from 'react-window';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { css } from '@emotion/react';
|
||||
import { get, isEqual } from 'lodash';
|
||||
import { EuiButtonEmpty, EuiButton, EuiSpacer, EuiEmptyPrompt, EuiTextColor } from '@elastic/eui';
|
||||
import {
|
||||
EuiButtonEmpty,
|
||||
EuiButton,
|
||||
EuiSpacer,
|
||||
EuiEmptyPrompt,
|
||||
EuiTextColor,
|
||||
type UseEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
import { useFieldEditorContext } from '../../field_editor_context';
|
||||
import { useFieldPreviewContext } from '../field_preview_context';
|
||||
|
@ -19,12 +28,8 @@ import type { FieldPreview, PreviewState } from '../types';
|
|||
import { PreviewListItem } from './field_list_item';
|
||||
import type { PreviewListItemProps } from './field_list_item';
|
||||
import { useStateSelector } from '../../../state_utils';
|
||||
import './field_list.scss';
|
||||
import { getPositionAfterToggling } from './get_item_position';
|
||||
|
||||
const ITEM_HEIGHT = 40;
|
||||
const SHOW_MORE_HEIGHT = 40;
|
||||
const INITIAL_MAX_NUMBER_OF_FIELDS = 7;
|
||||
import { ITEM_HEIGHT, SHOW_MORE_HEIGHT, INITIAL_MAX_NUMBER_OF_FIELDS } from './constants';
|
||||
|
||||
export type DocumentField = FieldPreview & {
|
||||
isPinned?: boolean;
|
||||
|
@ -73,6 +78,7 @@ const Row = React.memo<RowProps>(({ data, index, style }) => {
|
|||
}, areEqual);
|
||||
|
||||
export const PreviewFieldList: React.FC<Props> = ({ height, clearSearch, searchValue = '' }) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
const { dataView } = useFieldEditorContext();
|
||||
const { controller } = useFieldPreviewContext();
|
||||
const virtualListRef = useRef<VirtualList>(null);
|
||||
|
@ -160,7 +166,7 @@ export const PreviewFieldList: React.FC<Props> = ({ height, clearSearch, searchV
|
|||
iconType="search"
|
||||
title={
|
||||
<EuiTextColor color="subdued">
|
||||
<h3 className="indexPatternFieldEditor__previewEmptySearchResult__title">
|
||||
<h3 css={styles.emptySearchResult}>
|
||||
{i18n.translate(
|
||||
'indexPatternFieldEditor.fieldPreview.searchResult.emptyPromptTitle',
|
||||
{
|
||||
|
@ -189,7 +195,7 @@ export const PreviewFieldList: React.FC<Props> = ({ height, clearSearch, searchV
|
|||
|
||||
const renderToggleFieldsButton = () =>
|
||||
totalFields <= INITIAL_MAX_NUMBER_OF_FIELDS ? null : (
|
||||
<div className="indexPatternFieldEditor__previewFieldList__showMore">
|
||||
<div css={styles.showMore}>
|
||||
<EuiButtonEmpty onClick={toggleShowAllFields} flush="left">
|
||||
{showAllFields
|
||||
? i18n.translate('indexPatternFieldEditor.fieldPreview.showLessFieldsButtonLabel', {
|
||||
|
@ -234,7 +240,7 @@ export const PreviewFieldList: React.FC<Props> = ({ height, clearSearch, searchV
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="indexPatternFieldEditor__previewFieldList">
|
||||
<div className="indexPatternFieldEditor__previewFieldList" css={styles.previewFieldList}>
|
||||
{isEmptySearchResultVisible ? (
|
||||
renderEmptyResult()
|
||||
) : (
|
||||
|
@ -256,3 +262,21 @@ export const PreviewFieldList: React.FC<Props> = ({ height, clearSearch, searchV
|
|||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
emptySearchResult: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
fontWeight: euiTheme.font.weight.medium,
|
||||
}),
|
||||
previewFieldList: css({
|
||||
position: 'relative',
|
||||
}),
|
||||
showMore: css({
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: SHOW_MORE_HEIGHT,
|
||||
bottom: -SHOW_MORE_HEIGHT,
|
||||
display: 'flex',
|
||||
alignItems: 'flex-end',
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
|
@ -18,9 +17,10 @@ import {
|
|||
EuiButtonEmpty,
|
||||
EuiBadge,
|
||||
EuiTextColor,
|
||||
useEuiTheme,
|
||||
type UseEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
import { useFieldPreviewContext } from '../field_preview_context';
|
||||
import { IsUpdatingIndicator } from '../is_updating_indicator';
|
||||
|
@ -28,6 +28,7 @@ import { ImagePreviewModal } from '../image_preview_modal';
|
|||
import type { DocumentField } from './field_list';
|
||||
import { PreviewState } from '../types';
|
||||
import { useStateSelector } from '../../../state_utils';
|
||||
import { ITEM_HEIGHT } from './constants';
|
||||
|
||||
export interface PreviewListItemProps {
|
||||
field: DocumentField;
|
||||
|
@ -48,9 +49,10 @@ export const PreviewListItem: React.FC<PreviewListItemProps> = ({
|
|||
hasScriptError,
|
||||
isFromScript = false,
|
||||
}) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
|
||||
const pinButtonId = `fieldPreview.pinFieldButtonLabel.${key}`;
|
||||
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { controller } = useFieldPreviewContext();
|
||||
const isLoadingPreview = useStateSelector(controller.state$, isLoadingPreviewSelector);
|
||||
|
||||
|
@ -61,17 +63,12 @@ export const PreviewListItem: React.FC<PreviewListItemProps> = ({
|
|||
|
||||
const showPinIcon = isPinHovered || isPinFocused || isPinned;
|
||||
|
||||
const classes = classnames('indexPatternFieldEditor__previewFieldList__item', {
|
||||
'indexPatternFieldEditor__previewFieldList__item--highlighted': isFromScript,
|
||||
'indexPatternFieldEditor__previewFieldList__item--pinned': isPinned,
|
||||
});
|
||||
|
||||
const doesContainImage = formattedValue?.includes('<img');
|
||||
|
||||
const renderName = () => {
|
||||
if (isFromScript && !Boolean(key)) {
|
||||
return (
|
||||
<span className="indexPatternFieldEditor__previewFieldList--ligthWeight">
|
||||
<span css={styles.lightWeight}>
|
||||
<EuiTextColor color="subdued">
|
||||
{i18n.translate('indexPatternFieldEditor.fieldPreview.fieldNameNotSetLabel', {
|
||||
defaultMessage: 'Field name not set',
|
||||
|
@ -93,7 +90,7 @@ export const PreviewListItem: React.FC<PreviewListItemProps> = ({
|
|||
const renderValue = () => {
|
||||
if (isFromScript && isLoadingPreview) {
|
||||
return (
|
||||
<span className="indexPatternFieldEditor__previewFieldList--ligthWeight">
|
||||
<span css={styles.lightWeight}>
|
||||
<IsUpdatingIndicator />
|
||||
</span>
|
||||
);
|
||||
|
@ -113,7 +110,7 @@ export const PreviewListItem: React.FC<PreviewListItemProps> = ({
|
|||
|
||||
if (isFromScript && value === undefined) {
|
||||
return (
|
||||
<span className="indexPatternFieldEditor__previewFieldList--ligthWeight">
|
||||
<span css={styles.lightWeight}>
|
||||
<EuiTextColor color="subdued">
|
||||
{i18n.translate('indexPatternFieldEditor.fieldPreview.valueNotSetLabel', {
|
||||
defaultMessage: 'Value not set',
|
||||
|
@ -140,57 +137,35 @@ export const PreviewListItem: React.FC<PreviewListItemProps> = ({
|
|||
if (formattedValue !== undefined) {
|
||||
return withTooltip(
|
||||
<span
|
||||
className="indexPatternFieldEditor__previewFieldList__item__value__wrapper"
|
||||
css={styles.keyAndValueWrapper}
|
||||
// We can dangerously set HTML here because this content is guaranteed to have been run through a valid field formatter first.
|
||||
dangerouslySetInnerHTML={{ __html: formattedValue! }} // eslint-disable-line react/no-danger
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return withTooltip(
|
||||
<span className="indexPatternFieldEditor__previewFieldList__item__value__wrapper">
|
||||
{JSON.stringify(value)}
|
||||
</span>
|
||||
);
|
||||
return withTooltip(<span css={styles.keyAndValueWrapper}>{JSON.stringify(value)}</span>);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup
|
||||
className={classes}
|
||||
// highlights the field using token, TODO: migrate whole SCSS file to emotions
|
||||
css={
|
||||
isFromScript
|
||||
? css`
|
||||
background-color: ${euiTheme.colors.backgroundBasePrimary};
|
||||
font-weight: ${euiTheme.font.weight.bold};
|
||||
`
|
||||
: undefined
|
||||
}
|
||||
css={[styles.listItem, isFromScript ? styles.highlightedRow : undefined]}
|
||||
gutterSize="none"
|
||||
data-test-subj="listItem"
|
||||
onMouseEnter={() => setIsPinHovered(true)}
|
||||
onMouseLeave={() => setIsPinHovered(false)}
|
||||
>
|
||||
<EuiFlexItem className="indexPatternFieldEditor__previewFieldList__item__key">
|
||||
<div
|
||||
className="indexPatternFieldEditor__previewFieldList__item__key__wrapper"
|
||||
data-test-subj="key"
|
||||
>
|
||||
<EuiFlexItem css={styles.keyAndValue}>
|
||||
<div css={styles.keyAndValueWrapper} data-test-subj="key">
|
||||
{renderName()}
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="indexPatternFieldEditor__previewFieldList__item__value"
|
||||
data-test-subj="value"
|
||||
>
|
||||
<EuiFlexItem css={styles.keyAndValue} data-test-subj="value">
|
||||
{renderValue()}
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem
|
||||
className="indexPatternFieldEditor__previewFieldList__item__actions"
|
||||
grow={false}
|
||||
>
|
||||
<EuiFlexItem css={styles.actions} grow={false}>
|
||||
{toggleIsPinned && (
|
||||
<EuiButtonIcon
|
||||
onClick={(e: { detail: number }) => {
|
||||
|
@ -222,3 +197,40 @@ export const PreviewListItem: React.FC<PreviewListItemProps> = ({
|
|||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
listItem: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
borderBottom: euiTheme.border.thin,
|
||||
height: ITEM_HEIGHT,
|
||||
alignItems: 'center',
|
||||
overflow: 'hidden',
|
||||
}),
|
||||
highlightedRow: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
backgroundColor: euiTheme.colors.backgroundBasePrimary,
|
||||
fontWeight: euiTheme.font.weight.bold,
|
||||
}),
|
||||
lightWeight: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
fontWeight: euiTheme.font.weight.regular,
|
||||
}),
|
||||
keyAndValueWrapper: css({
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
display: 'block',
|
||||
width: '100%',
|
||||
}),
|
||||
keyAndValue: css({
|
||||
overflow: 'hidden',
|
||||
|
||||
'& .euiToolTipAnchor': {
|
||||
width: '100%', // We need the tooltip <span /> to be 100% to display the text ellipsis of the field value
|
||||
},
|
||||
}),
|
||||
actions: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
flexBasis: `${euiTheme.size.l} !important`,
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
.indexPatternFieldEditor {
|
||||
&__previewPannel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&__previewImageModal__wrapper {
|
||||
padding: $euiSize;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__previewEmptySearchResult__title {
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
*/
|
||||
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiSpacer, EuiResizeObserver, EuiFieldSearch, EuiCallOut } from '@elastic/eui';
|
||||
|
||||
|
@ -21,8 +22,6 @@ import { PreviewFieldList } from './field_list/field_list';
|
|||
import { useStateSelector } from '../../state_utils';
|
||||
import { PreviewState } from './types';
|
||||
|
||||
import './field_preview.scss';
|
||||
|
||||
const previewResponseSelector = (state: PreviewState) => state.previewResponse;
|
||||
const fetchDocErrorSelector = (state: PreviewState) => state.fetchDocError;
|
||||
const isLoadingPreviewSelector = (state: PreviewState) => state.isLoadingPreview;
|
||||
|
@ -80,7 +79,7 @@ export const FieldPreview = () => {
|
|||
|
||||
return (
|
||||
<div
|
||||
className="indexPatternFieldEditor__previewPannel"
|
||||
css={styles.previewPanel}
|
||||
// This tabIndex is for the scrollable area of the flyout panel.
|
||||
tabIndex={0}
|
||||
>
|
||||
|
@ -168,3 +167,11 @@ export const FieldPreview = () => {
|
|||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
previewPanel: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
height: '100%',
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiModal, EuiModalBody } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiModal, EuiModalBody, type UseEuiTheme } from '@elastic/eui';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
/**
|
||||
* By default the image formatter sets the max-width to "none" on the <img /> tag
|
||||
|
@ -30,11 +32,13 @@ interface Props {
|
|||
}
|
||||
|
||||
export const ImagePreviewModal = ({ imgHTML, closeModal }: Props) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
|
||||
return (
|
||||
<EuiModal onClose={closeModal}>
|
||||
<EuiModalBody>
|
||||
<div
|
||||
className="indexPatternFieldEditor__previewImageModal__wrapper"
|
||||
css={styles.previewImageModal}
|
||||
// We can dangerously set HTML here because this content is guaranteed to have been run through a valid field formatter first.
|
||||
dangerouslySetInnerHTML={{ __html: setMaxWidthImage(imgHTML) }} // eslint-disable-line react/no-danger
|
||||
/>
|
||||
|
@ -42,3 +46,14 @@ export const ImagePreviewModal = ({ imgHTML, closeModal }: Props) => {
|
|||
</EuiModal>
|
||||
);
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
previewImageModal: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
padding: euiTheme.size.base,
|
||||
|
||||
'& img': {
|
||||
maxWidth: '100%',
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{
|
||||
"extends": "../../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types",
|
||||
"outDir": "target/types"
|
||||
},
|
||||
"include": [
|
||||
"../../../../../typings/**/*",
|
||||
"__jest__/**/*",
|
||||
"common/**/*",
|
||||
"public/**/*",
|
||||
"server/**/*",
|
||||
"server/**/*"
|
||||
],
|
||||
"kbn_references": [
|
||||
"@kbn/core",
|
||||
|
@ -28,8 +28,7 @@
|
|||
"@kbn/config-schema",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/code-editor",
|
||||
"@kbn/css-utils"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
]
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
%inp-empty-state-footer {
|
||||
background: $euiColorLightestShade;
|
||||
margin: 0 (-$euiSizeL) (-$euiSizeL);
|
||||
padding: $euiSizeL;
|
||||
border-radius: 0 0 $euiBorderRadius $euiBorderRadius;
|
||||
|
||||
// sass-lint:disable-block mixins-before-declarations
|
||||
@include euiBreakpoint('xs', 's') {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
$inpEmptyStateMaxWidth: $euiSizeXXL * 19;
|
|
@ -1,201 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`EmptyIndexListPrompt should render normally 1`] = `
|
||||
<EuiPanel
|
||||
color="subdued"
|
||||
css="unknown styles"
|
||||
data-test-subj="indexPatternEmptyState"
|
||||
hasShadow={false}
|
||||
paddingSize="xl"
|
||||
>
|
||||
<EuiPageHeader>
|
||||
<EuiTitle>
|
||||
<h2>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Ready to try Kibana? First, you need data."
|
||||
id="indexPatternManagement.createDataView.emptyState.noDataTitle"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiPageHeader>
|
||||
<EuiSpacer
|
||||
size="xl"
|
||||
/>
|
||||
<div>
|
||||
<EuiFlexGrid
|
||||
className="inpEmptyState__cardGrid"
|
||||
columns={3}
|
||||
responsive={true}
|
||||
>
|
||||
<EuiFlexItem>
|
||||
<EuiCard
|
||||
className="inpEmptyState__card"
|
||||
description={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Add data from a variety of sources."
|
||||
id="indexPatternManagement.createDataView.emptyState.integrationCardDescription"
|
||||
/>
|
||||
}
|
||||
icon={
|
||||
<EuiIcon
|
||||
color="subdued"
|
||||
size="xl"
|
||||
type="database"
|
||||
/>
|
||||
}
|
||||
onClick={[Function]}
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Add integration"
|
||||
id="indexPatternManagement.createDataView.emptyState.integrationCardTitle"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiCard
|
||||
className="inpEmptyState__card"
|
||||
description={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Import a CSV, NDJSON, or log file."
|
||||
id="indexPatternManagement.createDataView.emptyState.uploadCardDescription"
|
||||
/>
|
||||
}
|
||||
icon={
|
||||
<EuiIcon
|
||||
color="subdued"
|
||||
size="xl"
|
||||
type="document"
|
||||
/>
|
||||
}
|
||||
onClick={[Function]}
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Upload a file"
|
||||
id="indexPatternManagement.createDataView.emptyState.uploadCardTitle"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiCard
|
||||
className="inpEmptyState__card"
|
||||
description={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Load a data set and a Kibana dashboard."
|
||||
id="indexPatternManagement.createDataView.emptyState.sampleDataCardDescription"
|
||||
/>
|
||||
}
|
||||
icon={
|
||||
<EuiIcon
|
||||
color="subdued"
|
||||
size="xl"
|
||||
type="heatmap"
|
||||
/>
|
||||
}
|
||||
onClick={[Function]}
|
||||
title={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Add sample data"
|
||||
id="indexPatternManagement.createDataView.emptyState.sampleDataCardTitle"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGrid>
|
||||
<EuiSpacer
|
||||
size="xxl"
|
||||
/>
|
||||
<div
|
||||
className="inpEmptyState__footer"
|
||||
>
|
||||
<EuiFlexGroup
|
||||
justifyContent="center"
|
||||
>
|
||||
<EuiFlexItem
|
||||
className="inpEmptyState__footerFlexItem"
|
||||
grow={false}
|
||||
>
|
||||
<EuiDescriptionList
|
||||
listItems={
|
||||
Array [
|
||||
Object {
|
||||
"description": <EuiLink
|
||||
external={true}
|
||||
href="http://elastic.co"
|
||||
target="_blank"
|
||||
>
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Read documentation"
|
||||
id="indexPatternManagement.createDataView.emptyState.readDocs"
|
||||
/>
|
||||
</EuiLink>,
|
||||
"title": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Want to learn more?"
|
||||
id="indexPatternManagement.createDataView.emptyState.learnMore"
|
||||
/>,
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
className="inpEmptyState__footerFlexItem"
|
||||
grow={false}
|
||||
>
|
||||
<EuiDescriptionList
|
||||
listItems={
|
||||
Array [
|
||||
Object {
|
||||
"description": <EuiLink
|
||||
data-test-subj="refreshIndicesButton"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Check for new data"
|
||||
id="indexPatternManagement.createDataView.emptyState.checkDataButton"
|
||||
/>
|
||||
|
||||
<EuiIcon
|
||||
size="s"
|
||||
type="refresh"
|
||||
/>
|
||||
</EuiLink>,
|
||||
"title": <Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Think you already have data?"
|
||||
id="indexPatternManagement.createDataView.emptyState.haveData"
|
||||
/>,
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer />
|
||||
<EuiText
|
||||
color="subdued"
|
||||
size="xs"
|
||||
textAlign="center"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="You can also {link}"
|
||||
id="indexPatternManagement.createDataView.emptyState.createAnywayTxt"
|
||||
values={
|
||||
Object {
|
||||
"link": <EuiLink
|
||||
data-test-subj="createAnyway"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="create a data view against hidden, system or default indices."
|
||||
id="indexPatternManagement.createDataView.emptyState.createAnywayLink"
|
||||
/>
|
||||
</EuiLink>,
|
||||
}
|
||||
}
|
||||
/>
|
||||
</EuiText>
|
||||
</div>
|
||||
</div>
|
||||
</EuiPanel>
|
||||
`;
|
|
@ -1,23 +0,0 @@
|
|||
@import '../../variables';
|
||||
@import '../../templates';
|
||||
|
||||
.inpEmptyState {
|
||||
// override EUI specificity
|
||||
max-width: $inpEmptyStateMaxWidth !important; // sass-lint:disable-line no-important
|
||||
}
|
||||
|
||||
.inpEmptyState__cardGrid {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.inpEmptyState__card {
|
||||
min-width: $euiSizeXL * 6;
|
||||
}
|
||||
|
||||
.inpEmptyState__footer {
|
||||
@extend %inp-empty-state-footer;
|
||||
}
|
||||
|
||||
.inpEmptyState__footerFlexItem {
|
||||
min-width: $euiSizeXL * 7;
|
||||
}
|
|
@ -9,51 +9,48 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EmptyIndexListPrompt } from './empty_index_list_prompt';
|
||||
import { shallow } from 'enzyme';
|
||||
import sinon from 'sinon';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useHistory: () => ({
|
||||
createHref: jest.fn(),
|
||||
}),
|
||||
}));
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { userEvent } from '@testing-library/user-event';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
|
||||
describe('EmptyIndexListPrompt', () => {
|
||||
it('should render normally', () => {
|
||||
const component = shallow(
|
||||
<EmptyIndexListPrompt
|
||||
onRefresh={() => {}}
|
||||
createAnyway={() => {}}
|
||||
addDataUrl={'http://elastic.co'}
|
||||
navigateToApp={async (appId) => {}}
|
||||
canSaveIndexPattern={true}
|
||||
/>
|
||||
it('should render normally', async () => {
|
||||
render(
|
||||
<I18nProvider>
|
||||
<EmptyIndexListPrompt
|
||||
onRefresh={jest.fn()}
|
||||
createAnyway={jest.fn()}
|
||||
addDataUrl={'http://elastic.co'}
|
||||
navigateToApp={jest.fn()}
|
||||
canSaveIndexPattern
|
||||
/>
|
||||
</I18nProvider>
|
||||
);
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
const emptyStatePanel = screen.getByTestId('indexPatternEmptyState');
|
||||
expect(emptyStatePanel).toBeInTheDocument();
|
||||
|
||||
const refreshButton = screen.getByTestId('refreshIndicesButton');
|
||||
expect(refreshButton).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('props', () => {
|
||||
describe('onRefresh', () => {
|
||||
it('is called when refresh button is clicked', () => {
|
||||
const onRefreshHandler = sinon.stub();
|
||||
it('calls onRefresh when refresh button is clicked', async () => {
|
||||
const onRefresh = jest.fn();
|
||||
render(
|
||||
<I18nProvider>
|
||||
<EmptyIndexListPrompt
|
||||
onRefresh={onRefresh}
|
||||
createAnyway={jest.fn()}
|
||||
addDataUrl={'http://elastic.co'}
|
||||
navigateToApp={jest.fn()}
|
||||
canSaveIndexPattern
|
||||
/>
|
||||
</I18nProvider>
|
||||
);
|
||||
|
||||
const component = mountWithIntl(
|
||||
<EmptyIndexListPrompt
|
||||
onRefresh={onRefreshHandler}
|
||||
createAnyway={() => {}}
|
||||
addDataUrl={'http://elastic.co'}
|
||||
navigateToApp={async (appId) => {}}
|
||||
canSaveIndexPattern={true}
|
||||
/>
|
||||
);
|
||||
const refreshButton = screen.getByTestId('refreshIndicesButton');
|
||||
await userEvent.click(refreshButton);
|
||||
|
||||
findTestSubject(component, 'refreshIndicesButton').simulate('click');
|
||||
|
||||
sinon.assert.calledOnce(onRefreshHandler);
|
||||
});
|
||||
});
|
||||
expect(onRefresh).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import './empty_index_list_prompt.scss';
|
||||
import React from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
@ -24,8 +23,10 @@ import {
|
|||
EuiLink,
|
||||
EuiText,
|
||||
EuiFlexGroup,
|
||||
type UseEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { ApplicationStart } from '@kbn/core/public';
|
||||
import { useMemoCss } from '@kbn/css-utils/public/use_memo_css';
|
||||
|
||||
export const EmptyIndexListPrompt = ({
|
||||
onRefresh,
|
||||
|
@ -40,6 +41,8 @@ export const EmptyIndexListPrompt = ({
|
|||
addDataUrl: string;
|
||||
navigateToApp: ApplicationStart['navigateToApp'];
|
||||
}) => {
|
||||
const styles = useMemoCss(componentStyles);
|
||||
|
||||
const createAnywayLink = (
|
||||
<EuiText color="subdued" textAlign="center" size="xs">
|
||||
<FormattedMessage
|
||||
|
@ -61,14 +64,11 @@ export const EmptyIndexListPrompt = ({
|
|||
|
||||
return (
|
||||
<EuiPanel
|
||||
className="inpEmptyState"
|
||||
data-test-subj="indexPatternEmptyState"
|
||||
color="subdued"
|
||||
hasShadow={false}
|
||||
paddingSize="xl"
|
||||
css={css`
|
||||
margin: auto;
|
||||
`}
|
||||
css={styles.wrapper}
|
||||
>
|
||||
<EuiPageHeader>
|
||||
<EuiTitle>
|
||||
|
@ -82,10 +82,10 @@ export const EmptyIndexListPrompt = ({
|
|||
</EuiPageHeader>
|
||||
<EuiSpacer size="xl" />
|
||||
<div>
|
||||
<EuiFlexGrid className="inpEmptyState__cardGrid" columns={3} responsive={true}>
|
||||
<EuiFlexGrid css={styles.cardGrid} columns={3} responsive={true}>
|
||||
<EuiFlexItem>
|
||||
<EuiCard
|
||||
className="inpEmptyState__card"
|
||||
css={styles.card}
|
||||
onClick={() => {
|
||||
navigateToApp('integrations', { path: '/browse' });
|
||||
}}
|
||||
|
@ -107,7 +107,7 @@ export const EmptyIndexListPrompt = ({
|
|||
<EuiFlexItem>
|
||||
<EuiCard
|
||||
onClick={() => navigateToApp('home', { path: '#/tutorial_directory/fileDataViz' })}
|
||||
className="inpEmptyState__card"
|
||||
css={styles.card}
|
||||
icon={<EuiIcon size="xl" type="document" color="subdued" />}
|
||||
title={
|
||||
<FormattedMessage
|
||||
|
@ -125,7 +125,7 @@ export const EmptyIndexListPrompt = ({
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiCard
|
||||
className="inpEmptyState__card"
|
||||
css={styles.card}
|
||||
onClick={() => {
|
||||
navigateToApp('home', { path: '#/tutorial_directory/sampleData' });
|
||||
}}
|
||||
|
@ -146,9 +146,9 @@ export const EmptyIndexListPrompt = ({
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGrid>
|
||||
<EuiSpacer size="xxl" />
|
||||
<div className="inpEmptyState__footer">
|
||||
<div css={styles.footer}>
|
||||
<EuiFlexGroup justifyContent="center">
|
||||
<EuiFlexItem grow={false} className="inpEmptyState__footerFlexItem">
|
||||
<EuiFlexItem grow={false} css={styles.footerItem}>
|
||||
<EuiDescriptionList
|
||||
listItems={[
|
||||
{
|
||||
|
@ -170,7 +170,7 @@ export const EmptyIndexListPrompt = ({
|
|||
]}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false} className="inpEmptyState__footerFlexItem">
|
||||
<EuiFlexItem grow={false} css={styles.footerItem}>
|
||||
<EuiDescriptionList
|
||||
listItems={[
|
||||
{
|
||||
|
@ -201,3 +201,29 @@ export const EmptyIndexListPrompt = ({
|
|||
</EuiPanel>
|
||||
);
|
||||
};
|
||||
|
||||
const componentStyles = {
|
||||
wrapper: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
maxWidth: `calc(${euiTheme.size.xxl} * 19)`,
|
||||
margin: 'auto',
|
||||
}),
|
||||
cardGrid: css({
|
||||
justifyContent: 'center',
|
||||
}),
|
||||
card: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
minWidth: `calc(${euiTheme.size.xl} * 6)`,
|
||||
}),
|
||||
footer: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
backgroundColor: euiTheme.colors.lightestShade,
|
||||
margin: `0 -${euiTheme.size.l} -${euiTheme.size.l}`,
|
||||
padding: euiTheme.size.l,
|
||||
borderRadius: `0 0 ${euiTheme.border.radius.small} ${euiTheme.border.radius.small}`,
|
||||
}),
|
||||
footerItem: ({ euiTheme }: UseEuiTheme) =>
|
||||
css({
|
||||
minWidth: `calc(${euiTheme.size.xl} * 7)`,
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"@kbn/rollup",
|
||||
"@kbn/share-plugin",
|
||||
"@kbn/shared-ux-table-persist",
|
||||
"@kbn/css-utils",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue