diff --git a/common/functions/__tests__/get_flot_axis_config.js b/common/functions/__tests__/get_flot_axis_config.js index 852f1006e58d0..dbe969bb92dc4 100644 --- a/common/functions/__tests__/get_flot_axis_config.js +++ b/common/functions/__tests__/get_flot_axis_config.js @@ -15,40 +15,40 @@ describe('getFlotAxisConfig', () => { describe('show', () => { it('hides the axis', () => { - expect(getFlotAxisConfig('x', false, columns, ticks)) + expect(getFlotAxisConfig('x', false, { columns, ticks })) .to.only.have.key('show') .and.to.have.property('show', false); - expect(getFlotAxisConfig('y', false, columns, ticks)) + expect(getFlotAxisConfig('y', false, { columns, ticks })) .to.only.have.key('show') .and.to.have.property('show', false); }); it('shows the axis', () => { - expect(getFlotAxisConfig('x', true, columns, ticks)).to.have.property('show', true); - expect(getFlotAxisConfig('y', true, columns, ticks)).to.have.property('show', true); + expect(getFlotAxisConfig('x', true, { columns, ticks })).to.have.property('show', true); + expect(getFlotAxisConfig('y', true, { columns, ticks })).to.have.property('show', true); }); it('sets show using an AxisConfig', () => { - let result = getFlotAxisConfig('x', xAxisConfig, columns, ticks); + let result = getFlotAxisConfig('x', xAxisConfig, { columns, ticks }); expect(result).to.have.property('show', xAxisConfig.show); - result = getFlotAxisConfig('y', yAxisConfig, columns, ticks); + result = getFlotAxisConfig('y', yAxisConfig, { columns, ticks }); expect(result).to.have.property('show', yAxisConfig.show); - result = getFlotAxisConfig('x', hideAxis, columns, ticks); + result = getFlotAxisConfig('x', hideAxis, { columns, ticks }); expect(result).to.have.property('show', hideAxis.show); - result = getFlotAxisConfig('y', hideAxis, columns, ticks); + result = getFlotAxisConfig('y', hideAxis, { columns, ticks }); expect(result).to.have.property('show', hideAxis.show); }); }); describe('position', () => { it('sets the position of the axis when given an AxisConfig', () => { - let result = getFlotAxisConfig('x', xAxisConfig, columns, ticks); + let result = getFlotAxisConfig('x', xAxisConfig, { columns, ticks }); expect(result).to.have.property('position', xAxisConfig.position); - result = getFlotAxisConfig('y', yAxisConfig, columns, ticks); + result = getFlotAxisConfig('y', yAxisConfig, { columns, ticks }); expect(result).to.have.property('position', yAxisConfig.position); }); @@ -59,7 +59,7 @@ describe('getFlotAxisConfig', () => { position: 'left', }; - const result = getFlotAxisConfig('x', invalidXPosition, columns, ticks); + const result = getFlotAxisConfig('x', invalidXPosition, { columns, ticks }); expect(result).to.have.property('position', 'bottom'); }); @@ -70,27 +70,27 @@ describe('getFlotAxisConfig', () => { position: 'bottom', }; - const result = getFlotAxisConfig('y', invalidYPosition, columns, ticks); + const result = getFlotAxisConfig('y', invalidYPosition, { columns, ticks }); expect(result).to.have.property('position', 'left'); }); }); describe('ticks', () => { it('adds a tick mark mapping for string columns', () => { - let result = getFlotAxisConfig('x', true, columns, ticks); + let result = getFlotAxisConfig('x', true, { columns, ticks }); expect(result.ticks).to.eql([[2, 'product1'], [1, 'product2']]); - result = getFlotAxisConfig('x', xAxisConfig, columns, ticks); + result = getFlotAxisConfig('x', xAxisConfig, { columns, ticks }); expect(result.ticks).to.eql([[2, 'product1'], [1, 'product2']]); }); }); describe('mode', () => { it('sets the mode to time for date columns', () => { - let result = getFlotAxisConfig('y', true, columns, ticks); + let result = getFlotAxisConfig('y', true, { columns, ticks }); expect(result).to.have.property('mode', 'time'); - result = getFlotAxisConfig('y', yAxisConfig, columns, ticks); + result = getFlotAxisConfig('y', yAxisConfig, { columns, ticks }); expect(result).to.have.property('mode', 'time'); }); }); diff --git a/common/functions/__tests__/get_font_spec.js b/common/functions/__tests__/get_font_spec.js new file mode 100644 index 0000000000000..d024b832ff0e6 --- /dev/null +++ b/common/functions/__tests__/get_font_spec.js @@ -0,0 +1,31 @@ +import expect from 'expect.js'; +import { getFontSpec } from '../plot/get_font_spec'; +import { fontStyle } from './fixtures/test_styles'; + +describe('getFontSpec', () => { + const defaultSpec = { + size: 12, + style: 'normal', + weight: 'normal', + family: '"Open Sans", Helvetica, Arial, sans-serif', + color: '#000', + }; + + describe('default output', () => { + it('returns the default spec object', () => { + expect(getFontSpec()).to.eql(defaultSpec); + }); + }); + + describe('convert from fontStyle object', () => { + it('returns plot font spec', () => { + expect(getFontSpec(fontStyle)).to.eql({ + size: 12, + style: 'normal', + weight: 'bolder', + family: 'Chalkboard, serif', + color: 'pink', + }); + }); + }); +}); diff --git a/common/functions/__tests__/plot.js b/common/functions/__tests__/plot.js index 6d5bcb8b35aa1..13389e8d78041 100644 --- a/common/functions/__tests__/plot.js +++ b/common/functions/__tests__/plot.js @@ -131,8 +131,15 @@ describe('plot', () => { describe('font', () => { it('sets the font style', () => { const result = fn(testPlot, { font: fontStyle }).value; - expect(result).to.have.property('font'); - expect(result.font).to.eql(fontStyle); + const style = { + size: 12, + style: 'normal', + weight: 'bolder', + family: 'Chalkboard, serif', + color: 'pink', + }; + expect(result.options.xaxis.font).to.eql(style); + expect(result.options.yaxis.font).to.eql(style); }); // TODO: write test when using an instance of the interpreter diff --git a/common/functions/__tests__/render.js b/common/functions/__tests__/render.js index aad55c4066864..586f91c87a212 100644 --- a/common/functions/__tests__/render.js +++ b/common/functions/__tests__/render.js @@ -21,7 +21,7 @@ describe('render', () => { it('returns a render', () => { const result = fn(renderTable, { as: 'debug', - css: '".canvas__element { background-color: red; }"', + css: '".canvasRenderEl { background-color: red; }"', containerStyle: containerStyle, }); @@ -44,10 +44,10 @@ describe('render', () => { describe('css', () => { it('sets the custom CSS for the render elemnt', () => { const result = fn(renderTable, { - css: '".canvas__element { background-color: red; }"', + css: '".canvasRenderEl { background-color: red; }"', }); - expect(result).to.have.property('css', '".canvas__element { background-color: red; }"'); + expect(result).to.have.property('css', '".canvasRenderEl { background-color: red; }"'); }); it("defaults to '* > * {}'", () => { diff --git a/common/functions/plot/get_flot_axis_config.js b/common/functions/plot/get_flot_axis_config.js index 5f5c24e73703c..8fd9736985c45 100644 --- a/common/functions/plot/get_flot_axis_config.js +++ b/common/functions/plot/get_flot_axis_config.js @@ -1,7 +1,7 @@ import { get, map } from 'lodash'; import { getType } from '../../lib/get_type'; -export const getFlotAxisConfig = (axis, argValue, columns, ticks) => { +export const getFlotAxisConfig = (axis, argValue, { columns, ticks, font } = {}) => { if (!argValue || argValue.show === false) return { show: false }; const config = { show: true }; @@ -23,5 +23,7 @@ export const getFlotAxisConfig = (axis, argValue, columns, ticks) => { if (axisType === 'date') config.mode = 'time'; + if (typeof font === 'object') config.font = font; + return config; }; diff --git a/common/functions/plot/get_font_spec.js b/common/functions/plot/get_font_spec.js new file mode 100644 index 0000000000000..bc9a81bf20ea7 --- /dev/null +++ b/common/functions/plot/get_font_spec.js @@ -0,0 +1,24 @@ +// converts the output of the font function to a flot font spec +// for font spec, see https://github.com/flot/flot/blob/master/API.md#customizing-the-axes +const defaultSpec = { + size: 12, + style: 'normal', + weight: 'normal', + family: '"Open Sans", Helvetica, Arial, sans-serif', + color: '#000', +}; + +export const getFontSpec = argFont => { + if (!argFont || !argFont.spec) return defaultSpec; + + const { fontSize, fontStyle, fontWeight, fontFamily, color } = argFont.spec; + const size = fontSize && Number(fontSize.replace('px', '')); + + return { + size: !isNaN(size) ? size : defaultSpec.size, + style: fontStyle || defaultSpec.style, + weight: fontWeight || defaultSpec.weight, + family: fontFamily || defaultSpec.family, + color: color || defaultSpec.color, + }; +}; diff --git a/common/functions/plot/index.js b/common/functions/plot/index.js index 522dbdc379cac..fcfff36f5818f 100644 --- a/common/functions/plot/index.js +++ b/common/functions/plot/index.js @@ -3,6 +3,7 @@ import keyBy from 'lodash.keyby'; import { getColorsFromPalette } from '../../lib/get_colors_from_palette'; import { getLegendConfig } from '../../lib/get_legend_config'; import { getFlotAxisConfig } from './get_flot_axis_config'; +import { getFontSpec } from './get_font_spec'; import { seriesStyleToFlot } from './series_style_to_flot'; import { getTickHash } from './get_tick_hash'; @@ -54,10 +55,9 @@ export const plot = () => ({ }, fn: (context, args) => { const seriesStyles = keyBy(args.seriesStyle || [], 'label') || {}; - const sortedRows = sortBy(context.rows, ['x', 'y', 'color', 'size', 'text']); - const ticks = getTickHash(context.columns, sortedRows); + const font = args.font ? getFontSpec(args.font) : {}; const data = map(groupBy(sortedRows, 'color'), (series, label) => { const seriesStyle = seriesStyles[label] || args.defaultStyle; @@ -102,15 +102,22 @@ export const plot = () => ({ type: 'render', as: 'plot', value: { - font: args.font, data: sortBy(data, 'label'), options: { canvas: false, colors: getColorsFromPalette(args.palette, data.length), legend: getLegendConfig(args.legend, data.length), grid: gridConfig, - xaxis: getFlotAxisConfig('x', args.xaxis, context.columns, ticks), - yaxis: getFlotAxisConfig('y', args.yaxis, context.columns, ticks), + xaxis: getFlotAxisConfig('x', args.xaxis, { + columns: context.columns, + ticks, + font, + }), + yaxis: getFlotAxisConfig('y', args.yaxis, { + columns: context.columns, + ticks, + font, + }), series: { shadowSize: 0, ...seriesStyleToFlot(args.defaultStyle), diff --git a/common/lib/ast.js b/common/lib/ast.js index 624d8da709236..07362377942a2 100644 --- a/common/lib/ast.js +++ b/common/lib/ast.js @@ -88,7 +88,7 @@ export function fromExpression(expression, type = 'expression') { try { return parse(String(expression), { startRule: type }); } catch (e) { - throw new Error(`Unable to parse expression: ${expression}\n ${e.message}`); + throw new Error(`Unable to parse expression: ${e.message}`); } } diff --git a/package.json b/package.json index f6417eee50cf5..cf0043b9ffe98 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ }, "dependencies": { "@elastic/datemath": "^4.0.2", - "@elastic/eui": "^0.0.38-bugfix.1", + "@elastic/eui": "^3.0.0", "@elastic/numeral": "^2.3.2", "@scant/router": "^0.1.0", "axios": "^0.18.0", diff --git a/public/app.js b/public/app.js index 04d7395df3715..359b791e6673f 100644 --- a/public/app.js +++ b/public/app.js @@ -4,8 +4,6 @@ import './angular/config'; import './angular/services'; import { CanvasRootController } from './angular/controllers'; -// TODO: We needed button style support. Remove this and hackery.less when you can -import 'bootstrap/dist/css/bootstrap.css'; import './style/index.css'; // load the application diff --git a/public/apps/home/home_app.js b/public/apps/home/home_app.js index 49d45998f294e..0f2688772aa32 100644 --- a/public/apps/home/home_app.js +++ b/public/apps/home/home_app.js @@ -1,13 +1,21 @@ import React from 'react'; +import { EuiTitle, EuiText, EuiSpacer, EuiPanel } from '@elastic/eui'; import { WorkpadLoader } from '../../components/workpad_loader'; export const HomeApp = () => ( -
-

Canvas

-

- Welcome to Canvas! To get started, create a new workpad, or load an existing workpad from the - controls below. -

- {}} /> +
+ +

Canvas

+
+ +

+ Welcome to Canvas! To get started, create a new workpad, or load an existing workpad from + the controls below. +

+
+ + + {}} /> +
); diff --git a/public/apps/home/home_app.scss b/public/apps/home/home_app.scss index 4cc13b790affc..94b26de856de3 100644 --- a/public/apps/home/home_app.scss +++ b/public/apps/home/home_app.scss @@ -1,9 +1,3 @@ -.canvas__home_app { - padding: $euiSizeS; - - .canvas__workpad_loader { - background-color: $euiColorDarkestShade; - color: $euiColorLightShade; - padding: $euiSizeS; - } +.canvasHomeApp { + padding: $euiSize; } diff --git a/public/apps/workpad/workpad_app/workpad_app.js b/public/apps/workpad/workpad_app/workpad_app.js index 84313886e4c57..fde8c22456171 100644 --- a/public/apps/workpad/workpad_app/workpad_app.js +++ b/public/apps/workpad/workpad_app/workpad_app.js @@ -20,22 +20,34 @@ export class WorkpadApp extends React.PureComponent { const { editing, deselectElement } = this.props; return ( -
-
-
- -
- +
+
+
+
+
+ +
+ +
+
+ +
+
+ + {editing && ( +
+ +
+ )}
- {editing && ( -
- + + {editing ? ( +
+
- )} + ) : null}
- - {editing ? : null}
); } diff --git a/public/apps/workpad/workpad_app/workpad_app.scss b/public/apps/workpad/workpad_app/workpad_app.scss index 4d619776eb7ed..f0e62358b3405 100644 --- a/public/apps/workpad/workpad_app/workpad_app.scss +++ b/public/apps/workpad/workpad_app/workpad_app.scss @@ -1,36 +1,71 @@ -.canvas__workpad_app { +.canvasLayout { display: flex; + background: $euiColorLightestShade; flex-grow: 1; - flex-direction: column; overflow: hidden; } -.canvas__workpad_app--main { - background-color: $euiColorLightestShade; +.canvasLayout__rows { display: flex; - flex: 1 1 auto; - flex-direction: row; - height: 0px; // Essentially a hack to make the sidebar and workspace scroll when the tray is open + flex-direction: column; + flex-grow: 1; + max-height: 100vh; } -.canvas__workpad_app--workpad { - background-color: $euiColorLightestShade; - padding: $euiSize; +.canvasLayout__cols { + display: flex; + align-items: stretch; flex-grow: 1; +} + +.canvasLayout__stage { + flex-grow: 1; + flex-basis: 0%; display: flex; flex-direction: column; - overflow: auto; } -.canvas__workpad_app--workspace { - flex: 0 0; - width: 0; +.canvasLayout__stageHeader { + flex-grow: 0; + flex-basis: auto; + padding: $euiSizeM $euiSize $euiSizeS $euiSize; +} + +.canvasLayout__stageContent { + flex-grow: 1; + flex-basis: 0%; + position: relative; } -.canvas__workpad_app--sidebar { - background-color: darken($euiColorLightestShade, 2%); +.canvasLayout__stageContentOverflow { + @include euiScrollBar; + + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + overflow: auto; + display: flex; + align-items: center; +} + +.canvasLayout__sidebar { + flex-grow: 0; + flex-basis: auto; width: 350px; + background: darken($euiColorLightestShade, 2%); + display: flex; + + .euiPanel { + margin-bottom: $euiSizeS; + } +} + +.canvasLayout__footer { flex-grow: 0; - overflow: auto; - border-left: $euiBorderThin; + flex-basis: auto; + width: 100%; + background-color: $euiColorLightestShade; + z-index: $euiZNavigation; } diff --git a/public/components/alignment_guide/alignment_guide.js b/public/components/alignment_guide/alignment_guide.js index dc6919793fff3..db6b03142c215 100644 --- a/public/components/alignment_guide/alignment_guide.js +++ b/public/components/alignment_guide/alignment_guide.js @@ -12,7 +12,7 @@ export const AlignmentGuide = ({ transformMatrix, a, b }) => { position: 'absolute', transform: aero.dom.matrixToCSS(transformMatrix), }; - return
; + return
; }; AlignmentGuide.propTypes = { diff --git a/public/components/alignment_guide/alignment_guide.scss b/public/components/alignment_guide/alignment_guide.scss index 920a05d9789f5..27f06b42df453 100644 --- a/public/components/alignment_guide/alignment_guide.scss +++ b/public/components/alignment_guide/alignment_guide.scss @@ -1,4 +1,4 @@ -.canvas__alignment-guide { +.canvasAlignmentGuide { transform-origin: center center; /* the default, only for clarity */ transform-style: preserve-3d; } diff --git a/public/components/app/app.js b/public/components/app/app.js index c197be7d82d72..8972776da07c6 100644 --- a/public/components/app/app.js +++ b/public/components/app/app.js @@ -42,7 +42,7 @@ export class App extends React.PureComponent { const restoreRoute = storage.get(LOCALSTORAGE_LASTPAGE); return ( -
+
{ return ( -
- {displayName} -
- {help} -
+ ); }; diff --git a/public/components/arg_add/arg_add.scss b/public/components/arg_add/arg_add.scss index c0d4b91f8829c..39dd0fdd735e8 100644 --- a/public/components/arg_add/arg_add.scss +++ b/public/components/arg_add/arg_add.scss @@ -1,8 +1,7 @@ - -.canvas__arg--add { - cursor: pointer; - padding: $euiSizeXS; - padding-left: $euiSizeS; +.canvasArg__add { + padding: $euiSizeM; + text-align: left; + width: 100%; &:not(:last-child) { border-bottom: $euiBorderThin; diff --git a/public/components/arg_add_popover/arg_add_popover.js b/public/components/arg_add_popover/arg_add_popover.js index ad6676aca681e..b9462cab8250e 100644 --- a/public/components/arg_add_popover/arg_add_popover.js +++ b/public/components/arg_add_popover/arg_add_popover.js @@ -10,7 +10,12 @@ export const ArgAddPopover = ({ options }) => { ); return ( - + {({ closePopover }) => options.map(opt => ( { ); const extendedArg = ( -
+
{ ); return ( -
+
{ const { argId, className, label, help, expandable, children, simpleArg, initialIsOpen } = props; return ( -
+
{expandable ? ( - {label} + + + {label} + } extraAction={simpleArg} initialIsOpen={initialIsOpen} > - {children} +
{children}
) : ( simpleArg && ( - - {label} - - } - id={argId} - > + {simpleArg} ) diff --git a/public/components/arg_form/arg_simple_form.js b/public/components/arg_form/arg_simple_form.js index a1640dc324d4e..77b82bb87be1c 100644 --- a/public/components/arg_form/arg_simple_form.js +++ b/public/components/arg_form/arg_simple_form.js @@ -1,28 +1,33 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiButtonIcon } from '@elastic/eui'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { TooltipIcon } from '../tooltip_icon'; // This is what is being generated by render() from the Arg class. It is called in FunctionForm export const ArgSimpleForm = ({ children, required, valueMissing, onRemove }) => { return ( -
-
{children}
- {!required && ( -
- -
- )} + + {children} {valueMissing && ( -
+ -
+ + )} + + {!required && ( + )} -
+ ); }; diff --git a/public/components/arg_form/pending_arg_value.js b/public/components/arg_form/pending_arg_value.js index 52c2a16f59e0e..8f836f2aa44f1 100644 --- a/public/components/arg_form/pending_arg_value.js +++ b/public/components/arg_form/pending_arg_value.js @@ -33,14 +33,14 @@ export class PendingArgValue extends React.PureComponent { const { label, argTypeInstance } = this.props; return ( -
+
-
+
diff --git a/public/components/arg_form/simple_failure.js b/public/components/arg_form/simple_failure.js index bc4449e41fd01..2d2c73589a16e 100644 --- a/public/components/arg_form/simple_failure.js +++ b/public/components/arg_form/simple_failure.js @@ -3,11 +3,11 @@ import { TooltipIcon } from '../tooltip_icon'; // This is what is being generated by render() from the Arg class. It is called in FunctionForm export const SimpleFailure = () => ( -
+
); diff --git a/public/components/asset_manager/asset_manager.js b/public/components/asset_manager/asset_manager.js index 9835f1142fe08..43b002f4cf13f 100644 --- a/public/components/asset_manager/asset_manager.js +++ b/public/components/asset_manager/asset_manager.js @@ -1,8 +1,26 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiImage, EuiButtonIcon } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiButtonIcon, + EuiButtonEmpty, + EuiButton, + EuiOverlayMask, + EuiModal, + EuiModalHeader, + EuiModalBody, + EuiText, + EuiImage, + EuiPanel, + EuiModalFooter, + EuiModalHeaderTitle, + EuiFlexGrid, + EuiProgress, + EuiSpacer, + EuiTextColor, +} from '@elastic/eui'; import { ConfirmModal } from '../confirm_modal'; -import { RemoveIcon } from '../remove_icon'; import { Clipboard } from '../clipboard'; import { Download } from '../download'; @@ -14,8 +32,12 @@ export class AssetManager extends React.PureComponent { state = { deleteId: null, + isModalVisible: false, }; + showModal = () => this.setState({ isModalVisible: true }); + closeModal = () => this.setState({ isModalVisible: false }); + doDelete = () => { this.resetDelete(); this.props.removeAsset(this.state.deleteId); @@ -23,77 +45,124 @@ export class AssetManager extends React.PureComponent { resetDelete = () => this.setState({ deleteId: null }); - renderAsset = asset => { - return ( - -
+ renderAsset = asset => ( + + +
- - - {asset.id} - - - - - - - - - - - -
- this.setState({ deleteId: asset.id })} - /> + + + +

+ {asset.id} +
+ + ({Math.round(asset.value.length / 1024)} kb) + +

+
+ + + + + + + + + + + + + + + + this.setState({ deleteId: asset.id })} + /> + +
- ); - }; +
+ ); render() { + const { isModalVisible } = this.state; + + const assetMaxLimit = 25000; + + const assetsTotal = Math.round( + this.props.assets.reduce((total, asset) => total + asset.value.length, 0) / 1024 + ); + + const percentageUsed = Math.round(assetsTotal / assetMaxLimit * 100); + + const assetModal = isModalVisible ? ( + + + + + Manage workpad assets + + + + + + + {percentageUsed}% space used + + + + + +

+ Below are the image assets that you added to this workpad. To reclaim space, delete + assets that you no longer need. Unfortunately, any assets that are actually in use + cannot be determined at this time. +

+
+ + {this.props.assets.map(this.renderAsset)} + +
+ + + Close + + +
+
+ ) : null; + return ( -
-
-

Manage Workpad Assets

-

- Below are the image assets you have added to this workpad via image uploads, sorted by - when you added them. Workpads are limited in size.{' '} - You can reclaim space by deleting assets that you no longer needed. - Sorry, I can't tell you which assets are currently in use: We're working on that, I - promise. -

-

- I can tell you that the current approximate size of your uncompressed assets is{' '} - - {Math.round( - this.props.assets.reduce((total, asset) => total + asset.value.length, 0) / 1024 - )}KB - -

-
- {this.props.assets.map(this.renderAsset)} + + + Manage assets + + + {assetModal} -
+ ); } } diff --git a/public/components/asset_manager/asset_manager.scss b/public/components/asset_manager/asset_manager.scss index fa8087290fc9d..55f569dcddadf 100644 --- a/public/components/asset_manager/asset_manager.scss +++ b/public/components/asset_manager/asset_manager.scss @@ -1,44 +1,56 @@ -.canvas__asset-manager { - .canvas__asset-manager--asset { - display: inline-block; - position: relative; - margin-right: $euiSize; - margin-bottom: $euiSize; - height: 200px; - width: 200px; - } +.canvasAssetManager { + max-width: 1000px; - .canvas__asset-manager--thumb { - overflow: hidden; - width: 100%; - height: 100%; + .canvasAssetManager__modalHeader { + flex-wrap: wrap; + } - .canvas_asset-manager-image { + .canvasAssetManager__modalHeaderTitle { + @include euiBreakpoint('xs', 's') { width: 100%; - height: 100%; + padding-bottom: $euiSize; } + } - img { - object-fit: cover; - min-height: 200px; + .canvasAssetManager__meterWrapper { + flex-grow: 0; + min-width: 40%; + align-items: center; + justify-content: flex-end; + padding-right: $euiSize; + + @include euiBreakpoint('xs', 's') { + flex-grow: 1; } } - .canvas__asset-manager--asset-identifier { - position: absolute; - bottom: 0; - background-color: transparentize($euiColorDarkestShade, 0.2); - border-radius: 0 0 $euiBorderThin $euiBorderThin; - padding: $euiSizeXS; - white-space: nowrap; - overflow: hidden; - width: 100%; - - .asset-id { - font-size: $euiFontSizeS; - display: block; - overflow: hidden; - text-overflow: ellipsis; + .canvasAssetManager__meterLabel { + margin: 0; + } + + // ASSETS LIST + + .canvasAssetManager__asset { + text-align: center; + overflow: hidden; // hides image from outer panel boundaries + } + + .canvasAssetManager__thumb { + margin: -$euiSizeS; + margin-bottom: 0; + font-size: 0; // eliminates any extra space around img + } + + .canvasAssetManager__img { + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + img { + width: auto; + max-width: 100%; + height: 164px; // nice default proportions for typical 4x3 images + opacity: 0; // only show the background image (which will properly keep proportions) } } } diff --git a/public/components/border_connection/border_connection.js b/public/components/border_connection/border_connection.js index be06da018fb30..21e6899aa41c9 100644 --- a/public/components/border_connection/border_connection.js +++ b/public/components/border_connection/border_connection.js @@ -11,7 +11,7 @@ export const BorderConnection = ({ transformMatrix, a, b }) => { position: 'absolute', transform: aero.dom.matrixToCSS(transformMatrix), }; - return
; + return
; }; BorderConnection.propTypes = { diff --git a/public/components/border_connection/border_connection.scss b/public/components/border_connection/border_connection.scss index 709e409789ea7..3171a25182110 100644 --- a/public/components/border_connection/border_connection.scss +++ b/public/components/border_connection/border_connection.scss @@ -1,4 +1,4 @@ -.canvas__border-connection { +.canvasBorder--connection { position: absolute; top: 0; width: 100%; diff --git a/public/components/border_resize_handle/border_resize_handle.js b/public/components/border_resize_handle/border_resize_handle.js index d61a7d63e3d30..aeed21a333c56 100644 --- a/public/components/border_resize_handle/border_resize_handle.js +++ b/public/components/border_resize_handle/border_resize_handle.js @@ -4,7 +4,7 @@ import aero from '../../lib/aeroelastic'; export const BorderResizeHandle = ({ transformMatrix }) => (
); diff --git a/public/components/border_resize_handle/border_resize_handle.scss b/public/components/border_resize_handle/border_resize_handle.scss index 1d7981bac318c..db8b926ba8221 100644 --- a/public/components/border_resize_handle/border_resize_handle.scss +++ b/public/components/border_resize_handle/border_resize_handle.scss @@ -1,4 +1,4 @@ -.canvas__border-resize-handle { +.canvasBorderResizeHandle { transform-origin: center center; /* the default, only for clarity */ transform-style: preserve-3d; display: block; diff --git a/public/components/color_dot/color_dot.js b/public/components/color_dot/color_dot.js index e352c6b2d6669..41eff6ff8b0db 100644 --- a/public/components/color_dot/color_dot.js +++ b/public/components/color_dot/color_dot.js @@ -3,9 +3,9 @@ import PropTypes from 'prop-types'; export const ColorDot = ({ value, children }) => { return ( -
-
-
+
+
+
{children}
diff --git a/public/components/color_dot/color_dot.scss b/public/components/color_dot/color_dot.scss index bcd623ed80dd9..473497506a893 100644 --- a/public/components/color_dot/color_dot.scss +++ b/public/components/color_dot/color_dot.scss @@ -1,24 +1,24 @@ -.canvas__color-dot { +.canvasColorDot { display: inline-block; position: relative; height: $euiSizeXL; width: $euiSizeXL; - .canvas__color-dot--background { + .canvasColorDot__background { position: absolute; height: $euiSizeXL; width: $euiSizeXL; - border-radius: 16px; + border-radius: $euiBorderRadius; top: 0; left: 0; } - .canvas__color-dot--foreground { + .canvasColorDot__foreground { position: absolute; - border: $euiBorderThick; + border: $euiBorderThin; height: $euiSizeXL; width: $euiSizeXL; - border-radius: $euiSize; + border-radius: $euiBorderRadius; top: 0; left: 0; display: flex; diff --git a/public/components/color_manager/color_manager.js b/public/components/color_manager/color_manager.js index f91532a0c50a9..94b2b43c3f7b0 100644 --- a/public/components/color_manager/color_manager.js +++ b/public/components/color_manager/color_manager.js @@ -10,6 +10,7 @@ export const ColorManager = ({ value, addColor, removeColor, onChange }) => ( onChange(e.target.value)} diff --git a/public/components/color_palette/color_palette.js b/public/components/color_palette/color_palette.js index 56f767eb1abf8..6f17ae756e7f5 100644 --- a/public/components/color_palette/color_palette.js +++ b/public/components/color_palette/color_palette.js @@ -6,14 +6,14 @@ import { ColorDot } from '../color_dot'; import { ItemGrid } from '../item_grid'; export const ColorPalette = ({ value, colors, colorsPerRow, onChange }) => ( -
+
{({ item: color }) => ( onChange(color)} - className="canvas__color-palette--dot" + className="canvasColorPalette__dot" > {color === value && ( diff --git a/public/components/color_palette/color_palette.scss b/public/components/color_palette/color_palette.scss index c90897a2c6b35..1496db27cb469 100644 --- a/public/components/color_palette/color_palette.scss +++ b/public/components/color_palette/color_palette.scss @@ -1,5 +1,5 @@ -.canvas__color-palette { - .canvas__color-palette--dot { +.canvasColorPalette { + .canvasColorPalette__dot { display: inline-block; margin: 0px $euiSizeXS $euiSizeXS 0px; } diff --git a/public/components/color_picker_mini/color_picker_mini.js b/public/components/color_picker_mini/color_picker_mini.js index 2adf9b96ef4b9..66445b6c3903f 100644 --- a/public/components/color_picker_mini/color_picker_mini.js +++ b/public/components/color_picker_mini/color_picker_mini.js @@ -16,7 +16,7 @@ export const ColorPickerMini = ({ onChange, value, anchorPosition, colors }) => return ( diff --git a/public/components/color_picker_mini/color_picker_mini.scss b/public/components/color_picker_mini/color_picker_mini.scss index 939ce8b809f0e..c1aa8d09a1a6b 100644 --- a/public/components/color_picker_mini/color_picker_mini.scss +++ b/public/components/color_picker_mini/color_picker_mini.scss @@ -1,3 +1,3 @@ -.canvas__color-picker-mini--popover { +.canvasColorPickerMini__popover { width: 250px; } diff --git a/public/components/confirm_modal/confirm_modal.js b/public/components/confirm_modal/confirm_modal.js index e14349a284bb7..a9cc635551342 100644 --- a/public/components/confirm_modal/confirm_modal.js +++ b/public/components/confirm_modal/confirm_modal.js @@ -28,7 +28,7 @@ export const ConfirmModal = props => { return ( {children} {isOpen && items.length ? ( -
+
{items.map((item, i) => (
onSelect(item)} onMouseOver={() => setSelectedIndex(i)} > diff --git a/public/components/context_menu/context_menu.scss b/public/components/context_menu/context_menu.scss index 6e01b32b6e57c..f982f8b3deedd 100644 --- a/public/components/context_menu/context_menu.scss +++ b/public/components/context_menu/context_menu.scss @@ -1,7 +1,7 @@ .contextMenu { position: relative; - .contextMenuItems { + .contextMenu__items { position: absolute; z-index: 1; width: 100%; @@ -10,7 +10,7 @@ background: $euiColorEmptyShade; border: $euiBorderThin; - .contextMenuItem { + .contextMenu__item { padding: $euiSizeS; background-color: $euiColorEmptyShade; border: $euiBorderThin; @@ -18,11 +18,11 @@ display: flex; align-self: flex-start; width: 100%; - } - .contextMenuItem.active { - background-color: $euiColorDarkShade; - color: $euiColorGhost; + &-isActive { + background-color: $euiColorDarkShade; + color: $euiColorGhost; + } } } } diff --git a/public/components/datasource/datasource_preview/datasource_preview.scss b/public/components/datasource/datasource.scss similarity index 59% rename from public/components/datasource/datasource_preview/datasource_preview.scss rename to public/components/datasource/datasource.scss index 190238406fdd3..ee6c082db1217 100644 --- a/public/components/datasource/datasource_preview/datasource_preview.scss +++ b/public/components/datasource/datasource.scss @@ -1,7 +1,11 @@ -.canvas__datasource_preview { +.canvasDataSource { background-color: $euiColorEmptyShade; color: $euiTextColor; border-radius: $euiBorderThin; margin: $euiSizeS; padding: 0 $euiSizeS; } + +.canvasDataSource__card + .canvasDataSource__card { + margin-top: $euiSizeS; +} diff --git a/public/components/datasource/datasource_component.js b/public/components/datasource/datasource_component.js index 3a35fca38c959..bc76312e05925 100644 --- a/public/components/datasource/datasource_component.js +++ b/public/components/datasource/datasource_component.js @@ -1,6 +1,13 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import { EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import { + EuiPanel, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiButtonEmpty, + EuiSpacer, +} from '@elastic/eui'; import { DatasourceSelector } from './datasource_selector'; import { DatasourcePreview } from './datasource_preview'; @@ -19,7 +26,6 @@ export const DatasourceComponent = props => { setSelecting, previewing, setPreviewing, - done, } = props; const getDatasourceFunctionNode = (name, args) => ({ @@ -40,10 +46,6 @@ export const DatasourceComponent = props => { setSelecting(false); }; - const close = () => { - if (done) done(); - }; - const save = () => { const datasourceAst = getDatasourceFunctionNode(stateDatasource.name, stateArgs); setDatasourceAst && setDatasourceAst(datasourceAst); @@ -53,48 +55,40 @@ export const DatasourceComponent = props => { return ; } - if (previewing) { - return ( + return ( + + + setSelecting(!selecting)} + > + Change your data source + + + {stateDatasource.render({ args: stateArgs, updateArgs, datasourceDef })} + + + + setPreviewing(true)} icon="check"> + Preview + + + + + Save + + + + + setPreviewing(false)} function={getDatasourceFunctionNode(stateDatasource.name, stateArgs)} /> - ); - } - - return ( -
-
{stateDatasource.render({ args: stateArgs, updateArgs, datasourceDef })}
- - - - - - - Apply - - - - setPreviewing(true)}> - Preview - - - - - Cancel - - - - setSelecting(!selecting)} - > - Change Datasource - - - -
+
); }; @@ -102,13 +96,15 @@ DatasourceComponent.propTypes = { datasources: PropTypes.array.isRequired, datasource: PropTypes.object.isRequired, datasourceDef: PropTypes.object.isRequired, - stateDatasource: PropTypes.object.isRequired, + stateDatasource: PropTypes.shape({ + name: PropTypes.string.isRequired, + render: PropTypes.func.isRequired, + }).isRequired, selectDatasource: PropTypes.func, setDatasourceAst: PropTypes.func, stateArgs: PropTypes.object.isRequired, updateArgs: PropTypes.func, resetArgs: PropTypes.func.isRequired, - done: PropTypes.func, selecting: PropTypes.bool, setSelecting: PropTypes.func, previewing: PropTypes.bool, diff --git a/public/components/datasource/datasource_preview/datasource_preview.js b/public/components/datasource/datasource_preview/datasource_preview.js index 401521fc99bf7..09b3ba2b26e49 100644 --- a/public/components/datasource/datasource_preview/datasource_preview.js +++ b/public/components/datasource/datasource_preview/datasource_preview.js @@ -1,18 +1,41 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { + EuiOverlayMask, + EuiModal, + EuiModalBody, + EuiModalHeader, + EuiModalHeaderTitle, + EuiSpacer, + EuiPanel, +} from '@elastic/eui'; import { Datatable } from '../../datatable'; -export const DatasourcePreview = ({ done, datatable }) => ( - // -
- {!done ? null : done()}>< Back} -
- -
-
-); +export const DatasourcePreview = ({ show, done, datatable }) => + show ? ( + + + + Datasource Preview + + +

+ Shown below are the first 10 rows of your datasource. Click Save in the + sidebar to use this data. +

+ + + + + + +
+
+
+ ) : null; DatasourcePreview.propTypes = { + show: PropTypes.bool.isRequired, datatable: PropTypes.object, done: PropTypes.func, }; diff --git a/public/components/datasource/datasource_selector.js b/public/components/datasource/datasource_selector.js index a33631fa7ac75..d8ad376d895c6 100644 --- a/public/components/datasource/datasource_selector.js +++ b/public/components/datasource/datasource_selector.js @@ -1,18 +1,19 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { MediaCard } from '../media_card'; +import { EuiCard, EuiIcon } from '@elastic/eui'; export const DatasourceSelector = ({ onSelect, datasources }) => (
{datasources.map(d => ( - } onClick={() => onSelect(d.name)} - > - {d.help} - + description={d.help} + layout="horizontal" + className="canvasDataSource__card" + /> ))}
); diff --git a/public/components/datasource/no_datasource.js b/public/components/datasource/no_datasource.js index dbd40b8b2a0f2..e3a8327f6eccc 100644 --- a/public/components/datasource/no_datasource.js +++ b/public/components/datasource/no_datasource.js @@ -1,24 +1,18 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiButton } from '@elastic/eui'; -export const NoDatasource = ({ done }) => ( -
-

No Datasource Detected

-

- Its not that you're not connected to any data. Maybe you are, maybe you're not. But if you - are, I don't know about it. I looked for a data source in your expression, because I really - wanted to give you a fancy interface to it. Alas, I could not find one that I know about. -

+import { EuiPanel, EuiText } from '@elastic/eui'; -

- I'm just going to trust that you know what you're doing. You look smart. We should hang out - more. What are you doing Thursday? -

-
- - Close - -
+export const NoDatasource = () => ( + + +

No data source present

+

+ This element does not have an attached data source. This is usually because the element is + an image or other static asset. If that's not the case you might want to check your + expression to make sure it is not malformed. +

+
+
); NoDatasource.propTypes = { diff --git a/public/components/datasource/unknown_args.js b/public/components/datasource/unknown_args.js index 0e83fbfe5dcdc..89de2dd00dd26 100644 --- a/public/components/datasource/unknown_args.js +++ b/public/components/datasource/unknown_args.js @@ -1,20 +1,30 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { EuiButton } from '@elastic/eui'; +import { EuiButton, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui'; export const UnknownArgs = ({ unknownArgs, done }) => ( -
-

Unknown Arguments Found

-

- There are arguments in the expression that can not be converting into an interface. Use the - expression editor to update the datasource. -

-

The following unknown arguments were found:

-
    {unknownArgs.map(name =>
  • {name}
  • )}
- + + +

Unknown Arguments Found

+

+ There are arguments in the expression that can not be converting into an interface. Use the + expression editor to update the datasource. +

+
+ + + + +

The following unknown arguments were found:

+
    {unknownArgs.map(name =>
  • {name}
  • )}
+
+ + + + Close -
+ ); UnknownArgs.propTypes = { diff --git a/public/components/datatable/datatable.js b/public/components/datatable/datatable.js index cec5a888dce18..5b5af8a105afe 100644 --- a/public/components/datatable/datatable.js +++ b/public/components/datatable/datatable.js @@ -1,9 +1,10 @@ import React from 'react'; import { Table } from 'react-bootstrap'; +import { EuiTextColor } from '@elastic/eui'; import PropTypes from 'prop-types'; import moment from 'moment'; import { Paginate } from '../paginate'; -import { PageControls } from '../paginate_controls'; +import { PaginateControls } from '../paginate_controls'; const getIcon = type => { if (type === null) return; @@ -43,7 +44,7 @@ export const Datatable = ({ datatable, perPage, paginate, showHeader }) => ( pageNumber, totalPages, }) => ( -
+
{!showHeader ? null : ( @@ -52,7 +53,7 @@ export const Datatable = ({ datatable, perPage, paginate, showHeader }) => ( {datatable.columns.map(col => ( ))} @@ -73,7 +74,7 @@ export const Datatable = ({ datatable, perPage, paginate, showHeader }) => ( {paginate && ( - { + ({ renderable, renderFunction, size, handlers, selected }) => { const { getFilter, setFilter, done, onComplete } = handlers; return Style.it( renderable.css, -
+
@@ -71,6 +75,7 @@ ElementContent.propTypes = { render: PropTypes.func, reuseDomNode: PropTypes.bool, }), + selected: PropTypes.bool, size: PropTypes.object, handlers: PropTypes.shape({ setFilter: PropTypes.func.isRequired, diff --git a/public/components/element_content/element_content.scss b/public/components/element_content/element_content.scss new file mode 100644 index 0000000000000..b74740fdd74ef --- /dev/null +++ b/public/components/element_content/element_content.scss @@ -0,0 +1,26 @@ +// It is up to the element to handle its overflow. +.canvasElement { + height: 100%; + width: 100%; +} + +.canvasElement__content { + height: 100%; + width: 100%; +} + +.canvasWorkpad:not(.fullscreen) { + .canvasElement { + &--isSelected { + cursor: grab; + + &:active { + cursor: grabbing; + } + } + + &:not(.canvasElement--isSelected):hover { + outline: solid 1px $euiColorVis0; + } + } +} diff --git a/public/components/toolbar/element_types/element_types.js b/public/components/element_types/element_types.js similarity index 54% rename from public/components/toolbar/element_types/element_types.js rename to public/components/element_types/element_types.js index 9418a7364df5f..1efffa1b0b323 100644 --- a/public/components/toolbar/element_types/element_types.js +++ b/public/components/element_types/element_types.js @@ -1,20 +1,26 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import { EuiFieldText } from '@elastic/eui'; import { map, includes, sortBy } from 'lodash'; import lowerCase from 'lodash.lowercase'; -import { MediaCard } from '../../media_card'; +import { EuiFieldSearch, EuiContextMenuItem, EuiPopoverTitle } from '@elastic/eui'; export const ElementTypes = ({ elements, onClick, search, setSearch }) => { search = lowerCase(search); elements = sortBy(map(elements, (element, name) => ({ name, ...element })), 'displayName'); const elementList = map(elements, (element, name) => { - const { help, image, displayName, expression, filter, width, height } = element; + const { help, displayName, expression, filter, width, height } = element; const whenClicked = () => onClick({ expression, filter, width, height }); + + // Add back in icon={image} to this when Design has a full icon set const card = ( - - {help} - + + {displayName} + ); if (!search) return card; @@ -25,15 +31,17 @@ export const ElementTypes = ({ elements, onClick, search, setSearch }) => { }); return ( -
- setSearch(e.target.value)} - value={search} - /> -
{elementList}
-
+ + + setSearch(e.target.value)} + value={search} + /> + + {elementList} + ); }; diff --git a/public/components/toolbar/element_types/index.js b/public/components/element_types/index.js similarity index 84% rename from public/components/toolbar/element_types/index.js rename to public/components/element_types/index.js index 3d90b6175f929..d29f4da678358 100644 --- a/public/components/toolbar/element_types/index.js +++ b/public/components/element_types/index.js @@ -1,5 +1,5 @@ import { pure, compose, withProps, withState } from 'recompose'; -import { elementsRegistry } from '../../../lib/elements_registry'; +import { elementsRegistry } from '../../lib/elements_registry'; import { ElementTypes as Component } from './element_types'; diff --git a/public/components/element_wrapper/element_wrapper.js b/public/components/element_wrapper/element_wrapper.js index 70c4e0b8d3101..6749c33bcdfaf 100644 --- a/public/components/element_wrapper/element_wrapper.js +++ b/public/components/element_wrapper/element_wrapper.js @@ -5,13 +5,13 @@ import { ElementContent } from '../element_content'; export class ElementWrapper extends React.PureComponent { static propTypes = { - state: PropTypes.string, - error: PropTypes.object, renderable: PropTypes.object, transformMatrix: PropTypes.arrayOf(PropTypes.number).isRequired, a: PropTypes.number.isRequired, b: PropTypes.number.isRequired, + state: PropTypes.string, createHandlers: PropTypes.func.isRequired, + selected: PropTypes.bool, }; state = { @@ -29,11 +29,16 @@ export class ElementWrapper extends React.PureComponent { // wait until the handlers have been created if (!this.state.handlers) return null; - const { renderable, transformMatrix, a, b, state } = this.props; + const { selected, renderable, transformMatrix, a, b, state } = this.props; return ( - + ); } diff --git a/public/components/element_wrapper/element_wrapper.scss b/public/components/element_wrapper/element_wrapper.scss deleted file mode 100644 index b0a028886306d..0000000000000 --- a/public/components/element_wrapper/element_wrapper.scss +++ /dev/null @@ -1,5 +0,0 @@ -// It is up to the element to handle its overflow. -.canvas__element--content { - height: 100%; - width: 100%; -} diff --git a/public/components/element_wrapper/index.js b/public/components/element_wrapper/index.js index f74bee9c9a60c..4d53ea42a9607 100644 --- a/public/components/element_wrapper/index.js +++ b/public/components/element_wrapper/index.js @@ -1,13 +1,12 @@ import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { getFullscreen, getEditing } from '../../state/selectors/app'; +import { getEditing } from '../../state/selectors/app'; import { getResolvedArgs, getSelectedPage } from '../../state/selectors/workpad'; import { getState, getValue, getError } from '../../lib/resolved_arg'; import { ElementWrapper as Component } from './element_wrapper'; import { createHandlers as createHandlersWithDispatch } from './lib/handlers'; const mapStateToProps = (state, { element }) => ({ - isFullscreen: getFullscreen(state), isEditing: getEditing(state), resolvedArg: getResolvedArgs(state, element.id, 'expressionRenderable'), selectedPage: getSelectedPage(state), @@ -19,17 +18,19 @@ const mapDispatchToProps = (dispatch, { element }) => ({ const mergeProps = (stateProps, dispatchProps, ownProps) => { const { resolvedArg, selectedPage } = stateProps; - const renderable = getValue(resolvedArg); - const { element } = ownProps; + const { element, restProps } = ownProps; + const { id, selected, transformMatrix, a, b } = element; return { + ...restProps, // pass through unused props + id, //pass through useful parts of the element object + selected, + transformMatrix, + a, + b, state: getState(resolvedArg), error: getError(resolvedArg), - renderable, - transformMatrix: element.transformMatrix, - id: element.id, - a: element.a, - b: element.b, + renderable: getValue(resolvedArg), createHandlers: dispatchProps.createHandlers(selectedPage), }; }; @@ -39,5 +40,9 @@ export const ElementWrapper = connect(mapStateToProps, mapDispatchToProps, merge ElementWrapper.propTypes = { element: PropTypes.shape({ id: PropTypes.string.isRequired, + selected: PropTypes.bool, + transformMatrix: PropTypes.arrayOf(PropTypes.number).isRequired, + a: PropTypes.number.isRequired, + b: PropTypes.number.isRequired, }).isRequired, }; diff --git a/public/components/enhance/error_boundary.js b/public/components/enhance/error_boundary.js index 2b6a00d5242e4..12d97b8a8ada0 100644 --- a/public/components/enhance/error_boundary.js +++ b/public/components/enhance/error_boundary.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { omit } from 'lodash'; import { withState, withHandlers, lifecycle, mapProps, compose } from 'recompose'; @@ -22,13 +22,13 @@ export const errorBoundaryHoc = compose( ); const ErrorBoundaryComponent = props => ( -
+ {props.children({ error: props.error, errorInfo: props.errorInfo, resetErrorState: props.resetErrorState, })} -
+ ); ErrorBoundaryComponent.propTypes = { diff --git a/public/components/es_field_select/es_field_select.js b/public/components/es_field_select/es_field_select.js index dd11186520c98..8098d4c8ee72a 100644 --- a/public/components/es_field_select/es_field_select.js +++ b/public/components/es_field_select/es_field_select.js @@ -8,7 +8,8 @@ export const ESFieldSelect = ({ value = '_score', fields = [], onChange, onFocus return ( onChange(e.target.value)} onFocus={onFocus} diff --git a/public/components/es_fields_select/es_fields_select.js b/public/components/es_fields_select/es_fields_select.js index 04bda4a5eb3d2..61bab0f16abad 100644 --- a/public/components/es_fields_select/es_fields_select.js +++ b/public/components/es_fields_select/es_fields_select.js @@ -16,7 +16,7 @@ export const ESFieldsSelect = ({ selected, fields, onChange, onFocus, onBlur }) selectedOptions={selectedOptions} options={options} onChange={values => onChange(values.map(({ label }) => label))} - className="canvas__esdocs--fields" + className="canvasFieldsSelect" onFocus={onFocus} onBlur={onBlur} /> diff --git a/public/components/es_fields_select/es_fields_select.scss b/public/components/es_fields_select/es_fields_select.scss index a62088c1480a0..2785e48079dc2 100644 --- a/public/components/es_fields_select/es_fields_select.scss +++ b/public/components/es_fields_select/es_fields_select.scss @@ -1,11 +1,3 @@ -.canvas__esdocs--fields { +.canvasFieldsSelect { max-width: unset; - - .euiFormControlLayout { - max-width: unset; - - .euiComboBox__inputWrap { - max-width: unset; - } - } } diff --git a/public/components/es_index_select/es_index_select.js b/public/components/es_index_select/es_index_select.js index fe4bc3b00b06d..aaa36681004ff 100644 --- a/public/components/es_index_select/es_index_select.js +++ b/public/components/es_index_select/es_index_select.js @@ -9,6 +9,7 @@ export const ESIndexSelect = ({ value = '_all', loading, indices, onChange, onFo return ( onChange(e.target.value)} onBlur={onBlur} diff --git a/public/components/expression/element_not_selected.js b/public/components/expression/element_not_selected.js index f94be5f539ccb..e8a905f12a0e9 100644 --- a/public/components/expression/element_not_selected.js +++ b/public/components/expression/element_not_selected.js @@ -5,7 +5,12 @@ import { EuiButton } from '@elastic/eui'; export const ElementNotSelected = ({ done }) => (
Select an element to show expression input
- {done && Close} + {done && ( + + {' '} + Close + + )}
); diff --git a/public/components/expression/expression.js b/public/components/expression/expression.js index 331a3783f0d38..e654870d91829 100644 --- a/public/components/expression/expression.js +++ b/public/components/expression/expression.js @@ -1,30 +1,38 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormGroup, Button, ButtonToolbar } from 'react-bootstrap'; +import { + EuiPanel, + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiSpacer, +} from '@elastic/eui'; import { ExpressionInput } from '../expression_input'; export const Expression = ({ formState, updateValue, setExpression, done, error }) => { return ( -
- - - - - - - {done && } - -
+ + + + + + + {formState.dirty ? 'Cancel' : 'Close'} + + + + setExpression(formState.expression)} + size="s" + > + Run + + + + ); }; diff --git a/public/components/expression/expression.scss b/public/components/expression/expression.scss deleted file mode 100644 index c3237a99f66eb..0000000000000 --- a/public/components/expression/expression.scss +++ /dev/null @@ -1,9 +0,0 @@ -.canvas__expression { - - textarea { - font-size: $euiFontSize; - //font-size: $euiFontSizeS; - font-family: monospace; - } - -} diff --git a/public/components/expression_input/expression_input.js b/public/components/expression_input/expression_input.js index dff8701ad4579..293b6492f3362 100644 --- a/public/components/expression_input/expression_input.js +++ b/public/components/expression_input/expression_input.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { EuiTextArea, EuiFormRow } from '@elastic/eui'; import { getAutocompleteProposals } from '../../lib/autocomplete_proposals'; import { ContextMenu } from '../context_menu'; import { matchPairsProvider } from './match_pairs'; @@ -70,21 +71,29 @@ export class ExpressionInput extends React.Component { }; render() { + const { value, error } = this.props; + const { suggestions } = this.state; + + const helpText = error + ? null + : 'This is the coded expression that backs this element. You better know what you are doing here.'; return (
-
{getColumnName(col)}{' '} - {getIcon(getColumnType(col))} + {getIcon(getColumnType(col))}