Skip to content

Commit

Permalink
[Vis: Default editor] EUIficate and Reactify the sidebar (elastic#49864)
Browse files Browse the repository at this point in the history
* EUIficate the sidebar

* Create a state reducer and a state context

* Create an editor context and actions

* Improve types

* Apply aggs reordering

* Fix functionality

* Improve types

* Fix sub_agg changes

* Remove legacy dependencies

* Watch dirty state

* Fix dirty state changes

* Update actions and reducers

* Handle keyboard submit

* Apply editor form validation

* Remove fancy forms

* Update validation

* Use embeddable instead of visualize loader

* Add auto apply behavior

* Remove legacy styles

* Remove the sidebar

* Restrict responsive to the bottom_bar

* Upgrade @elastic/eui to v14.10.0

* Replace EuiBottomBar with EuiControlBar

* Get rid of mutations in control vis

* Revert "Upgrade @elastic/eui to v14.10.0"

This reverts commit 2cd86c5.

* Replace bottom bar with a control panel for sidebar

* Replace selectors

* Use editor resizer

* Apply selectors

* Change selectors

* Fix sub agg change values

* Add collapse button

* Fix tests

* Get rid of editor editor_state_context, simplify the code

* Fix jest tests, update snapshots

* Fix types

* Moving collapse button to right of index pattern

* Tweaks bottom buttons

* Moved Vega buttons so they don’t scroll away

* Fix responsiveness

* Resolve UI comments

* Fix console resizer

* Update dev docs

* Bail out of additional render in metrics and axes

* Apply performance optimizations for metrics and axis panel

* Remove unused translations

* Use debounce when autoapply enabled

Co-authored-by: Caroline Horn <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
3 people authored and jkelastic committed Jan 17, 2020
1 parent 8fb26fa commit 9cbb683
Show file tree
Hide file tree
Showing 115 changed files with 2,218 additions and 2,206 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ This is the sidebar editor you see in many of the Kibana visualizations. You can

[[development-default-editor]]
==== `default` editor controller
The default editor controller receives an `optionsTemplate` or `optionsTabs` parameter.
These can be either an AngularJS template or React component.
The default editor controller receives an `optionsTemplate` or `optionTabs` parameter.
These tabs should be React components.

["source","js"]
-----------
Expand All @@ -220,12 +220,9 @@ These can be either an AngularJS template or React component.
description: 'Cool new chart',
editor: 'default',
editorConfig: {
optionsTemplate: '<my-custom-options-directive></my-custom-options-directive>' // or
optionsTemplate: MyReactComponent // or if multiple tabs are required:
optionsTabs: [
{ title: 'tab 1', template: '<div>....</div> },
{ title: 'tab 2', template: '<my-custom-options-directive></my-custom-options-directive>' },
{ title: 'tab 3', template: MyReactComponent }
optionTabs: [
{ title: 'tab 3', editor: MyReactComponent }
]
}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,28 @@
*/

import React from 'react';
import { EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

type ResizerMouseEvent = React.MouseEvent<HTMLDivElement, MouseEvent>;
export type ResizerMouseEvent = React.MouseEvent<HTMLButtonElement, MouseEvent>;
export type ResizerKeyDownEvent = React.KeyboardEvent<HTMLButtonElement>;

export interface Props {
onKeyDown: (eve: ResizerKeyDownEvent) => void;
onMouseDown: (eve: ResizerMouseEvent) => void;
className?: string;
}

/**
* TODO: This component uses styling constants from public UI - should be removed, next iteration should incl. horizontal and vertical resizers.
*/
export function Resizer(props: Props) {
return (
<div {...props} className="conApp__resizer" data-test-subj="splitPanelResizer">
&#xFE19;
</div>
<button
{...props}
data-test-subj="splitPanelResizer"
aria-label={i18n.translate('console.splitPanel.adjustPanelSizeAriaLabel', {
defaultMessage: 'Press left/right to adjust panels size',
})}
>
<EuiIcon type="grabHorizontal" />
</button>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,26 @@ import { usePanelContext } from '../context';

export interface Props {
children: ReactNode[] | ReactNode;
initialWidth?: string;
className?: string;

/**
* initial width of the panel in percents
*/
initialWidth?: number;
style?: CSSProperties;
}

export function Panel({ children, initialWidth = '100%', style = {} }: Props) {
const [width, setWidth] = useState(initialWidth);
export function Panel({ children, className, initialWidth = 100, style = {} }: Props) {
const [width, setWidth] = useState(`${initialWidth}%`);
const { registry } = usePanelContext();
const divRef = useRef<HTMLDivElement>(null);

useEffect(() => {
registry.registerPanel({
initialWidth,
width: initialWidth,
setWidth(value) {
setWidth(value + '%');
this.width = value;
},
getWidth() {
return divRef.current!.getBoundingClientRect().width;
Expand All @@ -44,7 +50,7 @@ export function Panel({ children, initialWidth = '100%', style = {} }: Props) {
}, [initialWidth, registry]);

return (
<div ref={divRef} style={{ ...style, width, display: 'flex' }}>
<div className={className} ref={divRef} style={{ ...style, width, display: 'flex' }}>
{children}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@
* under the License.
*/

import React, { Children, ReactNode, useRef, useState } from 'react';
import React, { Children, ReactNode, useRef, useState, useCallback } from 'react';

import { keyCodes } from '@elastic/eui';
import { PanelContextProvider } from '../context';
import { Resizer } from '../components/resizer';
import { Resizer, ResizerMouseEvent, ResizerKeyDownEvent } from '../components/resizer';
import { PanelRegistry } from '../registry';

export interface Props {
children: ReactNode;
className?: string;
resizerClassName?: string;
onPanelWidthChange?: (arrayOfPanelWidths: number[]) => any;
}

Expand All @@ -37,7 +40,12 @@ const initialState: State = { isDragging: false, currentResizerPos: -1 };

const pxToPercent = (proportion: number, whole: number) => (proportion / whole) * 100;

export function PanelsContainer({ children, onPanelWidthChange }: Props) {
export function PanelsContainer({
children,
className,
onPanelWidthChange,
resizerClassName,
}: Props) {
const [firstChild, secondChild] = Children.toArray(children);

const registryRef = useRef(new PanelRegistry());
Expand All @@ -48,25 +56,56 @@ export function PanelsContainer({ children, onPanelWidthChange }: Props) {
return containerRef.current!.getBoundingClientRect().width;
};

const handleMouseDown = useCallback(
(event: ResizerMouseEvent) => {
setState({
...state,
isDragging: true,
currentResizerPos: event.clientX,
});
},
[state]
);

const handleKeyDown = useCallback(
(ev: ResizerKeyDownEvent) => {
const { keyCode } = ev;

if (keyCode === keyCodes.LEFT || keyCode === keyCodes.RIGHT) {
ev.preventDefault();

const { current: registry } = registryRef;
const [left, right] = registry.getPanels();

const leftPercent = left.width - (keyCode === keyCodes.LEFT ? 1 : -1);
const rightPercent = right.width - (keyCode === keyCodes.RIGHT ? 1 : -1);

left.setWidth(leftPercent);
right.setWidth(rightPercent);

if (onPanelWidthChange) {
onPanelWidthChange([leftPercent, rightPercent]);
}
}
},
[onPanelWidthChange]
);

const childrenWithResizer = [
firstChild,
<Resizer
key={'resizer'}
onMouseDown={event => {
event.preventDefault();
setState({
...state,
isDragging: true,
currentResizerPos: event.clientX,
});
}}
className={resizerClassName}
onKeyDown={handleKeyDown}
onMouseDown={handleMouseDown}
/>,
secondChild,
];

return (
<PanelContextProvider registry={registryRef.current}>
<div
className={className}
ref={containerRef}
style={{ display: 'flex', height: '100%', width: '100%' }}
onMouseMove={event => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
export interface PanelController {
setWidth: (percent: number) => void;
getWidth: () => number;
initialWidth: string;
width: number;
}

export class PanelRegistry {
Expand All @@ -35,6 +35,6 @@ export class PanelRegistry {
}

getPanels() {
return this.panels.map(panel => ({ ...panel }));
return this.panels;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ describe('Split panel', () => {

const panelContainer = mount(
<PanelsContainer onPanelWidthChange={onWidthChange}>
<Panel initialWidth={'50%'}>{testComponentA}</Panel>
<Panel initialWidth={'50%'}>{testComponentB}</Panel>
<Panel initialWidth={50}>{testComponentA}</Panel>
<Panel initialWidth={50}>{testComponentB}</Panel>
</PanelsContainer>
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ export const Editor = ({ loading }: Props) => {
if (!currentTextObject) return null;

return (
<PanelsContainer onPanelWidthChange={onPanelWidthChange}>
<PanelsContainer onPanelWidthChange={onPanelWidthChange} resizerClassName="conApp__resizer">
<Panel
style={{ height: '100%', position: 'relative', minWidth: PANEL_MIN_WIDTH }}
initialWidth={firstPanelWidth + '%'}
initialWidth={firstPanelWidth}
>
{loading ? (
<EditorContentSpinner />
Expand All @@ -68,7 +68,7 @@ export const Editor = ({ loading }: Props) => {
</Panel>
<Panel
style={{ height: '100%', position: 'relative', minWidth: PANEL_MIN_WIDTH }}
initialWidth={secondPanelWidth + '%'}
initialWidth={secondPanelWidth}
>
{loading ? <EditorContentSpinner /> : <EditorOutput />}
</Panel>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9cbb683

Please sign in to comment.