diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx index 8c10efe1b10d9..ed34b2818b531 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx @@ -5,10 +5,14 @@ * 2.0. */ -import React, { FC, useCallback } from 'react'; +import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { useLocation } from 'react-router-dom'; import { BaseVisType, VisGroups, VisTypeAlias } from '@kbn/visualizations-plugin/public'; -import { EmbeddableFactoryDefinition, EmbeddableInput } from '@kbn/embeddable-plugin/public'; +import { + EmbeddableFactory, + EmbeddableFactoryDefinition, + EmbeddableInput, +} from '@kbn/embeddable-plugin/public'; import { trackCanvasUiMetric, METRIC_TYPE } from '../../../lib/ui_metric'; import { useEmbeddablesService, @@ -27,6 +31,11 @@ interface Props { addElement: (element: Partial) => void; } +interface UnwrappedEmbeddableFactory { + factory: EmbeddableFactory; + isEditable: boolean; +} + export const EditorMenu: FC = ({ addElement }) => { const embeddablesService = useEmbeddablesService(); const { pathname, search, hash } = useLocation(); @@ -35,6 +44,26 @@ export const EditorMenu: FC = ({ addElement }) => { const visualizationsService = useVisualizationsService(); const IS_DARK_THEME = platformService.getUISetting('theme:darkMode'); + const embeddableFactories = useMemo( + () => (embeddablesService ? Array.from(embeddablesService.getEmbeddableFactories()) : []), + [embeddablesService] + ); + + const [unwrappedEmbeddableFactories, setUnwrappedEmbeddableFactories] = useState< + UnwrappedEmbeddableFactory[] + >([]); + + useEffect(() => { + Promise.all( + embeddableFactories.map>(async (factory) => ({ + factory, + isEditable: await factory.isEditable(), + })) + ).then((factories) => { + setUnwrappedEmbeddableFactories(factories); + }); + }, [embeddableFactories]); + const createNewVisType = useCallback( (visType?: BaseVisType | VisTypeAlias) => () => { let path = ''; @@ -113,18 +142,17 @@ export const EditorMenu: FC = ({ addElement }) => { a === b ? 0 : a ? -1 : 1 ); - const factories = embeddablesService - ? Array.from(embeddablesService.getEmbeddableFactories()).filter( - ({ type, isEditable, canCreateNew, isContainerType }) => - // @ts-expect-error ts 4.5 upgrade - isEditable() && - !isContainerType && - canCreateNew() && - !['visualization', 'ml'].some((factoryType) => { - return type.includes(factoryType); - }) - ) - : []; + const factories = unwrappedEmbeddableFactories + .filter( + ({ isEditable, factory: { type, canCreateNew, isContainerType } }) => + isEditable && + !isContainerType && + canCreateNew() && + !['visualization', 'ml'].some((factoryType) => { + return type.includes(factoryType); + }) + ) + .map(({ factory }) => factory); const promotedVisTypes = getVisTypesByGroup(VisGroups.PROMOTED);