Skip to content

Commit

Permalink
[Canvas] Improvements to Expression Editor (elastic#32336) (elastic#3…
Browse files Browse the repository at this point in the history
…2679)

* Added font size controls and expand/shrink button to expression editor

* style the expression editor controls

* Removed debug code
  • Loading branch information
cqliu1 authored Mar 7, 2019
1 parent ab9131a commit fec3f64
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 18 deletions.
1 change: 1 addition & 0 deletions x-pack/plugins/canvas/common/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const API_ROUTE_WORKPAD_STRUCTURES = `${API_ROUTE}/workpad-structures`;
export const LOCALSTORAGE_PREFIX = `kibana.canvas`;
export const LOCALSTORAGE_CLIPBOARD = `${LOCALSTORAGE_PREFIX}.clipboard`;
export const LOCALSTORAGE_AUTOCOMPLETE_ENABLED = `${LOCALSTORAGE_PREFIX}.isAutocompleteEnabled`;
export const LOCALSTORAGE_EXPRESSION_EDITOR_FONT_SIZE = `${LOCALSTORAGE_PREFIX}.expressionEditorFontSize`;
export const LOCALSTORAGE_LASTPAGE = 'canvas:lastpage';
export const FETCH_TIMEOUT = 30000; // 30 seconds
export const CANVAS_USAGE_TYPE = 'canvas';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,9 @@ export class Autocomplete extends React.Component {
) : (
''
)}
<div onMouseDown={this.onMouseDown}>{this.props.children}</div>
<div className="canvasAutocomplete--inner" onMouseDown={this.onMouseDown}>
{this.props.children}
</div>
</div>
);
}
Expand Down
83 changes: 70 additions & 13 deletions x-pack/plugins/canvas/public/components/expression/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@ import {
EuiPanel,
EuiButton,
EuiButtonEmpty,
EuiButtonIcon,
EuiFlexGroup,
EuiFlexItem,
EuiSwitch,
EuiRange,
EuiToolTip,
} from '@elastic/eui';
import { ExpressionInput } from '../expression_input';

const minFontSize = 12;
const maxFontSize = 32;

export const Expression = ({
functionDefinitions,
formState,
Expand All @@ -25,17 +31,41 @@ export const Expression = ({
error,
isAutocompleteEnabled,
toggleAutocompleteEnabled,
fontSize,
setFontSize,
isCompact,
toggleCompactView,
}) => {
return (
<EuiPanel className="canvasTray__panel">
<EuiPanel
className={`canvasTray__panel canvasExpression--${isCompact ? 'compactSize' : 'fullSize'}`}
>
<ExpressionInput
fontSize={fontSize}
isCompact={isCompact}
functionDefinitions={functionDefinitions}
error={error}
value={formState.expression}
onChange={updateValue}
isAutocompleteEnabled={isAutocompleteEnabled}
/>
<EuiFlexGroup justifyContent="spaceBetween" gutterSize="s">
<div className="canvasExpression--controls">
<EuiToolTip content={isCompact ? 'Maximize' : 'Minimize'}>
<EuiButtonIcon
size="s"
onClick={toggleCompactView}
iconType="expand"
color="subdued"
aria-label="Toggle expression window height"
/>
</EuiToolTip>
</div>
<EuiFlexGroup
className="canvasExpression--settings"
justifyContent="spaceBetween"
alignItems="center"
gutterSize="l"
>
<EuiFlexItem grow={false}>
<EuiSwitch
id="autocompleteOptIn"
Expand All @@ -45,19 +75,46 @@ export const Expression = ({
onChange={toggleAutocompleteEnabled}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexGroup alignItems="center" gutterSize="xs">
<EuiFlexItem style={{ fontSize: `${minFontSize}px` }} grow={false}>
A
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiRange
value={fontSize}
min={minFontSize}
step={4}
max={maxFontSize}
onChange={e => setFontSize(e.target.value)}
/>
</EuiFlexItem>
<EuiFlexItem grow={false} style={{ fontSize: `${maxFontSize}px` }}>
A
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup justifyContent="flexEnd" gutterSize="s">
<EuiButtonEmpty size="s" color={formState.dirty ? 'danger' : 'primary'} onClick={done}>
{formState.dirty ? 'Cancel' : 'Close'}
</EuiButtonEmpty>
<EuiButton
fill
disabled={!!error}
onClick={() => setExpression(formState.expression)}
size="s"
>
Run
</EuiButton>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
size="s"
color={formState.dirty ? 'danger' : 'primary'}
onClick={done}
>
{formState.dirty ? 'Cancel' : 'Close'}
</EuiButtonEmpty>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
fill
disabled={!!error}
onClick={() => setExpression(formState.expression)}
size="s"
>
Run
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
50 changes: 50 additions & 0 deletions x-pack/plugins/canvas/public/components/expression/expression.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.canvasExpression--compactSize {
max-height: 480px;
}

.canvasExpression--controls {
position: absolute;
right: $euiSizeXL;
top: $euiSizeL;
}

.canvasExpression--fullSize {
height: calc(100vh - 200px); // space for global nav and autocomplete popup
display: flex;
flex-direction: column;

.expressionInput {
flex-grow: 1;
}

.expressionInput--inner {
height: 100%;
}

.canvasExpression--settings {
flex-grow: 0;
}

.canvasTextArea--code {
height: 100%;
padding-right: $euiSizeXXL;
}

.autocomplete {
flex-grow: 1;

.canvasAutocomplete--inner {
height: 100%;
}
}

.autocompletePopup {
top: -102px;
height: 100px;
}

.autocompleteItems,
.autocompleteReference {
height: 98px;
}
}
17 changes: 16 additions & 1 deletion x-pack/plugins/canvas/public/components/expression/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import { getSelectedPage, getSelectedElement } from '../../state/selectors/workp
import { setExpression, flushContext } from '../../state/actions/elements';
import { getFunctionDefinitions } from '../../lib/function_definitions';
import { getWindow } from '../../lib/get_window';
import { LOCALSTORAGE_AUTOCOMPLETE_ENABLED } from '../../../common/lib/constants';
import {
LOCALSTORAGE_AUTOCOMPLETE_ENABLED,
LOCALSTORAGE_EXPRESSION_EDITOR_FONT_SIZE,
} from '../../../common/lib/constants';
import { ElementNotSelected } from './element_not_selected';
import { Expression as Component } from './expression';

Expand Down Expand Up @@ -89,11 +92,19 @@ export const Expression = compose(
const setting = storage.get(LOCALSTORAGE_AUTOCOMPLETE_ENABLED);
return setting === null ? true : setting;
}),
withState('fontSize', 'setFontSize', () => {
const fontSize = storage.get(LOCALSTORAGE_EXPRESSION_EDITOR_FONT_SIZE);
return fontSize === null ? 16 : fontSize;
}),
withState('isCompact', 'setCompact', true),
withHandlers({
toggleAutocompleteEnabled: ({ isAutocompleteEnabled, setIsAutocompleteEnabled }) => () => {
storage.set(LOCALSTORAGE_AUTOCOMPLETE_ENABLED, !isAutocompleteEnabled);
setIsAutocompleteEnabled(!isAutocompleteEnabled);
},
toggleCompactView: ({ isCompact, setCompact }) => () => {
setCompact(!isCompact);
},
updateValue: ({ setFormState }) => expression => {
setFormState({
expression,
Expand All @@ -107,6 +118,10 @@ export const Expression = compose(
}));
setExpression(exp);
},
setFontSize: ({ setFontSize }) => size => {
storage.set(LOCALSTORAGE_EXPRESSION_EDITOR_FONT_SIZE, size);
setFontSize(size);
},
}),
expressionLifecycle,
withPropsOnChange(['formState'], ({ formState }) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,21 @@ export class ExpressionInput extends React.Component {
};

render() {
const { value, error, isAutocompleteEnabled } = this.props;
const { value, error, isAutocompleteEnabled, fontSize } = 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 (
<div className="expressionInput">
<EuiFormRow fullWidth isInvalid={Boolean(error)} error={error} helpText={helpText}>
<EuiFormRow
className="expressionInput--inner"
fullWidth
isInvalid={Boolean(error)}
error={error}
helpText={helpText}
>
{isAutocompleteEnabled ? (
<Autocomplete
header={this.getHeader()}
Expand All @@ -177,6 +183,8 @@ export class ExpressionInput extends React.Component {
onChange={this.onChange}
inputRef={ref => (this.ref = ref)}
spellCheck="false"
style={{ fontSize: `${fontSize}px` }}
resize="none"
/>
</Autocomplete>
) : (
Expand All @@ -187,6 +195,8 @@ export class ExpressionInput extends React.Component {
onChange={this.onChange}
inputRef={ref => (this.ref = ref)}
spellCheck="false"
style={{ fontSize: `${fontSize}px` }}
resize="none"
/>
)}
</EuiFormRow>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
.canvasTray {
max-height: 400px;
flex-direction: column;
@include euiBottomShadowFlat;
}
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/canvas/public/style/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@import '../components/dom_preview/dom_preview';
@import '../components/element_content/element_content';
@import '../components/element_types/element_types';
@import '../components/expression/expression';
@import '../components/fullscreen/fullscreen';
@import '../components/function_form/function_form';
@import '../components/hover_annotation/hover_annotation';
Expand Down

0 comments on commit fec3f64

Please sign in to comment.