+`;
+
+exports[`Storyshots components/Toolbar no element selected 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/canvas/public/components/toolbar/__examples__/toolbar.stories.tsx b/x-pack/plugins/canvas/public/components/toolbar/__examples__/toolbar.stories.tsx
index 5907c932ddabb..bd6ad7c8dc499 100644
--- a/x-pack/plugins/canvas/public/components/toolbar/__examples__/toolbar.stories.tsx
+++ b/x-pack/plugins/canvas/public/components/toolbar/__examples__/toolbar.stories.tsx
@@ -4,36 +4,30 @@
* you may not use this file except in compliance with the Elastic License.
*/
-/*
- TODO: uncomment and fix this test to address storybook errors as a result of nested component dependencies - https://github.com/elastic/kibana/issues/58289
- */
-
-/*
-import { action } from '@storybook/addon-actions';
import { storiesOf } from '@storybook/react';
import React from 'react';
-import { Toolbar } from '../toolbar';
+import { Toolbar } from '../toolbar.component';
+
+// @ts-expect-error untyped local
+import { getDefaultElement } from '../../../state/defaults';
storiesOf('components/Toolbar', module)
- .addDecorator(story => (
-
- {story()}
-
- ))
- .add('with null metric', () => (
+ .add('no element selected', () => (
+ ))
+ .add('element selected', () => (
+
));
-*/
diff --git a/x-pack/plugins/canvas/public/components/toolbar/index.js b/x-pack/plugins/canvas/public/components/toolbar/index.js
deleted file mode 100644
index 16860063f8a45..0000000000000
--- a/x-pack/plugins/canvas/public/components/toolbar/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { connect } from 'react-redux';
-import PropTypes from 'prop-types';
-import { pure, compose, withState, getContext, withHandlers } from 'recompose';
-import { canUserWrite } from '../../state/selectors/app';
-
-import {
- getWorkpad,
- getWorkpadName,
- getSelectedPageIndex,
- getSelectedElement,
- isWriteable,
-} from '../../state/selectors/workpad';
-
-import { Toolbar as Component } from './toolbar';
-
-const mapStateToProps = (state) => ({
- workpadName: getWorkpadName(state),
- workpadId: getWorkpad(state).id,
- totalPages: getWorkpad(state).pages.length,
- selectedPageNumber: getSelectedPageIndex(state) + 1,
- selectedElement: getSelectedElement(state),
- isWriteable: isWriteable(state) && canUserWrite(state),
-});
-
-export const Toolbar = compose(
- pure,
- connect(mapStateToProps),
- getContext({
- router: PropTypes.object,
- }),
- withHandlers({
- nextPage: (props) => () => {
- const pageNumber = Math.min(props.selectedPageNumber + 1, props.totalPages);
- props.router.navigateTo('loadWorkpad', { id: props.workpadId, page: pageNumber });
- },
- previousPage: (props) => () => {
- const pageNumber = Math.max(1, props.selectedPageNumber - 1);
- props.router.navigateTo('loadWorkpad', { id: props.workpadId, page: pageNumber });
- },
- }),
- withState('tray', 'setTray', (props) => props.tray),
- withState('showWorkpadManager', 'setShowWorkpadManager', false)
-)(Component);
diff --git a/x-pack/plugins/canvas/public/components/navbar/index.js b/x-pack/plugins/canvas/public/components/toolbar/index.ts
similarity index 66%
rename from x-pack/plugins/canvas/public/components/navbar/index.js
rename to x-pack/plugins/canvas/public/components/toolbar/index.ts
index 6948ada93155d..dfa730307dafb 100644
--- a/x-pack/plugins/canvas/public/components/navbar/index.js
+++ b/x-pack/plugins/canvas/public/components/toolbar/index.ts
@@ -4,7 +4,5 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { pure } from 'recompose';
-import { Navbar as Component } from './navbar';
-
-export const Navbar = pure(Component);
+export { Toolbar } from './toolbar';
+export { Toolbar as ToolbarComponent } from './toolbar.component';
diff --git a/x-pack/plugins/canvas/public/components/toolbar/toolbar.tsx b/x-pack/plugins/canvas/public/components/toolbar/toolbar.component.tsx
similarity index 64%
rename from x-pack/plugins/canvas/public/components/toolbar/toolbar.tsx
rename to x-pack/plugins/canvas/public/components/toolbar/toolbar.component.tsx
index c5475b2559444..6905b3ed23d3f 100644
--- a/x-pack/plugins/canvas/public/components/toolbar/toolbar.tsx
+++ b/x-pack/plugins/canvas/public/components/toolbar/toolbar.component.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import React from 'react';
+import React, { FC, useState, useContext, useEffect } from 'react';
import PropTypes from 'prop-types';
import {
EuiButtonEmpty,
@@ -16,72 +16,77 @@ import {
EuiModalFooter,
EuiButton,
} from '@elastic/eui';
-import { CanvasElement } from '../../../types';
-
-import { ComponentStrings } from '../../../i18n';
-// @ts-expect-error untyped local
-import { Navbar } from '../navbar';
// @ts-expect-error untyped local
import { WorkpadManager } from '../workpad_manager';
+import { RouterContext } from '../router';
import { PageManager } from '../page_manager';
// @ts-expect-error untyped local
import { Expression } from '../expression';
import { Tray } from './tray';
+import { CanvasElement } from '../../../types';
+import { ComponentStrings } from '../../../i18n';
+
const { Toolbar: strings } = ComponentStrings;
-enum TrayType {
- pageManager = 'pageManager',
- expression = 'expression',
-}
+type TrayType = 'pageManager' | 'expression';
interface Props {
- workpadName: string;
isWriteable: boolean;
- canUserWrite: boolean;
- tray: TrayType | null;
- setTray: (tray: TrayType | null) => void;
-
- previousPage: () => void;
- nextPage: () => void;
+ selectedElement?: CanvasElement;
selectedPageNumber: number;
totalPages: number;
-
- selectedElement: CanvasElement;
-
- showWorkpadManager: boolean;
- setShowWorkpadManager: (show: boolean) => void;
+ workpadId: string;
+ workpadName: string;
}
-export const Toolbar = (props: Props) => {
- const {
- selectedElement,
- tray,
- setTray,
- previousPage,
- nextPage,
- selectedPageNumber,
- workpadName,
- totalPages,
- showWorkpadManager,
- setShowWorkpadManager,
- isWriteable,
- } = props;
+export const Toolbar: FC = ({
+ isWriteable,
+ selectedElement,
+ selectedPageNumber,
+ totalPages,
+ workpadId,
+ workpadName,
+}) => {
+ const [activeTray, setActiveTray] = useState(null);
+ const [showWorkpadManager, setShowWorkpadManager] = useState(false);
+ const router = useContext(RouterContext);
+
+ // While the tray doesn't get activated if the workpad isn't writeable,
+ // this effect will ensure that if the tray is open and the workpad
+ // changes its writeable state, the tray will close.
+ useEffect(() => {
+ if (!isWriteable && activeTray === 'expression') {
+ setActiveTray(null);
+ }
+ }, [isWriteable, activeTray]);
- const elementIsSelected = Boolean(selectedElement);
+ if (!router) {
+ return