From 85de1ccbb0128cb8a12f6fff3de449e9b7691d82 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 26 Sep 2024 14:24:02 -0600 Subject: [PATCH 01/41] Starting work on refactor --- .../canvas/public/components/app/index.tsx | 10 +- .../labs_control/labs_control.tsx | 10 +- .../workpad.ts => canvas_workpad_service.ts} | 83 +++++++----- .../canvas/public/services/data_views.ts | 14 -- .../canvas/public/services/embeddables.ts | 22 ---- .../public/services/kibana/data_views.ts | 50 ------- .../public/services/kibana/embeddables.ts | 22 ---- .../canvas/public/services/kibana/labs.ts | 23 ---- .../canvas/public/services/kibana/nav_link.ts | 28 ---- .../public/services/kibana/reporting.ts | 45 ------- .../public/services/kibana/ui_actions.ts | 19 --- .../public/services/kibana/visualizations.ts | 21 --- .../canvas/public/services/kibana_services.ts | 85 ++++++++++++ x-pack/plugins/canvas/public/services/labs.ts | 14 -- .../canvas/public/services/nav_link.ts | 10 -- .../canvas/public/services/reporting.ts | 13 -- .../canvas/public/services/storybook/index.ts | 60 --------- .../public/services/storybook/notify.ts | 22 ---- .../public/services/storybook/workpad.ts | 122 ------------------ .../public/services/stubs/custom_element.ts | 21 --- .../public/services/stubs/data_views.ts | 26 ---- .../public/services/stubs/embeddables.ts | 20 --- .../public/services/stubs/expressions.ts | 41 ------ .../canvas/public/services/stubs/filters.ts | 23 ---- .../canvas/public/services/stubs/index.ts | 61 --------- .../canvas/public/services/stubs/labs.ts | 25 ---- .../canvas/public/services/stubs/nav_link.ts | 17 --- .../canvas/public/services/stubs/notify.ts | 21 --- .../canvas/public/services/stubs/platform.ts | 39 ------ .../public/services/stubs/reporting.tsx | 17 --- .../public/services/stubs/ui_actions.ts | 17 --- .../public/services/stubs/visualizations.ts | 19 --- .../canvas/public/services/stubs/workpad.ts | 115 ----------------- .../canvas/public/services/ui_actions.ts | 12 -- .../canvas/public/services/visualizations.ts | 14 -- .../plugins/canvas/public/services/workpad.ts | 43 ------ 36 files changed, 148 insertions(+), 1056 deletions(-) rename x-pack/plugins/canvas/public/services/{kibana/workpad.ts => canvas_workpad_service.ts} (56%) delete mode 100644 x-pack/plugins/canvas/public/services/data_views.ts delete mode 100644 x-pack/plugins/canvas/public/services/embeddables.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/data_views.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/embeddables.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/labs.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/nav_link.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/reporting.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/ui_actions.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/visualizations.ts create mode 100644 x-pack/plugins/canvas/public/services/kibana_services.ts delete mode 100644 x-pack/plugins/canvas/public/services/labs.ts delete mode 100644 x-pack/plugins/canvas/public/services/nav_link.ts delete mode 100644 x-pack/plugins/canvas/public/services/reporting.ts delete mode 100644 x-pack/plugins/canvas/public/services/storybook/index.ts delete mode 100644 x-pack/plugins/canvas/public/services/storybook/notify.ts delete mode 100644 x-pack/plugins/canvas/public/services/storybook/workpad.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/custom_element.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/data_views.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/embeddables.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/expressions.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/filters.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/index.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/labs.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/nav_link.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/notify.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/platform.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/reporting.tsx delete mode 100644 x-pack/plugins/canvas/public/services/stubs/ui_actions.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/visualizations.ts delete mode 100644 x-pack/plugins/canvas/public/services/stubs/workpad.ts delete mode 100644 x-pack/plugins/canvas/public/services/ui_actions.ts delete mode 100644 x-pack/plugins/canvas/public/services/visualizations.ts delete mode 100644 x-pack/plugins/canvas/public/services/workpad.ts diff --git a/x-pack/plugins/canvas/public/components/app/index.tsx b/x-pack/plugins/canvas/public/components/app/index.tsx index e23891ccc9bca..c038cd4b3b6f4 100644 --- a/x-pack/plugins/canvas/public/components/app/index.tsx +++ b/x-pack/plugins/canvas/public/components/app/index.tsx @@ -5,13 +5,13 @@ * 2.0. */ -import React, { FC, useEffect } from 'react'; -import PropTypes from 'prop-types'; import { ScopedHistory } from '@kbn/core/public'; -import { useNavLinkService } from '../../services'; +import PropTypes from 'prop-types'; +import React, { FC, useEffect } from 'react'; // @ts-expect-error import { shortcutManager } from '../../lib/shortcut_manager'; import { CanvasRouter } from '../../routes'; +import { navLinksService } from '../../services/kibana_services'; import { Flyouts } from '../flyouts'; class ShortcutManagerContextWrapper extends React.Component> { @@ -29,11 +29,9 @@ class ShortcutManagerContextWrapper extends React.Component = ({ history }) => { - const { updatePath } = useNavLinkService(); - useEffect(() => { return history.listen(({ pathname, search }) => { - updatePath(pathname + search); + navLinksService.updatePath(pathname + search); }); }); diff --git a/x-pack/plugins/canvas/public/components/workpad_header/labs_control/labs_control.tsx b/x-pack/plugins/canvas/public/components/workpad_header/labs_control/labs_control.tsx index 75d6f8064f32a..6e6ca58f0dd72 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/labs_control/labs_control.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/labs_control/labs_control.tsx @@ -5,13 +5,14 @@ * 2.0. */ -import React, { useState } from 'react'; import { EuiButtonEmpty, EuiNotificationBadge } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import React, { useState } from 'react'; import { LazyLabsFlyout, withSuspense } from '@kbn/presentation-util-plugin/public'; -import { useLabsService } from '../../../services'; +import { UI_SETTINGS } from '../../../../common'; +import { coreServices, presentationUtilService } from '../../../services/kibana_services'; const strings = { getLabsButtonLabel: () => @@ -23,14 +24,13 @@ const strings = { const Flyout = withSuspense(LazyLabsFlyout, null); export const LabsControl = () => { - const { isLabsEnabled, getProjects } = useLabsService(); const [isShown, setIsShown] = useState(false); - if (!isLabsEnabled()) { + if (!coreServices.uiSettings.get(UI_SETTINGS.ENABLE_LABS_UI)) { return null; } - const projects = getProjects(['canvas']); + const projects = presentationUtilService.labsService.getProjects(['canvas']); const overrideCount = Object.values(projects).filter( (project) => project.status.isOverride ).length; diff --git a/x-pack/plugins/canvas/public/services/kibana/workpad.ts b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts similarity index 56% rename from x-pack/plugins/canvas/public/services/kibana/workpad.ts rename to x-pack/plugins/canvas/public/services/canvas_workpad_service.ts index 3b70244440cc8..6e252db689e96 100644 --- a/x-pack/plugins/canvas/public/services/kibana/workpad.ts +++ b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts @@ -5,26 +5,51 @@ * 2.0. */ -import { SavedObject } from '@kbn/core/public'; -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -import { CanvasStartDeps } from '../../plugin'; -import { CanvasWorkpadService, ResolveWorkpadResponse } from '../workpad'; - +import { ResolvedSimpleSavedObject, SavedObject } from '@kbn/core/public'; import { - API_ROUTE_WORKPAD, - DEFAULT_WORKPAD_CSS, + API_ROUTE_SHAREABLE_ZIP, API_ROUTE_TEMPLATES, + API_ROUTE_WORKPAD, API_ROUTE_WORKPAD_ASSETS, API_ROUTE_WORKPAD_STRUCTURES, - API_ROUTE_SHAREABLE_ZIP, -} from '../../../common/lib/constants'; -import { CanvasWorkpad } from '../../../types'; + DEFAULT_WORKPAD_CSS, +} from '../../common/lib'; +import type { CanvasRenderedWorkpad } from '../../shareable_runtime/types'; +import { CanvasTemplate, CanvasWorkpad } from '../../types'; +import { coreServices } from './kibana_services'; + +export type FoundWorkpads = Array>; +export type FoundWorkpad = FoundWorkpads[number]; +export interface WorkpadFindResponse { + total: number; + workpads: FoundWorkpads; +} + +export interface TemplateFindResponse { + templates: CanvasTemplate[]; +} + +export interface ResolveWorkpadResponse { + workpad: CanvasWorkpad; + outcome: ResolvedSimpleSavedObject['outcome']; + aliasId?: ResolvedSimpleSavedObject['alias_target_id']; + aliasPurpose?: ResolvedSimpleSavedObject['alias_purpose']; +} -export type CanvasWorkpadServiceFactory = KibanaPluginServiceFactory< - CanvasWorkpadService, - CanvasStartDeps ->; +export interface CanvasWorkpadService { + get: (id: string) => Promise; + resolve: (id: string) => Promise; + create: (workpad: CanvasWorkpad) => Promise; + import: (workpad: CanvasWorkpad) => Promise; + createFromTemplate: (templateId: string) => Promise; + find: (term: string) => Promise; + remove: (id: string) => Promise; + findTemplates: () => Promise; + update: (id: string, workpad: CanvasWorkpad) => Promise; + updateWorkpad: (id: string, workpad: CanvasWorkpad) => Promise; + updateAssets: (id: string, assets: CanvasWorkpad['assets']) => Promise; + getRuntimeZip: (workpad: CanvasRenderedWorkpad) => Promise; +} /* Remove any top level keys from the workpad which will be rejected by validation @@ -57,19 +82,19 @@ const sanitizeWorkpad = function (workpad: CanvasWorkpad) { return workpad; }; -export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart, startPlugins }) => { +export const workpadServiceFactory: () => CanvasWorkpadService = () => { const getApiPath = function () { return `${API_ROUTE_WORKPAD}`; }; return { get: async (id: string) => { - const workpad = await coreStart.http.get(`${getApiPath()}/${id}`, { version: '1' }); + const workpad = await coreServices.http.get(`${getApiPath()}/${id}`, { version: '1' }); return { css: DEFAULT_WORKPAD_CSS, variables: [], ...workpad }; }, export: async (id: string) => { - const workpad = await coreStart.http.get>( + const workpad = await coreServices.http.get>( `${getApiPath()}/export/${id}`, { version: '1' } ); @@ -85,7 +110,7 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart, }; }, resolve: async (id: string) => { - const { workpad, ...resolveProps } = await coreStart.http.get( + const { workpad, ...resolveProps } = await coreServices.http.get( `${getApiPath()}/resolve/${id}`, { version: '1' } ); @@ -102,7 +127,7 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart, }; }, create: (workpad: CanvasWorkpad) => { - return coreStart.http.post(getApiPath(), { + return coreServices.http.post(getApiPath(), { body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }), assets: workpad.assets || {}, @@ -112,7 +137,7 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart, }); }, import: (workpad: CanvasWorkpad) => - coreStart.http.post(`${getApiPath()}/import`, { + coreServices.http.post(`${getApiPath()}/import`, { body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }), assets: workpad.assets || {}, @@ -121,17 +146,17 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart, version: '1', }), createFromTemplate: (templateId: string) => { - return coreStart.http.post(getApiPath(), { + return coreServices.http.post(getApiPath(), { body: JSON.stringify({ templateId }), version: '1', }); }, - findTemplates: async () => coreStart.http.get(API_ROUTE_TEMPLATES, { version: '1' }), + findTemplates: async () => coreServices.http.get(API_ROUTE_TEMPLATES, { version: '1' }), find: (searchTerm: string) => { // TODO: this shouldn't be necessary. Check for usage. const validSearchTerm = typeof searchTerm === 'string' && searchTerm.length > 0; - return coreStart.http.get(`${getApiPath()}/find`, { + return coreServices.http.get(`${getApiPath()}/find`, { query: { perPage: 10000, name: validSearchTerm ? searchTerm : '', @@ -140,28 +165,28 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart, }); }, remove: (id: string) => { - return coreStart.http.delete(`${getApiPath()}/${id}`, { version: '1' }); + return coreServices.http.delete(`${getApiPath()}/${id}`, { version: '1' }); }, update: (id, workpad) => { - return coreStart.http.put(`${getApiPath()}/${id}`, { + return coreServices.http.put(`${getApiPath()}/${id}`, { body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }), version: '1', }); }, updateWorkpad: (id, workpad) => { - return coreStart.http.put(`${API_ROUTE_WORKPAD_STRUCTURES}/${id}`, { + return coreServices.http.put(`${API_ROUTE_WORKPAD_STRUCTURES}/${id}`, { body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }), version: '1', }); }, updateAssets: (id, assets) => { - return coreStart.http.put(`${API_ROUTE_WORKPAD_ASSETS}/${id}`, { + return coreServices.http.put(`${API_ROUTE_WORKPAD_ASSETS}/${id}`, { body: JSON.stringify(assets), version: '1', }); }, getRuntimeZip: (workpad) => { - return coreStart.http.post(API_ROUTE_SHAREABLE_ZIP, { + return coreServices.http.post(API_ROUTE_SHAREABLE_ZIP, { body: JSON.stringify(workpad), version: '1', }); diff --git a/x-pack/plugins/canvas/public/services/data_views.ts b/x-pack/plugins/canvas/public/services/data_views.ts deleted file mode 100644 index 86faa87bfaa59..0000000000000 --- a/x-pack/plugins/canvas/public/services/data_views.ts +++ /dev/null @@ -1,14 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { DataView } from '@kbn/data-views-plugin/common'; - -export interface CanvasDataViewsService { - getFields: (index: string) => Promise; - getDataViews: () => Promise>>; - getDefaultDataView: () => Promise | undefined>; -} diff --git a/x-pack/plugins/canvas/public/services/embeddables.ts b/x-pack/plugins/canvas/public/services/embeddables.ts deleted file mode 100644 index b8f3d7d14b5e5..0000000000000 --- a/x-pack/plugins/canvas/public/services/embeddables.ts +++ /dev/null @@ -1,22 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EmbeddableFactory, - type EmbeddableStateTransfer, - ReactEmbeddableSavedObject, -} from '@kbn/embeddable-plugin/public'; -import { FinderAttributes } from '@kbn/saved-objects-finder-plugin/common'; - -export interface CanvasEmbeddablesService { - reactEmbeddableRegistryHasKey: (key: string) => boolean; - getReactEmbeddableSavedObjects: < - TSavedObjectAttributes extends FinderAttributes - >() => IterableIterator<[string, ReactEmbeddableSavedObject]>; - getEmbeddableFactories: () => IterableIterator; - getStateTransfer: () => EmbeddableStateTransfer; -} diff --git a/x-pack/plugins/canvas/public/services/kibana/data_views.ts b/x-pack/plugins/canvas/public/services/kibana/data_views.ts deleted file mode 100644 index 27ec0bb1c5fc6..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/data_views.ts +++ /dev/null @@ -1,50 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { DataView } from '@kbn/data-views-plugin/public'; -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { ErrorStrings } from '../../../i18n'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasDataViewsService } from '../data_views'; -import { CanvasNotifyService } from '../notify'; - -const { esService: strings } = ErrorStrings; - -export type DataViewsServiceFactory = KibanaPluginServiceFactory< - CanvasDataViewsService, - CanvasStartDeps, - { - notify: CanvasNotifyService; - } ->; - -export const dataViewsServiceFactory: DataViewsServiceFactory = ({ startPlugins }, { notify }) => ({ - getDataViews: async () => { - try { - const dataViews = await startPlugins.dataViews.getIdsWithTitle(); - return dataViews.map(({ id, name, title }) => ({ id, name, title } as DataView)); - } catch (e) { - notify.error(e, { title: strings.getIndicesFetchErrorMessage() }); - } - - return []; - }, - getFields: async (dataViewTitle: string) => { - const dataView = await startPlugins.dataViews.create({ title: dataViewTitle }); - - return dataView.fields - .filter((field) => !field.name.startsWith('_')) - .map((field) => field.name); - }, - getDefaultDataView: async () => { - const dataView = await startPlugins.dataViews.getDefaultDataView(); - - return dataView - ? { id: dataView.id, name: dataView.name, title: dataView.getIndexPattern() } - : undefined; - }, -}); diff --git a/x-pack/plugins/canvas/public/services/kibana/embeddables.ts b/x-pack/plugins/canvas/public/services/kibana/embeddables.ts deleted file mode 100644 index 20f6f3feec8a4..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/embeddables.ts +++ /dev/null @@ -1,22 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasEmbeddablesService } from '../embeddables'; - -export type EmbeddablesServiceFactory = KibanaPluginServiceFactory< - CanvasEmbeddablesService, - CanvasStartDeps ->; - -export const embeddablesServiceFactory: EmbeddablesServiceFactory = ({ startPlugins }) => ({ - reactEmbeddableRegistryHasKey: startPlugins.embeddable.reactEmbeddableRegistryHasKey, - getReactEmbeddableSavedObjects: startPlugins.embeddable.getReactEmbeddableSavedObjects, - getEmbeddableFactories: startPlugins.embeddable.getEmbeddableFactories, - getStateTransfer: startPlugins.embeddable.getStateTransfer, -}); diff --git a/x-pack/plugins/canvas/public/services/kibana/labs.ts b/x-pack/plugins/canvas/public/services/kibana/labs.ts deleted file mode 100644 index 69613ae67fd85..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/labs.ts +++ /dev/null @@ -1,23 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { projectIDs } from '@kbn/presentation-util-plugin/common'; -import { UI_SETTINGS } from '../../../common'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasLabsService } from '../labs'; - -export type CanvasLabsServiceFactory = KibanaPluginServiceFactory< - CanvasLabsService, - CanvasStartDeps ->; - -export const labsServiceFactory: CanvasLabsServiceFactory = ({ startPlugins, coreStart }) => ({ - projectIDs, - isLabsEnabled: () => coreStart.uiSettings.get(UI_SETTINGS.ENABLE_LABS_UI), - ...startPlugins.presentationUtil.labsService, -}); diff --git a/x-pack/plugins/canvas/public/services/kibana/nav_link.ts b/x-pack/plugins/canvas/public/services/kibana/nav_link.ts deleted file mode 100644 index 8470c688f5b2b..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/nav_link.ts +++ /dev/null @@ -1,28 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -import { SESSIONSTORAGE_LASTPATH } from '../../../common/lib/constants'; -import { getSessionStorage } from '../../lib/storage'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasNavLinkService } from '../nav_link'; - -export type CanvasNavLinkServiceFactory = KibanaPluginServiceFactory< - CanvasNavLinkService, - CanvasStartDeps ->; - -export const navLinkServiceFactory: CanvasNavLinkServiceFactory = ({ coreStart, appUpdater }) => ({ - updatePath: (path: string) => { - appUpdater?.next(() => ({ - defaultPath: `${path}`, - })); - - getSessionStorage().set(`${SESSIONSTORAGE_LASTPATH}:${coreStart.http.basePath.get()}`, path); - }, -}); diff --git a/x-pack/plugins/canvas/public/services/kibana/reporting.ts b/x-pack/plugins/canvas/public/services/kibana/reporting.ts deleted file mode 100644 index 56b9b91e45fc6..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/reporting.ts +++ /dev/null @@ -1,45 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -import { CanvasStartDeps } from '../../plugin'; -import { CanvasReportingService } from '../reporting'; - -export type CanvasReportingServiceFactory = KibanaPluginServiceFactory< - CanvasReportingService, - CanvasStartDeps ->; - -export const reportingServiceFactory: CanvasReportingServiceFactory = ({ - startPlugins, - coreStart, -}) => { - const { reporting } = startPlugins; - - const reportingEnabled = () => ({ - getReportingPanelPDFComponent: () => reporting?.components.ReportingPanelPDFV2 || null, - }); - const reportingDisabled = () => ({ getReportingPanelPDFComponent: () => null }); - - if (!reporting) { - // Reporting is not enabled - return reportingDisabled(); - } - - if (reporting.usesUiCapabilities()) { - if (coreStart.application.capabilities.canvas?.generatePdf === true) { - // Canvas has declared Reporting as a subfeature with the `generatePdf` UI Capability - return reportingEnabled(); - } else { - return reportingDisabled(); - } - } - - // Legacy/Deprecated: Reporting is enabled as an Elasticsearch feature - return reportingEnabled(); -}; diff --git a/x-pack/plugins/canvas/public/services/kibana/ui_actions.ts b/x-pack/plugins/canvas/public/services/kibana/ui_actions.ts deleted file mode 100644 index bb621206082d1..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/ui_actions.ts +++ /dev/null @@ -1,19 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasUiActionsService } from '../ui_actions'; - -export type UiActionsServiceFactory = KibanaPluginServiceFactory< - CanvasUiActionsService, - CanvasStartDeps ->; - -export const uiActionsServiceFactory: UiActionsServiceFactory = ({ startPlugins }) => ({ - getTriggerCompatibleActions: startPlugins.uiActions.getTriggerCompatibleActions, -}); diff --git a/x-pack/plugins/canvas/public/services/kibana/visualizations.ts b/x-pack/plugins/canvas/public/services/kibana/visualizations.ts deleted file mode 100644 index 6f1728953ee8e..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/visualizations.ts +++ /dev/null @@ -1,21 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasVisualizationsService } from '../visualizations'; - -export type VisualizationsServiceFactory = KibanaPluginServiceFactory< - CanvasVisualizationsService, - CanvasStartDeps ->; - -export const visualizationsServiceFactory: VisualizationsServiceFactory = ({ startPlugins }) => ({ - showNewVisModal: startPlugins.visualizations.showNewVisModal, - getByGroup: startPlugins.visualizations.getByGroup, - getAliases: startPlugins.visualizations.getAliases, -}); diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts new file mode 100644 index 0000000000000..cf66ca88846cf --- /dev/null +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BehaviorSubject } from 'rxjs'; + +import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; +import type { AppUpdater, CoreStart } from '@kbn/core/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +// import type { DataView, DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +import type { EmbeddableStart } from '@kbn/embeddable-plugin/public/plugin'; +import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; +// import type { ReportingStart } from '@kbn/reporting-plugin/public'; +import type { SpacesApi } from '@kbn/spaces-plugin/public'; +import type { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin'; +import type { VisualizationsStart } from '@kbn/visualizations-plugin/public'; + +import { SESSIONSTORAGE_LASTPATH } from '../../common/lib'; +import { getSessionStorage } from '../lib/storage'; +import { CanvasStartDeps } from '../plugin'; + +export interface CanvasNavLinkService { + updatePath: (path: string) => void; +} + +export let coreServices: CoreStart; +export let contentManagementService: ContentManagementPublicStart; +export let dataService: DataPublicPluginStart; +// export let dataViewsService: DataViewsPublicPluginStart; +export let embeddableService: EmbeddableStart; +export let presentationUtilService: PresentationUtilPluginStart; +// export let reportingService: ReportingStart | undefined; +export let spacesService: SpacesApi | undefined; +export let uiActionsService: UiActionsPublicStart; +export let visualizationsService: VisualizationsStart; + +export let navLinksService: CanvasNavLinkService; + +const servicesReady$ = new BehaviorSubject(false); + +export const setKibanaServices = ( + kibanaCore: CoreStart, + deps: CanvasStartDeps, + appUpdater?: BehaviorSubject +) => { + coreServices = kibanaCore; + contentManagementService = deps.contentManagement; + dataService = deps.data; + // dataViewsService = deps.dataViews; + embeddableService = deps.embeddable; + presentationUtilService = deps.presentationUtil; + // reportingService = kibanaCore.application.capabilities.canvas?.generatePdf + // ? deps.reporting + // : undefined; + spacesService = deps.spaces; + uiActionsService = deps.uiActions; + visualizationsService = deps.visualizations; + + navLinksService = { + updatePath: (path: string) => { + appUpdater?.next(() => ({ + defaultPath: `${path}`, + })); + + getSessionStorage().set(`${SESSIONSTORAGE_LASTPATH}:${kibanaCore.http.basePath.get()}`, path); + }, + }; + + servicesReady$.next(true); +}; + +export const untilPluginStartServicesReady = () => { + if (servicesReady$.value) return Promise.resolve(); + return new Promise((resolve) => { + const subscription = servicesReady$.subscribe((isInitialized) => { + if (isInitialized) { + subscription.unsubscribe(); + resolve(); + } + }); + }); +}; diff --git a/x-pack/plugins/canvas/public/services/labs.ts b/x-pack/plugins/canvas/public/services/labs.ts deleted file mode 100644 index 0f20e25f31d60..0000000000000 --- a/x-pack/plugins/canvas/public/services/labs.ts +++ /dev/null @@ -1,14 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PresentationLabsService } from '@kbn/presentation-util-plugin/public'; -import { projectIDs } from '@kbn/presentation-util-plugin/common'; - -export interface CanvasLabsService extends PresentationLabsService { - projectIDs: typeof projectIDs; - isLabsEnabled: () => boolean; -} diff --git a/x-pack/plugins/canvas/public/services/nav_link.ts b/x-pack/plugins/canvas/public/services/nav_link.ts deleted file mode 100644 index 02c7ca50219a6..0000000000000 --- a/x-pack/plugins/canvas/public/services/nav_link.ts +++ /dev/null @@ -1,10 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export interface CanvasNavLinkService { - updatePath: (path: string) => void; -} diff --git a/x-pack/plugins/canvas/public/services/reporting.ts b/x-pack/plugins/canvas/public/services/reporting.ts deleted file mode 100644 index 71d90421eafa8..0000000000000 --- a/x-pack/plugins/canvas/public/services/reporting.ts +++ /dev/null @@ -1,13 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ReportingStart } from '@kbn/reporting-plugin/public'; - -type ReportingPanelPDFComponent = ReportingStart['components']['ReportingPanelPDFV2']; -export interface CanvasReportingService { - getReportingPanelPDFComponent: () => ReportingPanelPDFComponent | null; -} diff --git a/x-pack/plugins/canvas/public/services/storybook/index.ts b/x-pack/plugins/canvas/public/services/storybook/index.ts deleted file mode 100644 index 52cad460662b2..0000000000000 --- a/x-pack/plugins/canvas/public/services/storybook/index.ts +++ /dev/null @@ -1,60 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - PluginServiceProviders, - PluginServiceProvider, -} from '@kbn/presentation-util-plugin/public'; - -import { CanvasPluginServices } from '..'; -import { pluginServiceProviders as stubProviders } from '../stubs'; -import { workpadServiceFactory } from './workpad'; -import { notifyServiceFactory } from './notify'; - -export interface StorybookParams { - hasTemplates?: boolean; - useStaticData?: boolean; - workpadCount?: number; -} - -export const pluginServiceProviders: PluginServiceProviders = - { - ...stubProviders, - workpad: new PluginServiceProvider(workpadServiceFactory), - notify: new PluginServiceProvider(notifyServiceFactory), - }; - -export const argTypes = { - hasTemplates: { - name: 'Has templates?', - type: { - name: 'boolean', - }, - defaultValue: true, - control: { - type: 'boolean', - }, - }, - useStaticData: { - name: 'Use static data?', - type: { - name: 'boolean', - }, - defaultValue: false, - control: { - type: 'boolean', - }, - }, - workpadCount: { - name: 'Number of workpads', - type: { name: 'number' }, - defaultValue: 5, - control: { - type: 'range', - }, - }, -}; diff --git a/x-pack/plugins/canvas/public/services/storybook/notify.ts b/x-pack/plugins/canvas/public/services/storybook/notify.ts deleted file mode 100644 index f6f97c42a1741..0000000000000 --- a/x-pack/plugins/canvas/public/services/storybook/notify.ts +++ /dev/null @@ -1,22 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { action } from '@storybook/addon-actions'; - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -import { StorybookParams } from '.'; -import { CanvasNotifyService } from '../notify'; - -type CanvasNotifyServiceFactory = PluginServiceFactory; - -export const notifyServiceFactory: CanvasNotifyServiceFactory = () => ({ - success: (message) => action(`success: ${message}`)(), - error: (message) => action(`error: ${message}`)(), - info: (message) => action(`info: ${message}`)(), - warning: (message) => action(`warning: ${message}`)(), -}); diff --git a/x-pack/plugins/canvas/public/services/storybook/workpad.ts b/x-pack/plugins/canvas/public/services/storybook/workpad.ts deleted file mode 100644 index 9f40ccccafb3d..0000000000000 --- a/x-pack/plugins/canvas/public/services/storybook/workpad.ts +++ /dev/null @@ -1,122 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import moment from 'moment'; - -import { action } from '@storybook/addon-actions'; -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { getId } from '../../lib/get_id'; -// @ts-expect-error -import { getDefaultWorkpad } from '../../state/defaults'; - -import { StorybookParams } from '.'; -import { CanvasWorkpadService } from '../workpad'; - -import * as stubs from '../stubs/workpad'; - -export { - findNoTemplates, - findNoWorkpads, - findSomeTemplates, - getNoTemplates, - getSomeTemplates, -} from '../stubs/workpad'; - -type CanvasWorkpadServiceFactory = PluginServiceFactory; - -const TIMEOUT = 500; -const promiseTimeout = (time: number) => () => new Promise((resolve) => setTimeout(resolve, time)); - -const { findNoTemplates, findNoWorkpads, findSomeTemplates, importWorkpad } = stubs; - -const getRandomName = () => { - const lorem = - 'Lorem ipsum dolor sit amet consectetur adipiscing elit Fusce lobortis aliquet arcu ut turpis duis'.split( - ' ' - ); - return [1, 2, 3].map(() => lorem[Math.floor(Math.random() * lorem.length)]).join(' '); -}; - -const getRandomDate = ( - start: Date = moment().toDate(), - end: Date = moment().subtract(7, 'days').toDate() -) => new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toISOString(); - -export const getSomeWorkpads = (count = 3) => - Array.from({ length: count }, () => ({ - '@created': getRandomDate( - moment().subtract(3, 'days').toDate(), - moment().subtract(10, 'days').toDate() - ), - '@timestamp': getRandomDate(), - id: getId('workpad'), - name: getRandomName(), - })); - -export const findSomeWorkpads = - (count = 3, useStaticData = false, timeout = TIMEOUT) => - (_term: string) => { - return Promise.resolve() - .then(promiseTimeout(timeout)) - .then(() => ({ - total: count, - workpads: useStaticData ? stubs.getSomeWorkpads(count) : getSomeWorkpads(count), - })); - }; - -export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ - workpadCount, - hasTemplates, - useStaticData, -}) => ({ - get: (id: string) => { - action('workpadService.get')(id); - return Promise.resolve({ ...getDefaultWorkpad(), id }); - }, - resolve: (id: string) => { - action('workpadService.resolve')(id); - return Promise.resolve({ outcome: 'exactMatch', workpad: { ...getDefaultWorkpad(), id } }); - }, - findTemplates: () => { - action('workpadService.findTemplates')(); - return (hasTemplates ? findSomeTemplates() : findNoTemplates())(); - }, - import: (workpad) => { - action('workpadService.import')(workpad); - return importWorkpad(workpad); - }, - create: (workpad) => { - action('workpadService.create')(workpad); - return Promise.resolve(workpad); - }, - createFromTemplate: (templateId: string) => { - action('workpadService.createFromTemplate')(templateId); - return Promise.resolve(getDefaultWorkpad()); - }, - find: (term: string) => { - action('workpadService.find')(term); - return (workpadCount ? findSomeWorkpads(workpadCount, useStaticData) : findNoWorkpads())(term); - }, - remove: (id: string) => { - action('workpadService.remove')(id); - return Promise.resolve(); - }, - update: (id, workpad) => { - action('worpadService.update')(workpad, id); - return Promise.resolve(); - }, - updateWorkpad: (id, workpad) => { - action('workpadService.updateWorkpad')(workpad, id); - return Promise.resolve(); - }, - updateAssets: (id, assets) => { - action('workpadService.updateAssets')(assets, id); - return Promise.resolve(); - }, - getRuntimeZip: (workpad) => - Promise.resolve(new Blob([JSON.stringify(workpad)], { type: 'application/json' })), -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/custom_element.ts b/x-pack/plugins/canvas/public/services/stubs/custom_element.ts deleted file mode 100644 index 551c06ef4b65e..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/custom_element.ts +++ /dev/null @@ -1,21 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasCustomElementService } from '../custom_element'; - -type CanvasCustomElementServiceFactory = PluginServiceFactory; - -const noop = (..._args: any[]): any => {}; - -export const customElementServiceFactory: CanvasCustomElementServiceFactory = () => ({ - create: noop, - find: noop, - get: noop, - remove: noop, - update: noop, -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/data_views.ts b/x-pack/plugins/canvas/public/services/stubs/data_views.ts deleted file mode 100644 index 1b1227dba4d3f..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/data_views.ts +++ /dev/null @@ -1,26 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasDataViewsService } from '../data_views'; - -type DataViewsServiceFactory = PluginServiceFactory; - -export const dataViewsServiceFactory: DataViewsServiceFactory = () => ({ - getDataViews: () => - Promise.resolve([ - { id: 'dataview1', title: 'dataview1', name: 'Data view 1' }, - { id: 'dataview2', title: 'dataview2', name: 'Data view 2' }, - ]), - getFields: () => Promise.resolve(['field1', 'field2']), - getDefaultDataView: () => - Promise.resolve({ - id: 'defaultDataViewId', - title: 'defaultDataView', - name: 'Default data view', - }), -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/embeddables.ts b/x-pack/plugins/canvas/public/services/stubs/embeddables.ts deleted file mode 100644 index 95131efec2bde..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/embeddables.ts +++ /dev/null @@ -1,20 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasEmbeddablesService } from '../embeddables'; - -type EmbeddablesServiceFactory = PluginServiceFactory; - -const noop = (..._args: any[]): any => {}; - -export const embeddablesServiceFactory: EmbeddablesServiceFactory = () => ({ - reactEmbeddableRegistryHasKey: noop, - getReactEmbeddableSavedObjects: noop, - getEmbeddableFactories: noop, - getStateTransfer: noop, -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/expressions.ts b/x-pack/plugins/canvas/public/services/stubs/expressions.ts deleted file mode 100644 index 177eb1e50d75f..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/expressions.ts +++ /dev/null @@ -1,41 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { AnyExpressionRenderDefinition } from '@kbn/expressions-plugin/common'; -import { plugin } from '@kbn/expressions-plugin/public'; -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { functions as functionDefinitions } from '../../../canvas_plugin_src/functions/common'; -import { renderFunctions } from '../../../canvas_plugin_src/renderers/core'; -import { - CanvasExpressionsService, - CanvasExpressionsServiceRequiredServices, - ExpressionsService, -} from '../kibana/expressions'; - -type CanvasExpressionsServiceFactory = PluginServiceFactory< - CanvasExpressionsService, - {}, - CanvasExpressionsServiceRequiredServices ->; - -export const expressionsServiceFactory: CanvasExpressionsServiceFactory = ( - params, - requiredServices -) => { - const placeholder = {} as any; - const expressionsPlugin = plugin(placeholder); - const setup = expressionsPlugin.setup(placeholder); - const fork = setup.fork('canvas'); - const expressionsService = fork.setup(); - - functionDefinitions.forEach((fn) => expressionsService.registerFunction(fn)); - renderFunctions.forEach((fn) => { - setup.registerRenderer(fn as unknown as AnyExpressionRenderDefinition); - }); - - return new ExpressionsService(fork.start(), requiredServices); -}; diff --git a/x-pack/plugins/canvas/public/services/stubs/filters.ts b/x-pack/plugins/canvas/public/services/stubs/filters.ts deleted file mode 100644 index 19d237bb9c390..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/filters.ts +++ /dev/null @@ -1,23 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasFiltersService } from '../filters'; - -export type CanvasFiltersServiceFactory = PluginServiceFactory; - -const noop = (..._args: any[]): any => {}; - -export const filtersServiceFactory: CanvasFiltersServiceFactory = () => ({ - getFilters: () => [ - 'exactly value="machine-learning" column="project1" filterGroup="Group 1"', - 'exactly value="kibana" column="project2" filterGroup="Group 1"', - 'time column="@timestamp1" from="2021-11-02 17:13:18" to="2021-11-09 17:13:18" filterGroup="Some group"', - ], - updateFilter: noop, - getFiltersContext: () => ({ variables: {} }), -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/index.ts b/x-pack/plugins/canvas/public/services/stubs/index.ts deleted file mode 100644 index c129441b07825..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/index.ts +++ /dev/null @@ -1,61 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from '../legacy/stubs'; - -import { - PluginServiceProviders, - PluginServiceProvider, - PluginServiceRegistry, -} from '@kbn/presentation-util-plugin/public'; - -import { CanvasPluginServices } from '..'; -import { customElementServiceFactory } from './custom_element'; -import { dataViewsServiceFactory } from './data_views'; -import { embeddablesServiceFactory } from './embeddables'; -import { expressionsServiceFactory } from './expressions'; -import { labsServiceFactory } from './labs'; -import { navLinkServiceFactory } from './nav_link'; -import { notifyServiceFactory } from './notify'; -import { platformServiceFactory } from './platform'; -import { reportingServiceFactory } from './reporting'; -import { visualizationsServiceFactory } from './visualizations'; -import { workpadServiceFactory } from './workpad'; -import { filtersServiceFactory } from './filters'; -import { uiActionsServiceFactory } from './ui_actions'; - -export { customElementServiceFactory } from './custom_element'; -export { dataViewsServiceFactory } from './data_views'; -export { expressionsServiceFactory } from './expressions'; -export { filtersServiceFactory } from './filters'; -export { labsServiceFactory } from './labs'; -export { navLinkServiceFactory } from './nav_link'; -export { notifyServiceFactory } from './notify'; -export { platformServiceFactory } from './platform'; -export { reportingServiceFactory } from './reporting'; -export { visualizationsServiceFactory } from './visualizations'; -export { workpadServiceFactory } from './workpad'; - -export const pluginServiceProviders: PluginServiceProviders = { - customElement: new PluginServiceProvider(customElementServiceFactory), - dataViews: new PluginServiceProvider(dataViewsServiceFactory), - embeddables: new PluginServiceProvider(embeddablesServiceFactory), - expressions: new PluginServiceProvider(expressionsServiceFactory, ['filters', 'notify']), - filters: new PluginServiceProvider(filtersServiceFactory), - labs: new PluginServiceProvider(labsServiceFactory), - navLink: new PluginServiceProvider(navLinkServiceFactory), - notify: new PluginServiceProvider(notifyServiceFactory), - platform: new PluginServiceProvider(platformServiceFactory), - reporting: new PluginServiceProvider(reportingServiceFactory), - visualizations: new PluginServiceProvider(visualizationsServiceFactory), - workpad: new PluginServiceProvider(workpadServiceFactory), - uiActions: new PluginServiceProvider(uiActionsServiceFactory), -}; - -export const pluginServiceRegistry = new PluginServiceRegistry( - pluginServiceProviders -); diff --git a/x-pack/plugins/canvas/public/services/stubs/labs.ts b/x-pack/plugins/canvas/public/services/stubs/labs.ts deleted file mode 100644 index d563126a15da3..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/labs.ts +++ /dev/null @@ -1,25 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { projectIDs } from '@kbn/presentation-util-plugin/common'; -import { CanvasLabsService } from '../labs'; - -type CanvasLabsServiceFactory = PluginServiceFactory; - -const noop = (..._args: any[]): any => {}; - -export const labsServiceFactory: CanvasLabsServiceFactory = () => ({ - getProject: noop, - getProjects: noop, - getProjectIDs: () => projectIDs, - isProjectEnabled: () => false, - isLabsEnabled: () => true, - projectIDs, - reset: noop, - setProjectStatus: noop, -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/nav_link.ts b/x-pack/plugins/canvas/public/services/stubs/nav_link.ts deleted file mode 100644 index becbdebcd6328..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/nav_link.ts +++ /dev/null @@ -1,17 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasNavLinkService } from '../nav_link'; - -type CanvasNavLinkServiceFactory = PluginServiceFactory; - -const noop = (..._args: any[]): any => {}; - -export const navLinkServiceFactory: CanvasNavLinkServiceFactory = () => ({ - updatePath: noop, -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/notify.ts b/x-pack/plugins/canvas/public/services/stubs/notify.ts deleted file mode 100644 index 2406afe3ca8a2..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/notify.ts +++ /dev/null @@ -1,21 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -import { CanvasNotifyService } from '../notify'; - -type CanvasNotifyServiceFactory = PluginServiceFactory; - -const noop = (..._args: any[]): any => {}; - -export const notifyServiceFactory: CanvasNotifyServiceFactory = () => ({ - error: noop, - info: noop, - success: noop, - warning: noop, -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/platform.ts b/x-pack/plugins/canvas/public/services/stubs/platform.ts deleted file mode 100644 index 0726810075251..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/platform.ts +++ /dev/null @@ -1,39 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -import { CanvasPlatformService } from '../platform'; - -type CanvasPlatformServiceFactory = PluginServiceFactory; - -const noop = (..._args: any[]): any => {}; - -const uiSettings: Record = { - dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS', -}; - -const getUISetting = (setting: string) => uiSettings[setting]; - -export const platformServiceFactory: CanvasPlatformServiceFactory = () => ({ - getBasePath: () => '/base/path', - getBasePathInterface: noop, - getDocLinkVersion: () => 'docLinkVersion', - getElasticWebsiteUrl: () => 'https://elastic.co', - getKibanaVersion: () => 'kibanaVersion', - getHasWriteAccess: () => true, - getUISetting, - hasHeaderBanner$: noop, - setBreadcrumbs: noop, - setRecentlyAccessed: noop, - getUISettings: noop, - setFullscreen: noop, - redirectLegacyUrl: noop, - getLegacyUrlConflict: undefined, - getHttp: noop, - getContentManagement: noop, -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/reporting.tsx b/x-pack/plugins/canvas/public/services/stubs/reporting.tsx deleted file mode 100644 index 71c376efbaba9..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/reporting.tsx +++ /dev/null @@ -1,17 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -import { CanvasReportingService } from '../reporting'; - -type CanvasReportingServiceFactory = PluginServiceFactory; - -export const reportingServiceFactory: CanvasReportingServiceFactory = () => ({ - getReportingPanelPDFComponent: () => () =>
Reporting Panel PDF
, -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/ui_actions.ts b/x-pack/plugins/canvas/public/services/stubs/ui_actions.ts deleted file mode 100644 index 84039e0888be8..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/ui_actions.ts +++ /dev/null @@ -1,17 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; -import { CanvasUiActionsService } from '../ui_actions'; - -type UiActionsServiceFactory = PluginServiceFactory; - -export const uiActionsServiceFactory: UiActionsServiceFactory = () => { - const pluginMock = uiActionsPluginMock.createStartContract(); - return { getTriggerCompatibleActions: pluginMock.getTriggerCompatibleActions }; -}; diff --git a/x-pack/plugins/canvas/public/services/stubs/visualizations.ts b/x-pack/plugins/canvas/public/services/stubs/visualizations.ts deleted file mode 100644 index 812287bf078fb..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/visualizations.ts +++ /dev/null @@ -1,19 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { CanvasVisualizationsService } from '../visualizations'; - -type VisualizationsServiceFactory = PluginServiceFactory; - -const noop = (..._args: any[]): any => {}; - -export const visualizationsServiceFactory: VisualizationsServiceFactory = () => ({ - showNewVisModal: noop, - getByGroup: noop, - getAliases: noop, -}); diff --git a/x-pack/plugins/canvas/public/services/stubs/workpad.ts b/x-pack/plugins/canvas/public/services/stubs/workpad.ts deleted file mode 100644 index 51be4e150ebe5..0000000000000 --- a/x-pack/plugins/canvas/public/services/stubs/workpad.ts +++ /dev/null @@ -1,115 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import moment from 'moment'; -import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -// @ts-expect-error -import { getDefaultWorkpad } from '../../state/defaults'; -import { CanvasWorkpadService } from '../workpad'; -import { CanvasTemplate, CanvasWorkpad } from '../../../types'; - -type CanvasWorkpadServiceFactory = PluginServiceFactory; - -export const TIMEOUT = 500; -export const promiseTimeout = (time: number) => () => - new Promise((resolve) => setTimeout(resolve, time)); - -const DAY = 86400000; -const JAN_1_2000 = 946684800000; - -const getWorkpads = (count = 3) => { - const workpads = []; - for (let i = 0; i < count; i++) { - workpads[i] = { - ...getDefaultWorkpad(), - name: `Workpad ${i}`, - id: `workpad-${i}`, - '@created': moment(JAN_1_2000 + DAY * i).toDate(), - '@timestamp': moment(JAN_1_2000 + DAY * (i + 1)).toDate(), - }; - } - return workpads; -}; - -export const getSomeWorkpads = (count = 3) => getWorkpads(count); - -export const findSomeWorkpads = - (count = 3, timeout = TIMEOUT) => - (_term: string) => { - return Promise.resolve() - .then(promiseTimeout(timeout)) - .then(() => ({ - total: count, - workpads: getSomeWorkpads(count), - })); - }; - -const templates: CanvasTemplate[] = [ - { - id: 'test1-id', - name: 'test1', - help: 'This is a test template', - tags: ['tag1', 'tag2'], - template_key: 'test1-key', - }, - { - id: 'test2-id', - name: 'test2', - help: 'This is a second test template', - tags: ['tag2', 'tag3'], - template_key: 'test2-key', - }, -]; - -export const findNoWorkpads = - (timeout = TIMEOUT) => - (_term: string) => { - return Promise.resolve() - .then(promiseTimeout(timeout)) - .then(() => ({ - total: 0, - workpads: [], - })); - }; - -export const findSomeTemplates = - (timeout = TIMEOUT) => - () => { - return Promise.resolve() - .then(promiseTimeout(timeout)) - .then(() => getSomeTemplates()); - }; - -export const findNoTemplates = - (timeout = TIMEOUT) => - () => { - return Promise.resolve() - .then(promiseTimeout(timeout)) - .then(() => getNoTemplates()); - }; - -export const importWorkpad = (workpad: CanvasWorkpad) => Promise.resolve(workpad); -export const getNoTemplates = () => ({ templates: [] }); -export const getSomeTemplates = () => ({ templates }); - -export const workpadServiceFactory: CanvasWorkpadServiceFactory = () => ({ - get: (id: string) => Promise.resolve({ ...getDefaultWorkpad(), id }), - resolve: (id: string) => - Promise.resolve({ outcome: 'exactMatch', workpad: { ...getDefaultWorkpad(), id } }), - findTemplates: findNoTemplates(), - create: (workpad) => Promise.resolve(workpad), - import: (workpad) => importWorkpad(workpad), - createFromTemplate: (_templateId: string) => Promise.resolve(getDefaultWorkpad()), - find: findNoWorkpads(), - remove: (_id: string) => Promise.resolve(), - update: (id, workpad) => Promise.resolve(), - updateWorkpad: (id, workpad) => Promise.resolve(), - updateAssets: (id, assets) => Promise.resolve(), - getRuntimeZip: (workpad) => - Promise.resolve(new Blob([JSON.stringify(workpad)], { type: 'application/json' })), -}); diff --git a/x-pack/plugins/canvas/public/services/ui_actions.ts b/x-pack/plugins/canvas/public/services/ui_actions.ts deleted file mode 100644 index 62f99facce023..0000000000000 --- a/x-pack/plugins/canvas/public/services/ui_actions.ts +++ /dev/null @@ -1,12 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; - -export interface CanvasUiActionsService { - getTriggerCompatibleActions: UiActionsStart['getTriggerCompatibleActions']; -} diff --git a/x-pack/plugins/canvas/public/services/visualizations.ts b/x-pack/plugins/canvas/public/services/visualizations.ts deleted file mode 100644 index dc816f764e5ec..0000000000000 --- a/x-pack/plugins/canvas/public/services/visualizations.ts +++ /dev/null @@ -1,14 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { VisualizationsStart } from '@kbn/visualizations-plugin/public'; - -export interface CanvasVisualizationsService { - showNewVisModal: VisualizationsStart['showNewVisModal']; - getByGroup: VisualizationsStart['getByGroup']; - getAliases: VisualizationsStart['getAliases']; -} diff --git a/x-pack/plugins/canvas/public/services/workpad.ts b/x-pack/plugins/canvas/public/services/workpad.ts deleted file mode 100644 index 72996f54c158d..0000000000000 --- a/x-pack/plugins/canvas/public/services/workpad.ts +++ /dev/null @@ -1,43 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ResolvedSimpleSavedObject } from '@kbn/core/public'; -import { CanvasWorkpad, CanvasTemplate } from '../../types'; -import type { CanvasRenderedWorkpad } from '../../shareable_runtime/types'; - -export type FoundWorkpads = Array>; -export type FoundWorkpad = FoundWorkpads[number]; -export interface WorkpadFindResponse { - total: number; - workpads: FoundWorkpads; -} - -export interface TemplateFindResponse { - templates: CanvasTemplate[]; -} - -export interface ResolveWorkpadResponse { - workpad: CanvasWorkpad; - outcome: ResolvedSimpleSavedObject['outcome']; - aliasId?: ResolvedSimpleSavedObject['alias_target_id']; - aliasPurpose?: ResolvedSimpleSavedObject['alias_purpose']; -} - -export interface CanvasWorkpadService { - get: (id: string) => Promise; - resolve: (id: string) => Promise; - create: (workpad: CanvasWorkpad) => Promise; - import: (workpad: CanvasWorkpad) => Promise; - createFromTemplate: (templateId: string) => Promise; - find: (term: string) => Promise; - remove: (id: string) => Promise; - findTemplates: () => Promise; - update: (id: string, workpad: CanvasWorkpad) => Promise; - updateWorkpad: (id: string, workpad: CanvasWorkpad) => Promise; - updateAssets: (id: string, assets: CanvasWorkpad['assets']) => Promise; - getRuntimeZip: (workpad: CanvasRenderedWorkpad) => Promise; -} From 9f1090334732f5cc3bdb1eb5e6cdef0b963a1acb Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 26 Sep 2024 15:06:21 -0600 Subject: [PATCH 02/41] Remove platform service --- .../embeddable_flyout/flyout.component.tsx | 32 ++++++------- .../home/my_workpads/workpad_table.tsx | 11 ++--- .../public/components/home_app/home_app.tsx | 7 ++- .../public/components/workpad/workpad.tsx | 6 +-- .../flyout/hooks/use_download_runtime.ts | 12 ++--- .../workpad_header/share_menu/share_menu.tsx | 3 +- .../plugins/canvas/public/lib/fullscreen.js | 7 ++- .../canvas/public/lib/template_service.ts | 5 +- .../use_fullscreen_presentation_helper.ts | 12 +++-- .../routes/workpad/hooks/use_workpad.ts | 7 +-- .../workpad/workpad_presentation_helper.tsx | 9 ++-- .../canvas/public/services/kibana/platform.ts | 46 ------------------- .../canvas/public/services/kibana_services.ts | 7 ++- .../canvas/public/services/platform.ts | 37 --------------- .../canvas/public/state/initial_state.js | 7 +-- .../canvas/public/state/reducers/workpad.js | 26 +++++------ 16 files changed, 72 insertions(+), 162 deletions(-) delete mode 100644 x-pack/plugins/canvas/public/services/kibana/platform.ts delete mode 100644 x-pack/plugins/canvas/public/services/platform.ts diff --git a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx index 9adde7ab57718..39740b62b849f 100644 --- a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx +++ b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx @@ -5,14 +5,15 @@ * 2.0. */ -import React, { FC, useCallback, useMemo } from 'react'; -import { EuiFlyout, EuiFlyoutHeader, EuiFlyoutBody, EuiTitle } from '@elastic/eui'; +import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import React, { FC, useCallback, useMemo } from 'react'; -import { SavedObjectFinder, SavedObjectMetaData } from '@kbn/saved-objects-finder-plugin/public'; -import { FinderAttributes } from '@kbn/saved-objects-finder-plugin/common'; +import { coreServices } from '@kbn/controls-plugin/public/services/kibana_services'; import { EmbeddableFactory, ReactEmbeddableSavedObject } from '@kbn/embeddable-plugin/public'; -import { useEmbeddablesService, usePlatformService } from '../../services'; +import { FinderAttributes } from '@kbn/saved-objects-finder-plugin/common'; +import { SavedObjectFinder, SavedObjectMetaData } from '@kbn/saved-objects-finder-plugin/public'; +import { contentManagementService, embeddableService } from '../../services/kibana_services'; const strings = { getNoItemsText: () => @@ -45,13 +46,8 @@ export const AddEmbeddableFlyout: FC = ({ onClose, isByValueEnabled, }) => { - const embeddablesService = useEmbeddablesService(); - const platformService = usePlatformService(); - const { getEmbeddableFactories, getReactEmbeddableSavedObjects } = embeddablesService; - const { getContentManagement, getUISettings } = platformService; - const legacyFactoriesBySavedObjectType: LegacyFactoryMap = useMemo(() => { - return [...getEmbeddableFactories()] + return [...embeddableService.getEmbeddableFactories()] .filter( (embeddableFactory) => Boolean(embeddableFactory.savedObjectMetaData?.type) && !embeddableFactory.isContainerType @@ -60,10 +56,10 @@ export const AddEmbeddableFlyout: FC = ({ acc[factory.savedObjectMetaData!.type] = factory; return acc; }, {} as LegacyFactoryMap); - }, [getEmbeddableFactories]); + }, []); const factoriesBySavedObjectType: FactoryMap = useMemo(() => { - return [...getReactEmbeddableSavedObjects()] + return [...embeddableService.getReactEmbeddableSavedObjects()] .filter(([type, embeddableFactory]) => { return Boolean(embeddableFactory.savedObjectMetaData?.type); }) @@ -74,7 +70,7 @@ export const AddEmbeddableFlyout: FC = ({ }; return acc; }, {} as FactoryMap); - }, [getReactEmbeddableSavedObjects]); + }, []); const metaData = useMemo( () => @@ -111,7 +107,7 @@ export const AddEmbeddableFlyout: FC = ({ onSelect(id, type, isByValueEnabled); return; } - const embeddableFactories = getEmbeddableFactories(); + const embeddableFactories = embeddableService.getEmbeddableFactories(); // Find the embeddable type from the saved object type const found = Array.from(embeddableFactories).find((embeddableFactory) => { return Boolean( @@ -124,7 +120,7 @@ export const AddEmbeddableFlyout: FC = ({ onSelect(id, foundEmbeddableType, isByValueEnabled); }, - [isByValueEnabled, getEmbeddableFactories, onSelect, factoriesBySavedObjectType] + [isByValueEnabled, onSelect, factoriesBySavedObjectType] ); return ( @@ -141,8 +137,8 @@ export const AddEmbeddableFlyout: FC = ({ showFilter={true} noItemsMessage={strings.getNoItemsText()} services={{ - contentClient: getContentManagement().client, - uiSettings: getUISettings(), + contentClient: contentManagementService.client, + uiSettings: coreServices.uiSettings, }} /> diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.tsx index 6d88691f2eabe..7bbb3a57ab9ce 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.tsx @@ -8,17 +8,16 @@ import React, { useContext } from 'react'; import { useSelector } from 'react-redux'; -import { canUserWrite as canUserWriteSelector } from '../../../state/selectors/app'; import type { State } from '../../../../types'; -import { usePlatformService } from '../../../services'; -import { useCloneWorkpad } from '../hooks'; +import { canUserWrite as canUserWriteSelector } from '../../../state/selectors/app'; import { useDownloadWorkpad } from '../../hooks'; +import { useCloneWorkpad } from '../hooks'; -import { WorkpadTable as Component } from './workpad_table.component'; +import { coreServices } from '../../../services/kibana_services'; import { WorkpadsContext } from './my_workpads'; +import { WorkpadTable as Component } from './workpad_table.component'; export const WorkpadTable = () => { - const platformService = usePlatformService(); const onCloneWorkpad = useCloneWorkpad(); const onExportWorkpad = useDownloadWorkpad(); const context = useContext(WorkpadsContext); @@ -33,7 +32,7 @@ export const WorkpadTable = () => { const { workpads } = context; - const dateFormat = platformService.getUISetting('dateFormat'); + const dateFormat = coreServices.uiSettings.get('dateFormat'); return ; }; diff --git a/x-pack/plugins/canvas/public/components/home_app/home_app.tsx b/x-pack/plugins/canvas/public/components/home_app/home_app.tsx index 086a737d525e9..54d9659f5a1d8 100644 --- a/x-pack/plugins/canvas/public/components/home_app/home_app.tsx +++ b/x-pack/plugins/canvas/public/components/home_app/home_app.tsx @@ -11,17 +11,16 @@ import { useDispatch } from 'react-redux'; import { getBaseBreadcrumb } from '../../lib/breadcrumbs'; import { resetWorkpad } from '../../state/actions/workpad'; import { HomeApp as Component } from './home_app.component'; -import { usePlatformService } from '../../services'; +import { coreServices } from '../../services/kibana_services'; export const HomeApp = () => { - const { setBreadcrumbs } = usePlatformService(); const dispatch = useDispatch(); const onLoad = () => dispatch(resetWorkpad()); const history = useHistory(); useEffect(() => { - setBreadcrumbs([getBaseBreadcrumb(history)]); - }, [setBreadcrumbs, history]); + coreServices.chrome.setBreadcrumbs([getBaseBreadcrumb(history)]); + }, [history]); return ; }; diff --git a/x-pack/plugins/canvas/public/components/workpad/workpad.tsx b/x-pack/plugins/canvas/public/components/workpad/workpad.tsx index 1e604a6deb850..6052e6951a8e9 100644 --- a/x-pack/plugins/canvas/public/components/workpad/workpad.tsx +++ b/x-pack/plugins/canvas/public/components/workpad/workpad.tsx @@ -24,10 +24,10 @@ import { useZoomHandlers } from '../../lib/app_handler_creators'; import { trackCanvasUiMetric, METRIC_TYPE } from '../../lib/ui_metric'; import { LAUNCHED_FULLSCREEN, LAUNCHED_FULLSCREEN_AUTOPLAY } from '../../../common/lib/constants'; import { WorkpadRoutingContext } from '../../routes/workpad'; -import { usePlatformService } from '../../services'; import { Workpad as WorkpadComponent, Props } from './workpad.component'; import { State } from '../../../types'; import { useIncomingEmbeddable } from '../hooks'; +import { coreServices } from '../../services/kibana_services'; type ContainerProps = Pick; @@ -40,9 +40,7 @@ export const Workpad: FC = (props) => { const { isFullscreen, setFullscreen, undo, redo, autoplayInterval, nextPage, previousPage } = useContext(WorkpadRoutingContext); - const platformService = usePlatformService(); - - const hasHeaderBanner = useObservable(platformService.hasHeaderBanner$()); + const hasHeaderBanner = useObservable(coreServices.chrome.hasHeaderBanner$()); const propsFromState = useSelector((state: State) => { const { width, height, id: workpadId, css: workpadCss } = getWorkpad(state); diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts index cd1635d65a573..3ce62f34ebbab 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts @@ -5,14 +5,15 @@ * 2.0. */ -import { useCallback } from 'react'; -import fileSaver from 'file-saver'; import { i18n } from '@kbn/i18n'; +import fileSaver from 'file-saver'; +import { useCallback } from 'react'; import { API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD } from '../../../../../../common/lib/constants'; import { ZIP } from '../../../../../../i18n/constants'; -import { usePlatformService, useNotifyService, useWorkpadService } from '../../../../../services'; import type { CanvasRenderedWorkpad } from '../../../../../../shareable_runtime/types'; +import { useNotifyService, usePlatformService, useWorkpadService } from '../../../../../services'; +import { coreServices } from '../../../../../services/kibana_services'; const strings = { getDownloadRuntimeFailureErrorMessage: () => @@ -35,18 +36,17 @@ const strings = { }; export const useDownloadRuntime = () => { - const platformService = usePlatformService(); const notifyService = useNotifyService(); const downloadRuntime = useCallback(() => { try { - const path = `${platformService.getBasePath()}${API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD}`; + const path = `${coreServices.http.basePath.get}${API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD}`; window.open(path); return; } catch (err) { notifyService.error(err, { title: strings.getDownloadRuntimeFailureErrorMessage() }); } - }, [platformService, notifyService]); + }, [notifyService]); return downloadRuntime; }; diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx index c66336a9153c0..99087cb595f0b 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx @@ -14,6 +14,7 @@ import { getPages, getWorkpad } from '../../../state/selectors/workpad'; import { useDownloadWorkpad } from '../../hooks'; import { ShareMenu as ShareMenuComponent } from './share_menu.component'; import { getPdfJobParams } from './utils'; +import { kibanaVersion } from '../../../services/kibana_services'; const strings = { getUnknownExportErrorMessage: (type: string) => @@ -46,7 +47,7 @@ export const ShareMenu = () => { ReportingPanelPDFComponent !== null ? ({ onClose }: { onClose: () => void }) => ( getPdfJobParams(sharingData, platformService.getKibanaVersion())} + getJobParams={() => getPdfJobParams(sharingData, kibanaVersion)} layoutOption="canvas" onClose={onClose} objectId={workpad.id} diff --git a/x-pack/plugins/canvas/public/lib/fullscreen.js b/x-pack/plugins/canvas/public/lib/fullscreen.js index fd4e0b65785b9..50a9578b07b78 100644 --- a/x-pack/plugins/canvas/public/lib/fullscreen.js +++ b/x-pack/plugins/canvas/public/lib/fullscreen.js @@ -5,22 +5,21 @@ * 2.0. */ -import { pluginServices } from '../services'; +import { coreServices } from '../services/kibana_services'; export const fullscreenClass = 'canvas-isFullscreen'; export function setFullscreen(fullscreen, doc = document) { - const platformService = pluginServices.getServices().platform; const enabled = Boolean(fullscreen); const body = doc.querySelector('body'); const bodyClassList = body.classList; const isFullscreen = bodyClassList.contains(fullscreenClass); if (enabled && !isFullscreen) { - platformService.setFullscreen(false); + coreServices.chrome.setIsVisible(false); bodyClassList.add(fullscreenClass); } else if (!enabled && isFullscreen) { bodyClassList.remove(fullscreenClass); - platformService.setFullscreen(true); + coreServices.chrome.setIsVisible(true); } } diff --git a/x-pack/plugins/canvas/public/lib/template_service.ts b/x-pack/plugins/canvas/public/lib/template_service.ts index d5ec467f18740..cdcf0976f3ce8 100644 --- a/x-pack/plugins/canvas/public/lib/template_service.ts +++ b/x-pack/plugins/canvas/public/lib/template_service.ts @@ -9,12 +9,11 @@ import { API_ROUTE_TEMPLATES } from '../../common/lib/constants'; import { fetch } from '../../common/lib/fetch'; -import { pluginServices } from '../services'; import { CanvasTemplate } from '../../types'; +import { coreServices } from '../services/kibana_services'; const getApiPath = function () { - const platformService = pluginServices.getServices().platform; - const basePath = platformService.getBasePath(); + const basePath = coreServices.http.basePath.get; return `${basePath}${API_ROUTE_TEMPLATES}`; }; diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts index ca66fa227e4eb..3e6837ca77b43 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts @@ -4,16 +4,20 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useContext, useEffect } from 'react'; +import { useCallback, useContext, useEffect } from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { usePlatformService } from '../../../services'; import { WorkpadRoutingContext } from '..'; +import { coreServices } from '../../../services/kibana_services'; const fullscreenClass = 'canvas-isFullscreen'; export const useFullscreenPresentationHelper = () => { const { isFullscreen } = useContext(WorkpadRoutingContext); - const { setFullscreen } = usePlatformService(); + + const setFullscreen = useCallback( + (fullscreen: boolean) => coreServices.chrome.setIsVisible(fullscreen), + [] + ); useEffect(() => { const body = document.querySelector('body'); @@ -27,7 +31,7 @@ export const useFullscreenPresentationHelper = () => { bodyClassList.remove(fullscreenClass); setFullscreen(true); } - }, [isFullscreen, setFullscreen]); + }, [setFullscreen, isFullscreen]); // Remove fullscreen when component unmounts useEffectOnce(() => () => { diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts index 61908d96828fd..122181cc22847 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts @@ -16,7 +16,8 @@ import { setAssets } from '../../../state/actions/assets'; // @ts-expect-error import { setZoomScale } from '../../../state/actions/transient'; import { CanvasWorkpad } from '../../../../types'; -import type { ResolveWorkpadResponse } from '../../../services/workpad'; +import { ResolveWorkpadResponse } from '../../../services/canvas_workpad_service'; +import { spacesService } from '../../../services/kibana_services'; const getWorkpadLabel = () => i18n.translate('xpack.canvas.workpadResolve.redirectLabel', { @@ -75,9 +76,9 @@ export const useWorkpad = ( if (!resolveInfo) return; const { aliasId, outcome, aliasPurpose } = resolveInfo; - if (outcome === 'aliasMatch' && platformService.redirectLegacyUrl && aliasId) { + if (outcome === 'aliasMatch' && spacesService && aliasId) { const redirectPath = getRedirectPath(aliasId); - await platformService.redirectLegacyUrl({ + await spacesService?.ui.redirectLegacyUrl({ path: `#${redirectPath}`, aliasPurpose, objectNoun: getWorkpadLabel(), diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx index 0dfb4dd8fbf78..bde100182788e 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_presentation_helper.tsx @@ -14,7 +14,7 @@ import { getWorkpad } from '../../state/selectors/workpad'; import { useFullscreenPresentationHelper } from './hooks/use_fullscreen_presentation_helper'; import { useAutoplayHelper } from './hooks/use_autoplay_helper'; import { useRefreshHelper } from './hooks/use_refresh_helper'; -import { usePlatformService } from '../../services'; +import { coreServices, spacesService } from '../../services/kibana_services'; const getWorkpadLabel = () => i18n.translate('xpack.canvas.workpadConflict.redirectLabel', { @@ -22,7 +22,6 @@ const getWorkpadLabel = () => }); export const WorkpadPresentationHelper: FC> = ({ children }) => { - const platformService = usePlatformService(); const workpad = useSelector(getWorkpad); useFullscreenPresentationHelper(); useAutoplayHelper(); @@ -30,18 +29,18 @@ export const WorkpadPresentationHelper: FC> = ({ chil const history = useHistory(); useEffect(() => { - platformService.setBreadcrumbs([ + coreServices.chrome.setBreadcrumbs([ getBaseBreadcrumb(history), getWorkpadBreadcrumb({ name: workpad.name }), ]); - }, [workpad.name, platformService, history]); + }, [workpad.name, history]); useEffect(() => { setDocTitle(workpad.name || getUntitledWorkpadLabel()); }, [workpad.name, workpad.id]); const conflictElement = workpad.aliasId - ? platformService.getLegacyUrlConflict?.({ + ? spacesService?.ui.components.getLegacyUrlConflict({ objectNoun: getWorkpadLabel(), currentObjectId: workpad.id, otherObjectId: workpad.aliasId, diff --git a/x-pack/plugins/canvas/public/services/kibana/platform.ts b/x-pack/plugins/canvas/public/services/kibana/platform.ts deleted file mode 100644 index 1518280ab0688..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/platform.ts +++ /dev/null @@ -1,46 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; - -import { CanvasStartDeps } from '../../plugin'; -import { CanvasPlatformService } from '../platform'; - -export type CanvaPlatformServiceFactory = KibanaPluginServiceFactory< - CanvasPlatformService, - CanvasStartDeps ->; - -export const platformServiceFactory: CanvaPlatformServiceFactory = ({ - coreStart, - initContext, - startPlugins, -}) => { - if (!initContext) { - throw new Error('Canvas platform service requires init context'); - } - - return { - getBasePath: coreStart.http.basePath.get, - getBasePathInterface: () => coreStart.http.basePath, - getElasticWebsiteUrl: () => coreStart.docLinks.ELASTIC_WEBSITE_URL, - getDocLinkVersion: () => coreStart.docLinks.DOC_LINK_VERSION, - getKibanaVersion: () => initContext.env.packageInfo.version, - // TODO: is there a better type for this? The capabilities type allows for a Record, - // though we don't do this. So this cast may be the best option. - getHasWriteAccess: () => coreStart.application.capabilities.canvas.save as boolean, - getUISetting: coreStart.uiSettings.get.bind(coreStart.uiSettings), - hasHeaderBanner$: coreStart.chrome.hasHeaderBanner$, - setBreadcrumbs: coreStart.chrome.setBreadcrumbs, - setRecentlyAccessed: coreStart.chrome.recentlyAccessed.add, - setFullscreen: coreStart.chrome.setIsVisible, - redirectLegacyUrl: startPlugins.spaces?.ui.redirectLegacyUrl, - getLegacyUrlConflict: startPlugins.spaces?.ui.components.getLegacyUrlConflict, - getUISettings: () => coreStart.uiSettings, - getHttp: () => coreStart.http, - getContentManagement: () => startPlugins.contentManagement, - }; -}; diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index cf66ca88846cf..9ca0bfe9206c1 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -8,7 +8,7 @@ import { BehaviorSubject } from 'rxjs'; import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; -import type { AppUpdater, CoreStart } from '@kbn/core/public'; +import type { AppUpdater, CoreStart, PluginInitializerContext } from '@kbn/core/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; // import type { DataView, DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { EmbeddableStart } from '@kbn/embeddable-plugin/public/plugin'; @@ -26,6 +26,8 @@ export interface CanvasNavLinkService { updatePath: (path: string) => void; } +export let kibanaVersion: string; + export let coreServices: CoreStart; export let contentManagementService: ContentManagementPublicStart; export let dataService: DataPublicPluginStart; @@ -44,8 +46,11 @@ const servicesReady$ = new BehaviorSubject(false); export const setKibanaServices = ( kibanaCore: CoreStart, deps: CanvasStartDeps, + initContext: PluginInitializerContext, appUpdater?: BehaviorSubject ) => { + kibanaVersion = initContext.env.packageInfo.version; + coreServices = kibanaCore; contentManagementService = deps.contentManagement; dataService = deps.data; diff --git a/x-pack/plugins/canvas/public/services/platform.ts b/x-pack/plugins/canvas/public/services/platform.ts deleted file mode 100644 index 555f8643fff9b..0000000000000 --- a/x-pack/plugins/canvas/public/services/platform.ts +++ /dev/null @@ -1,37 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Observable } from 'rxjs'; -import { - IUiSettingsClient, - ChromeBreadcrumb, - IBasePath, - ChromeStart, - HttpStart, -} from '@kbn/core/public'; - -import { SpacesPluginStart } from '@kbn/spaces-plugin/public'; -import { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; - -export interface CanvasPlatformService { - getBasePath: () => string; - getBasePathInterface: () => IBasePath; - getDocLinkVersion: () => string; - getElasticWebsiteUrl: () => string; - getKibanaVersion: () => string; - getHasWriteAccess: () => boolean; - getUISetting: (key: string, defaultValue?: any) => any; - hasHeaderBanner$: () => Observable; - setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void; - setRecentlyAccessed: (link: string, label: string, id: string) => void; - setFullscreen: ChromeStart['setIsVisible']; - redirectLegacyUrl?: SpacesPluginStart['ui']['redirectLegacyUrl']; - getLegacyUrlConflict?: SpacesPluginStart['ui']['components']['getLegacyUrlConflict']; - getUISettings: () => IUiSettingsClient; - getHttp: () => HttpStart; - getContentManagement: () => ContentManagementPublicStart; -} diff --git a/x-pack/plugins/canvas/public/state/initial_state.js b/x-pack/plugins/canvas/public/state/initial_state.js index 88330c92d867b..fd509c952ef18 100644 --- a/x-pack/plugins/canvas/public/state/initial_state.js +++ b/x-pack/plugins/canvas/public/state/initial_state.js @@ -6,18 +6,15 @@ */ import { get } from 'lodash'; -import { pluginServices } from '../services'; +import { coreServices } from '../services/kibana_services'; import { getDefaultWorkpad, getDefaultSidebar, getDefaultFlyouts } from './defaults'; export const getInitialState = (path) => { - const platformService = pluginServices.getServices().platform; - const { getHasWriteAccess } = platformService; - const state = { app: {}, // Kibana stuff in here assets: {}, // assets end up here transient: { - canUserWrite: getHasWriteAccess(), + canUserWrite: coreServices.application.capabilities.canvas.save, zoomScale: 1, elementStats: { total: 0, diff --git a/x-pack/plugins/canvas/public/state/reducers/workpad.js b/x-pack/plugins/canvas/public/state/reducers/workpad.js index ebde0106f9c01..61ff2dc8978be 100644 --- a/x-pack/plugins/canvas/public/state/reducers/workpad.js +++ b/x-pack/plugins/canvas/public/state/reducers/workpad.js @@ -6,7 +6,7 @@ */ import { handleActions } from 'redux-actions'; -import { pluginServices } from '../../services'; +import { coreServices } from '../../services/kibana_services'; import { getDefaultWorkpad } from '../defaults'; import { setWorkpad, @@ -24,13 +24,11 @@ import { APP_ROUTE_WORKPAD } from '../../../common/lib/constants'; export const workpadReducer = handleActions( { [setWorkpad]: (workpadState, { payload }) => { - pluginServices - .getServices() - .platform.setRecentlyAccessed( - `${APP_ROUTE_WORKPAD}/${payload.id}`, - payload.name, - payload.id - ); + coreServices.chrome.recentlyAccessed.add( + `${APP_ROUTE_WORKPAD}/${payload.id}`, + payload.name, + payload.id + ); return payload; }, @@ -43,13 +41,11 @@ export const workpadReducer = handleActions( }, [setName]: (workpadState, { payload }) => { - pluginServices - .getServices() - .platform.setRecentlyAccessed( - `${APP_ROUTE_WORKPAD}/${workpadState.id}`, - payload, - workpadState.id - ); + coreServices.chrome.recentlyAccessed.add( + `${APP_ROUTE_WORKPAD}/${workpadState.id}`, + payload, + workpadState.id + ); return { ...workpadState, name: payload }; }, From 20270becb0d6b0721918434d9cb281bb736b0026 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 1 Oct 2024 10:13:53 -0600 Subject: [PATCH 03/41] Refactor notify + expressions services --- .../components/asset_manager/asset_manager.ts | 4 +- .../public/components/function_form/index.tsx | 7 +- .../home/hooks/use_delete_workpad.ts | 8 +-- x-pack/plugins/canvas/public/lib/assets.ts | 5 +- .../public/lib/element_handler_creators.ts | 3 +- .../workpad/hooks/use_workpad_persist.ts | 7 +- ...sions.ts => canvas_expressions_service.ts} | 51 ++++---------- .../notify.ts => canvas_notify_service.ts} | 20 +++--- .../canvas/public/services/expressions.ts | 8 --- .../plugins/canvas/public/services/index.ts | 10 ++- .../canvas/public/services/kibana/index.ts | 66 ------------------- .../canvas/public/services/kibana_services.ts | 11 ++-- .../canvas/public/state/actions/elements.js | 4 +- 13 files changed, 58 insertions(+), 146 deletions(-) rename x-pack/plugins/canvas/public/services/{kibana/expressions.ts => canvas_expressions_service.ts} (68%) rename x-pack/plugins/canvas/public/services/{kibana/notify.ts => canvas_notify_service.ts} (72%) delete mode 100644 x-pack/plugins/canvas/public/services/expressions.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/index.ts diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts index b46c9f07f7caa..7f9ee9ecffa83 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts @@ -31,7 +31,7 @@ export const AssetManager = connect( onAddAsset: (workpad: CanvasWorkpad, type: AssetType['type'], content: AssetType['value']) => { // make the ID here and pass it into the action const asset = createAsset(type, content); - const { notify, workpad: workpadService } = pluginServices.getServices(); + const { workpad: workpadService } = pluginServices.getServices(); return workpadService .updateAssets(workpad.id, { ...workpad.assets, [asset.id]: asset }) @@ -40,7 +40,7 @@ export const AssetManager = connect( // then return the id, so the caller knows the id that will be created return asset.id; }) - .catch((error) => notifyError(error, notify.error)); + .catch((error) => notifyError(error)); }, }), (stateProps, dispatchProps, ownProps) => { diff --git a/x-pack/plugins/canvas/public/components/function_form/index.tsx b/x-pack/plugins/canvas/public/components/function_form/index.tsx index 202bb4384d696..46da2403c22b7 100644 --- a/x-pack/plugins/canvas/public/components/function_form/index.tsx +++ b/x-pack/plugins/canvas/public/components/function_form/index.tsx @@ -34,7 +34,7 @@ import { findExistingAsset } from '../../lib/find_existing_asset'; import { FunctionForm as Component } from './function_form'; import { Args, ArgType, ArgTypeDef } from '../../expression_types/types'; import { State, ExpressionContext, CanvasElement, AssetType } from '../../../types'; -import { useNotifyService, useWorkpadService } from '../../services'; +import { useWorkpadService } from '../../services'; import { createAsset, notifyError } from '../../lib/assets'; interface FunctionFormProps { @@ -55,7 +55,6 @@ export const FunctionForm: React.FunctionComponent = (props) const { expressionIndex, ...restProps } = props; const { nextArgType, path, parentPath, argType } = restProps; const service = useWorkpadService(); - const notifyService = useNotifyService(); const dispatch = useDispatch(); const context = useSelector( @@ -120,9 +119,9 @@ export const FunctionForm: React.FunctionComponent = (props) // then return the id, so the caller knows the id that will be created return asset.id; }) - .catch((error) => notifyError(error, notifyService.error)); + .catch((error) => notifyError(error)); }, - [dispatch, notifyService, service, workpad.assets, workpad.id] + [dispatch, service, workpad.assets, workpad.id] ); const onAssetAdd = useCallback( diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts index 722ddae7411c9..3143b19fa8130 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts @@ -8,11 +8,11 @@ import { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useWorkpadService } from '../../../services'; +import { getCanvasNotifyService } from '../../../services/canvas_notify_service'; export const useDeleteWorkpads = () => { const workpadService = useWorkpadService(); - const notifyService = useNotifyService(); return useCallback( async (workpadIds: string[]) => { @@ -42,7 +42,7 @@ export const useDeleteWorkpads = () => { const removedIds = workpadIds.filter((id) => passes.includes(id)); if (errored.length > 0) { - notifyService.error(errors.getDeleteFailureErrorMessage()); + getCanvasNotifyService().error(errors.getDeleteFailureErrorMessage()); } return { @@ -51,7 +51,7 @@ export const useDeleteWorkpads = () => { }; }); }, - [workpadService, notifyService] + [workpadService] ); }; diff --git a/x-pack/plugins/canvas/public/lib/assets.ts b/x-pack/plugins/canvas/public/lib/assets.ts index d7fd0ecbac57f..b51cda9216fbc 100644 --- a/x-pack/plugins/canvas/public/lib/assets.ts +++ b/x-pack/plugins/canvas/public/lib/assets.ts @@ -6,8 +6,8 @@ */ import { i18n } from '@kbn/i18n'; import { AssetType, CanvasAsset } from '../../types'; -import { CanvasNotifyService } from '../services/notify'; import { getId } from './get_id'; +import { getCanvasNotifyService } from '../services/canvas_notify_service'; const strings = { getSaveFailureTitle: () => @@ -32,7 +32,8 @@ export const createAsset = (type: AssetType['type'], content: AssetType['value'] '@created': new Date().toISOString(), }); -export const notifyError = (err: any, notifyErrorFn: CanvasNotifyService['error']) => { +export const notifyError = (err: any) => { + const { error: notifyErrorFn } = getCanvasNotifyService(); const statusCode = err.response && err.response.status; switch (statusCode) { case 400: diff --git a/x-pack/plugins/canvas/public/lib/element_handler_creators.ts b/x-pack/plugins/canvas/public/lib/element_handler_creators.ts index 82b9827529040..567733d659963 100644 --- a/x-pack/plugins/canvas/public/lib/element_handler_creators.ts +++ b/x-pack/plugins/canvas/public/lib/element_handler_creators.ts @@ -12,6 +12,7 @@ import { pluginServices } from '../services'; import { getId } from './get_id'; import { PositionedElement } from '../../types'; import { ELEMENT_NUDGE_OFFSET, ELEMENT_SHIFT_OFFSET } from '../../common/lib/constants'; +import { getCanvasNotifyService } from '../services/canvas_notify_service'; const extractId = (node: { id: string }): string => node.id; @@ -71,7 +72,7 @@ export const basicHandlerCreators = { createCustomElement: ({ selectedNodes }: Props) => (name = '', description = '', image = ''): void => { - const notifyService = pluginServices.getServices().notify; + const notifyService = getCanvasNotifyService(); const customElementService = pluginServices.getServices().customElement; if (selectedNodes.length) { diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts index 45e21e59717ad..f63d3bf8e32a1 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts @@ -10,12 +10,11 @@ import { useSelector } from 'react-redux'; import { CanvasWorkpad, State } from '../../../../types'; import { getWorkpad } from '../../../state/selectors/workpad'; import { canUserWrite } from '../../../state/selectors/app'; -import { useWorkpadService, useNotifyService } from '../../../services'; +import { useWorkpadService } from '../../../services'; import { notifyError } from '../../../lib/assets'; export const useWorkpadPersist = () => { const service = useWorkpadService(); - const notifyService = useNotifyService(); // Watch for workpad state and then persist those changes const [workpad, canWrite]: [CanvasWorkpad, boolean] = useSelector((state: State) => [ @@ -31,9 +30,9 @@ export const useWorkpadPersist = () => { if (canWrite) { if (workpadChanged) { service.updateWorkpad(workpad.id, workpad).catch((err) => { - notifyError(err, notifyService.error); + notifyError(err); }); } } - }, [service, workpad, workpadChanged, canWrite, notifyService.error]); + }, [service, workpad, workpadChanged, canWrite]); }; diff --git a/x-pack/plugins/canvas/public/services/kibana/expressions.ts b/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts similarity index 68% rename from x-pack/plugins/canvas/public/services/kibana/expressions.ts rename to x-pack/plugins/canvas/public/services/canvas_expressions_service.ts index 248cd462bea90..e3a8b277d5d7f 100644 --- a/x-pack/plugins/canvas/public/services/kibana/expressions.ts +++ b/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts @@ -4,36 +4,21 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { fromExpression, getType } from '@kbn/interpreter'; import { ExpressionAstExpression, ExpressionExecutionParams, ExpressionValue, } from '@kbn/expressions-plugin/common'; +import { fromExpression, getType } from '@kbn/interpreter'; import { pluck } from 'rxjs'; -import { ExpressionsServiceStart } from '@kbn/expressions-plugin/public'; -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -import { buildEmbeddableFilters } from '../../../common/lib/build_embeddable_filters'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasFiltersService } from './filters'; -import { CanvasNotifyService } from '../notify'; +import { buildEmbeddableFilters } from '../../common/lib/build_embeddable_filters'; +import { expressionsService } from './kibana_services'; interface Options { castToRender?: boolean; } -export class ExpressionsService { - private filters: CanvasFiltersService; - private notify: CanvasNotifyService; - - constructor( - private readonly expressions: ExpressionsServiceStart, - { filters, notify }: CanvasExpressionsServiceRequiredServices - ) { - this.filters = filters; - this.notify = notify; - } - +class ExpressionsService { async interpretAst( ast: ExpressionAstExpression, variables: Record, @@ -51,7 +36,7 @@ export class ExpressionsService { input: ExpressionValue = null, context?: ExpressionExecutionParams ): Promise { - return await this.expressions + return await expressionsService .execute(ast, input, { ...context, namespace: 'canvas' }) .getData() .pipe(pluck('result')) @@ -98,11 +83,11 @@ export class ExpressionsService { } getRenderer(name: string) { - return this.expressions.getRenderer(name); + return expressionsService.getRenderer(name); } getFunctions() { - return this.expressions.getFunctions(); + return expressionsService.getFunctions(); } private async getFilters() { @@ -122,19 +107,11 @@ export class ExpressionsService { } } -export type CanvasExpressionsService = ExpressionsService; -export interface CanvasExpressionsServiceRequiredServices { - notify: CanvasNotifyService; - filters: CanvasFiltersService; -} - -export type CanvasExpressionsServiceFactory = KibanaPluginServiceFactory< - CanvasExpressionsService, - CanvasStartDeps, - CanvasExpressionsServiceRequiredServices ->; +let canvasExpressionsService: ExpressionsService; -export const expressionsServiceFactory: CanvasExpressionsServiceFactory = ( - { startPlugins }, - requiredServices -) => new ExpressionsService(startPlugins.expressions, requiredServices); +export const getCanvasExpressionService = () => { + if (!canvasExpressionsService) { + canvasExpressionsService = new ExpressionsService(); + } + return canvasExpressionsService; +}; diff --git a/x-pack/plugins/canvas/public/services/kibana/notify.ts b/x-pack/plugins/canvas/public/services/canvas_notify_service.ts similarity index 72% rename from x-pack/plugins/canvas/public/services/kibana/notify.ts rename to x-pack/plugins/canvas/public/services/canvas_notify_service.ts index 8448a1d515fe4..f836d0590bbfc 100644 --- a/x-pack/plugins/canvas/public/services/kibana/notify.ts +++ b/x-pack/plugins/canvas/public/services/canvas_notify_service.ts @@ -6,17 +6,17 @@ */ import { get } from 'lodash'; -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; import { ToastInputFields } from '@kbn/core/public'; -import { formatMsg } from '../../lib/format_msg'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasNotifyService } from '../notify'; +import { formatMsg } from '../lib/format_msg'; +import { coreServices } from './kibana_services'; -export type CanvasNotifyServiceFactory = KibanaPluginServiceFactory< - CanvasNotifyService, - CanvasStartDeps ->; +interface CanvasNotifyService { + error: (err: string | Error, opts?: ToastInputFields) => void; + warning: (err: string | Error, opts?: ToastInputFields) => void; + info: (err: string | Error, opts?: ToastInputFields) => void; + success: (err: string | Error, opts?: ToastInputFields) => void; +} const getToast = (err: Error | string, opts: ToastInputFields = {}) => { const errData = (get(err, 'response') || err) as Error | string; @@ -36,8 +36,8 @@ const getToast = (err: Error | string, opts: ToastInputFields = {}) => { }; }; -export const notifyServiceFactory: CanvasNotifyServiceFactory = ({ coreStart }) => { - const toasts = coreStart.notifications.toasts; +export const getCanvasNotifyService = (): CanvasNotifyService => { + const toasts = coreServices.notifications.toasts; return { /* diff --git a/x-pack/plugins/canvas/public/services/expressions.ts b/x-pack/plugins/canvas/public/services/expressions.ts deleted file mode 100644 index 456a1314bdfff..0000000000000 --- a/x-pack/plugins/canvas/public/services/expressions.ts +++ /dev/null @@ -1,8 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export type { CanvasExpressionsService } from './kibana/expressions'; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index dd035fcd3b1ad..3112edc595327 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -12,7 +12,7 @@ import { PluginServices } from '@kbn/presentation-util-plugin/public'; import { CanvasCustomElementService } from './custom_element'; import { CanvasDataViewsService } from './data_views'; import { CanvasEmbeddablesService } from './embeddables'; -import { CanvasExpressionsService } from './expressions'; +import { CanvasExpressionsService } from './canvas_expressions_service'; import { CanvasFiltersService } from './filters'; import { CanvasLabsService } from './labs'; import { CanvasNavLinkService } from './nav_link'; @@ -22,6 +22,8 @@ import { CanvasReportingService } from './reporting'; import { CanvasVisualizationsService } from './visualizations'; import { CanvasWorkpadService } from './workpad'; import { CanvasUiActionsService } from './ui_actions'; +import { useMemo } from 'react'; +import { getCanvasNotifyService } from './canvas_notify_service'; export interface CanvasPluginServices { customElement: CanvasCustomElementService; @@ -43,7 +45,6 @@ export const pluginServices = new PluginServices(); export const useCustomElementService = () => (() => pluginServices.getHooks().customElement.useService())(); -export const useDataViewsService = () => (() => pluginServices.getHooks().dataViews.useService())(); export const useEmbeddablesService = () => (() => pluginServices.getHooks().embeddables.useService())(); export const useExpressionsService = () => @@ -51,7 +52,10 @@ export const useExpressionsService = () => export const useFiltersService = () => (() => pluginServices.getHooks().filters.useService())(); export const useLabsService = () => (() => pluginServices.getHooks().labs.useService())(); export const useNavLinkService = () => (() => pluginServices.getHooks().navLink.useService())(); -export const useNotifyService = () => (() => pluginServices.getHooks().notify.useService())(); +export const useNotifyService = () => { + const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); + return canvasNotifyService; +}; export const usePlatformService = () => (() => pluginServices.getHooks().platform.useService())(); export const useReportingService = () => (() => pluginServices.getHooks().reporting.useService())(); export const useVisualizationsService = () => diff --git a/x-pack/plugins/canvas/public/services/kibana/index.ts b/x-pack/plugins/canvas/public/services/kibana/index.ts deleted file mode 100644 index cab569133f70f..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/index.ts +++ /dev/null @@ -1,66 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - PluginServiceProviders, - PluginServiceProvider, - PluginServiceRegistry, - KibanaPluginServiceParams, -} from '@kbn/presentation-util-plugin/public'; - -import { CanvasPluginServices } from '..'; -import { CanvasStartDeps } from '../../plugin'; -import { customElementServiceFactory } from './custom_element'; -import { dataViewsServiceFactory } from './data_views'; -import { embeddablesServiceFactory } from './embeddables'; -import { expressionsServiceFactory } from './expressions'; -import { labsServiceFactory } from './labs'; -import { navLinkServiceFactory } from './nav_link'; -import { notifyServiceFactory } from './notify'; -import { platformServiceFactory } from './platform'; -import { reportingServiceFactory } from './reporting'; -import { visualizationsServiceFactory } from './visualizations'; -import { workpadServiceFactory } from './workpad'; -import { filtersServiceFactory } from './filters'; -import { uiActionsServiceFactory } from './ui_actions'; - -export { customElementServiceFactory } from './custom_element'; -export { dataViewsServiceFactory } from './data_views'; -export { embeddablesServiceFactory } from './embeddables'; -export { expressionsServiceFactory } from './expressions'; -export { filtersServiceFactory } from './filters'; -export { labsServiceFactory } from './labs'; -export { notifyServiceFactory } from './notify'; -export { platformServiceFactory } from './platform'; -export { reportingServiceFactory } from './reporting'; -export { visualizationsServiceFactory } from './visualizations'; -export { workpadServiceFactory } from './workpad'; -export { uiActionsServiceFactory } from './ui_actions'; - -export const pluginServiceProviders: PluginServiceProviders< - CanvasPluginServices, - KibanaPluginServiceParams -> = { - customElement: new PluginServiceProvider(customElementServiceFactory), - dataViews: new PluginServiceProvider(dataViewsServiceFactory, ['notify']), - embeddables: new PluginServiceProvider(embeddablesServiceFactory), - expressions: new PluginServiceProvider(expressionsServiceFactory, ['filters', 'notify']), - filters: new PluginServiceProvider(filtersServiceFactory), - labs: new PluginServiceProvider(labsServiceFactory), - navLink: new PluginServiceProvider(navLinkServiceFactory), - notify: new PluginServiceProvider(notifyServiceFactory), - platform: new PluginServiceProvider(platformServiceFactory), - reporting: new PluginServiceProvider(reportingServiceFactory), - visualizations: new PluginServiceProvider(visualizationsServiceFactory), - workpad: new PluginServiceProvider(workpadServiceFactory), - uiActions: new PluginServiceProvider(uiActionsServiceFactory), -}; - -export const pluginServiceRegistry = new PluginServiceRegistry< - CanvasPluginServices, - KibanaPluginServiceParams ->(pluginServiceProviders); diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index 9ca0bfe9206c1..3e232043e5c96 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -10,13 +10,14 @@ import { BehaviorSubject } from 'rxjs'; import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; import type { AppUpdater, CoreStart, PluginInitializerContext } from '@kbn/core/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -// import type { DataView, DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { EmbeddableStart } from '@kbn/embeddable-plugin/public/plugin'; +import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; -// import type { ReportingStart } from '@kbn/reporting-plugin/public'; import type { SpacesApi } from '@kbn/spaces-plugin/public'; import type { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin'; import type { VisualizationsStart } from '@kbn/visualizations-plugin/public'; +import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; +// import type { ReportingStart } from '@kbn/reporting-plugin/public'; import { SESSIONSTORAGE_LASTPATH } from '../../common/lib'; import { getSessionStorage } from '../lib/storage'; @@ -31,7 +32,8 @@ export let kibanaVersion: string; export let coreServices: CoreStart; export let contentManagementService: ContentManagementPublicStart; export let dataService: DataPublicPluginStart; -// export let dataViewsService: DataViewsPublicPluginStart; +export let expressionsService: ExpressionsStart; +export let dataViewsService: DataViewsPublicPluginStart; export let embeddableService: EmbeddableStart; export let presentationUtilService: PresentationUtilPluginStart; // export let reportingService: ReportingStart | undefined; @@ -54,7 +56,8 @@ export const setKibanaServices = ( coreServices = kibanaCore; contentManagementService = deps.contentManagement; dataService = deps.data; - // dataViewsService = deps.dataViews; + expressionsService = deps.expressions; + dataViewsService = deps.dataViews; embeddableService = deps.embeddable; presentationUtilService = deps.presentationUtil; // reportingService = kibanaCore.application.capabilities.canvas?.generatePdf diff --git a/x-pack/plugins/canvas/public/state/actions/elements.js b/x-pack/plugins/canvas/public/state/actions/elements.js index b94a198ee4be9..aba2869c28f62 100644 --- a/x-pack/plugins/canvas/public/state/actions/elements.js +++ b/x-pack/plugins/canvas/public/state/actions/elements.js @@ -24,6 +24,7 @@ import { getDefaultElement } from '../defaults'; import { ErrorStrings } from '../../../i18n'; import { subMultitree } from '../../lib/aeroelastic/functional'; import { pluginServices } from '../../services'; +import { getCanvasNotifyService } from '../../services/canvas_notify_service'; import { selectToplevelNodes } from './transient'; import * as args from './resolved_args'; @@ -129,7 +130,8 @@ const fetchRenderableWithContextFn = ({ dispatch, getState }, element, ast, cont }); const variables = getWorkpadVariablesAsObject(getState()); - const { expressions, notify } = pluginServices.getServices(); + const { expressions } = pluginServices.getServices(); + const notify = getCanvasNotifyService(); return expressions .runInterpreter(ast, context, variables, { castToRender: true }) From bc18acd8b2166de1ff60cc0933ae19f2ec5b759e Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 1 Oct 2024 10:41:22 -0600 Subject: [PATCH 04/41] Start cleaning up hooks --- .../renderers/embeddable/embeddable.tsx | 5 +-- .../datasource/datasource_component.js | 11 ++--- .../embeddable_flyout/flyout.component.tsx | 7 +++- .../components/function_form_list/index.js | 4 +- .../hooks/workpad/use_incoming_embeddable.ts | 8 ++-- .../editor_menu/editor_menu.tsx | 23 +++++------ .../flyout/hooks/use_download_runtime.ts | 2 +- .../workpad_header/share_menu/share_menu.tsx | 3 +- .../canvas/public/functions/filters.ts | 6 ++- .../canvas/public/lib/create_handlers.ts | 4 +- .../public/lib/element_handler_creators.ts | 4 +- .../routes/workpad/hooks/use_workpad.ts | 5 +-- .../public/services/canvas_filters_service.ts | 40 +++++++++++++++++++ .../plugins/canvas/public/services/index.ts | 26 ++++++------ .../canvas/public/state/actions/elements.js | 11 ++--- 15 files changed, 98 insertions(+), 61 deletions(-) create mode 100644 x-pack/plugins/canvas/public/services/canvas_filters_service.ts diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx index d088988c243fe..a21528fb970fb 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx @@ -19,7 +19,6 @@ import React, { FC } from 'react'; import ReactDOM from 'react-dom'; import { useSearchApi } from '@kbn/presentation-publishing'; import { omit } from 'lodash'; -import { pluginServices } from '../../../public/services'; import { CANVAS_EMBEDDABLE_CLASSNAME } from '../../../common/lib'; import { RendererStrings } from '../../../i18n'; import { @@ -32,6 +31,7 @@ import { EmbeddableExpression } from '../../expression_types/embeddable'; import { StartDeps } from '../../plugin'; import { embeddableInputToExpression } from './embeddable_input_to_expression'; import { useGetAppContext } from './use_get_app_context'; +import { embeddableService } from '../../../public/services/kibana_services'; const { embeddable: strings } = RendererStrings; @@ -132,13 +132,12 @@ export const embeddableRendererFactory = ( help: strings.getHelpDescription(), reuseDomNode: true, render: async (domNode, { input, embeddableType, canvasApi }, handlers) => { - const { embeddables } = pluginServices.getServices(); const uniqueId = handlers.getElementId(); const isByValueEnabled = plugins.presentationUtil.labsService.isProjectEnabled( 'labs:canvas:byValueEmbeddable' ); - if (embeddables.reactEmbeddableRegistryHasKey(embeddableType)) { + if (embeddableService.reactEmbeddableRegistryHasKey(embeddableType)) { /** * Prioritize React embeddables */ diff --git a/x-pack/plugins/canvas/public/components/datasource/datasource_component.js b/x-pack/plugins/canvas/public/components/datasource/datasource_component.js index 4b64149d2a8f6..0d61015536294 100644 --- a/x-pack/plugins/canvas/public/components/datasource/datasource_component.js +++ b/x-pack/plugins/canvas/public/components/datasource/datasource_component.js @@ -20,7 +20,7 @@ import { import { isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { pluginServices } from '../../services'; +import { dataViewsService } from '../../services/kibana_services'; import { DatasourceSelector } from './datasource_selector'; import { DatasourcePreview } from './datasource_preview'; @@ -67,12 +67,9 @@ export class DatasourceComponent extends PureComponent { state = { defaultIndex: '' }; componentDidMount() { - pluginServices - .getServices() - .dataViews.getDefaultDataView() - .then((defaultDataView) => { - this.setState({ defaultIndex: defaultDataView.title }); - }); + dataViewsService.getDefaultDataView().then((defaultDataView) => { + this.setState({ defaultIndex: defaultDataView.title }); + }); } componentDidUpdate(prevProps) { diff --git a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx index 39740b62b849f..fbb7b971bfcb4 100644 --- a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx +++ b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.component.tsx @@ -9,11 +9,14 @@ import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eu import { i18n } from '@kbn/i18n'; import React, { FC, useCallback, useMemo } from 'react'; -import { coreServices } from '@kbn/controls-plugin/public/services/kibana_services'; import { EmbeddableFactory, ReactEmbeddableSavedObject } from '@kbn/embeddable-plugin/public'; import { FinderAttributes } from '@kbn/saved-objects-finder-plugin/common'; import { SavedObjectFinder, SavedObjectMetaData } from '@kbn/saved-objects-finder-plugin/public'; -import { contentManagementService, embeddableService } from '../../services/kibana_services'; +import { + contentManagementService, + coreServices, + embeddableService, +} from '../../services/kibana_services'; const strings = { getNoItemsText: () => diff --git a/x-pack/plugins/canvas/public/components/function_form_list/index.js b/x-pack/plugins/canvas/public/components/function_form_list/index.js index 0ad6651e3f57e..53ce940563887 100644 --- a/x-pack/plugins/canvas/public/components/function_form_list/index.js +++ b/x-pack/plugins/canvas/public/components/function_form_list/index.js @@ -8,7 +8,7 @@ import { compose, withProps } from 'react-recompose'; import { get } from 'lodash'; import { toExpression } from '@kbn/interpreter'; -import { pluginServices } from '../../services'; +import { getCanvasExpressionService } from '../../services/canvas_expressions_service'; import { getArgTypeDef } from '../../lib/args'; import { FunctionFormList as Component } from './function_form_list'; @@ -78,7 +78,7 @@ const componentFactory = ({ parentPath, removable, }) => { - const { expressions } = pluginServices.getServices(); + const { expressions } = getCanvasExpressionService(); return { args, nestedFunctionsArgs: argsWithExprFunctions, diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts index 0a4e66917814d..50c3e527bbbae 100644 --- a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts @@ -12,7 +12,7 @@ import { ErrorStrings } from '../../../../i18n'; import { CANVAS_APP } from '../../../../common/lib'; import { decode } from '../../../../common/lib/embeddable_dataurl'; import { CanvasElement, CanvasPage } from '../../../../types'; -import { useEmbeddablesService, useLabsService, useNotifyService } from '../../../services'; +import { useNotifyService } from '../../../services'; // @ts-expect-error unconverted file import { addElement, fetchAllRenderables } from '../../../state/actions/elements'; // @ts-expect-error unconverted file @@ -24,16 +24,16 @@ import { } from '../../../state/actions/embeddable'; import { clearValue } from '../../../state/actions/resolved_args'; import { embeddableInputToExpression } from '../../../../canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression'; +import { embeddableService, presentationUtilService } from '../../../services/kibana_services'; const { actionsElements: strings } = ErrorStrings; export const useIncomingEmbeddable = (selectedPage: CanvasPage) => { - const embeddablesService = useEmbeddablesService(); - const labsService = useLabsService(); + const labsService = presentationUtilService.labsService; const dispatch = useDispatch(); const notifyService = useNotifyService(); const isByValueEnabled = labsService.isProjectEnabled('labs:canvas:byValueEmbeddable'); - const stateTransferService = embeddablesService.getStateTransfer(); + const stateTransferService = embeddableService.getStateTransfer(); // fetch incoming embeddable from state transfer service. const incomingEmbeddable = stateTransferService.getIncomingEmbeddablePackage(CANVAS_APP, true); 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 fd644903ac25d..06d20e919dcbe 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 @@ -21,11 +21,6 @@ import { import { Action, ActionExecutionContext } from '@kbn/ui-actions-plugin/public/actions'; import { trackCanvasUiMetric, METRIC_TYPE } from '../../../lib/ui_metric'; -import { - useEmbeddablesService, - useUiActionsService, - useVisualizationsService, -} from '../../../services'; import { CANVAS_APP } from '../../../../common/lib'; import { ElementSpec } from '../../../../types'; import { EditorMenu as Component } from './editor_menu.component'; @@ -33,6 +28,11 @@ import { embeddableInputToExpression } from '../../../../canvas_plugin_src/rende import { EmbeddableInput as CanvasEmbeddableInput } from '../../../../canvas_plugin_src/expression_types'; import { useCanvasApi } from '../../hooks/use_canvas_api'; import { ADD_CANVAS_ELEMENT_TRIGGER } from '../../../state/triggers/add_canvas_element_trigger'; +import { + embeddableService, + uiActionsService, + visualizationsService, +} from '../../../services/kibana_services'; interface Props { /** @@ -47,18 +47,15 @@ interface UnwrappedEmbeddableFactory { } export const EditorMenu: FC = ({ addElement }) => { - const embeddablesService = useEmbeddablesService(); const { pathname, search, hash } = useLocation(); - const stateTransferService = embeddablesService.getStateTransfer(); - const visualizationsService = useVisualizationsService(); - const uiActions = useUiActionsService(); + const stateTransferService = embeddableService.getStateTransfer(); const canvasApi = useCanvasApi(); const [addPanelActions, setAddPanelActions] = useState>>([]); const embeddableFactories = useMemo( - () => (embeddablesService ? Array.from(embeddablesService.getEmbeddableFactories()) : []), - [embeddablesService] + () => (embeddableService ? Array.from(embeddableService.getEmbeddableFactories()) : []), + [] ); const [unwrappedEmbeddableFactories, setUnwrappedEmbeddableFactories] = useState< @@ -79,7 +76,7 @@ export const EditorMenu: FC = ({ addElement }) => { useEffect(() => { let mounted = true; async function loadPanelActions() { - const registeredActions = await uiActions?.getTriggerCompatibleActions?.( + const registeredActions = await uiActionsService.getTriggerCompatibleActions( ADD_CANVAS_ELEMENT_TRIGGER, { embeddable: canvasApi } ); @@ -89,7 +86,7 @@ export const EditorMenu: FC = ({ addElement }) => { return () => { mounted = false; }; - }, [uiActions, canvasApi]); + }, [canvasApi]); const createNewVisType = useCallback( (visType?: BaseVisType | VisTypeAlias) => () => { diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts index 3ce62f34ebbab..27b93269f4352 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts @@ -12,7 +12,7 @@ import { API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD } from '../../../../../../common/l import { ZIP } from '../../../../../../i18n/constants'; import type { CanvasRenderedWorkpad } from '../../../../../../shareable_runtime/types'; -import { useNotifyService, usePlatformService, useWorkpadService } from '../../../../../services'; +import { useNotifyService, useWorkpadService } from '../../../../../services'; import { coreServices } from '../../../../../services/kibana_services'; const strings = { diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx index 99087cb595f0b..2ec0d8c4281c7 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx @@ -9,7 +9,7 @@ import React, { useCallback } from 'react'; import { useSelector } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { State } from '../../../../types'; -import { useReportingService, usePlatformService } from '../../../services'; +import { useReportingService } from '../../../services'; import { getPages, getWorkpad } from '../../../state/selectors/workpad'; import { useDownloadWorkpad } from '../../hooks'; import { ShareMenu as ShareMenuComponent } from './share_menu.component'; @@ -29,7 +29,6 @@ const strings = { export const ShareMenu = () => { const downloadWorkpad = useDownloadWorkpad(); const reportingService = useReportingService(); - const platformService = usePlatformService(); const { workpad, pageCount } = useSelector((state: State) => ({ workpad: getWorkpad(state), diff --git a/x-pack/plugins/canvas/public/functions/filters.ts b/x-pack/plugins/canvas/public/functions/filters.ts index a168020b6eef8..a37953657e157 100644 --- a/x-pack/plugins/canvas/public/functions/filters.ts +++ b/x-pack/plugins/canvas/public/functions/filters.ts @@ -7,10 +7,11 @@ import { fromExpression } from '@kbn/interpreter'; import { get } from 'lodash'; -import { pluginServices } from '../services'; import type { FiltersFunction } from '../../common/functions'; import { buildFiltersFunction } from '../../common/functions'; import { InitializeArguments } from '.'; +import { getCanvasFiltersService } from '../services/canvas_filters_service'; +import { getCanvasExpressionService } from '../services/canvas_expressions_service'; export interface Arguments { group: string[]; @@ -40,7 +41,8 @@ function getFiltersByGroup(allFilters: string[], groups?: string[], ungrouped = export function filtersFunctionFactory(initialize: InitializeArguments): () => FiltersFunction { const fn: FiltersFunction['fn'] = (input, { group, ungrouped }) => { - const { expressions, filters: filtersService } = pluginServices.getServices(); + const expressions = getCanvasExpressionService(); + const filtersService = getCanvasFiltersService(); const filterList = getFiltersByGroup(filtersService.getFilters(), group, ungrouped); diff --git a/x-pack/plugins/canvas/public/lib/create_handlers.ts b/x-pack/plugins/canvas/public/lib/create_handlers.ts index 374bdaff99721..43ef4a3e8b97d 100644 --- a/x-pack/plugins/canvas/public/lib/create_handlers.ts +++ b/x-pack/plugins/canvas/public/lib/create_handlers.ts @@ -12,7 +12,7 @@ import { } from '@kbn/expressions-plugin/public'; import { updateEmbeddableExpression, fetchEmbeddableRenderable } from '../state/actions/embeddable'; import { RendererHandlers, CanvasElement } from '../../types'; -import { pluginServices } from '../services'; +import { getCanvasFiltersService } from '../services/canvas_filters_service'; import { clearValue } from '../state/actions/resolved_args'; // This class creates stub handlers to ensure every element and renderer fulfills the contract. @@ -80,7 +80,7 @@ export const createDispatchedHandlerFactory = ( oldElement = element; } - const { filters } = pluginServices.getServices(); + const filters = getCanvasFiltersService(); const handlers: RendererHandlers & { event: IInterpreterRenderHandlers['event']; diff --git a/x-pack/plugins/canvas/public/lib/element_handler_creators.ts b/x-pack/plugins/canvas/public/lib/element_handler_creators.ts index 567733d659963..e767a482a87d3 100644 --- a/x-pack/plugins/canvas/public/lib/element_handler_creators.ts +++ b/x-pack/plugins/canvas/public/lib/element_handler_creators.ts @@ -146,7 +146,7 @@ export const clipboardHandlerCreators = { cutNodes: ({ pageId, removeNodes, selectedNodes }: Props) => (): void => { - const notifyService = pluginServices.getServices().notify; + const notifyService = getCanvasNotifyService(); if (selectedNodes.length) { setClipboardData({ selectedNodes }); @@ -157,7 +157,7 @@ export const clipboardHandlerCreators = { copyNodes: ({ selectedNodes }: Props) => (): void => { - const notifyService = pluginServices.getServices().notify; + const notifyService = getCanvasNotifyService(); if (selectedNodes.length) { setClipboardData({ selectedNodes }); diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts index 122181cc22847..40ab8d17d491c 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts @@ -8,7 +8,7 @@ import { useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { useDispatch, useSelector } from 'react-redux'; -import { useWorkpadService, usePlatformService } from '../../../services'; +import { useWorkpadService } from '../../../services'; import { getWorkpad } from '../../../state/selectors/workpad'; import { setWorkpad } from '../../../state/actions/workpad'; // @ts-expect-error @@ -35,7 +35,6 @@ export const useWorkpad = ( ): [CanvasWorkpad | undefined, string | Error | undefined] => { const workpadService = useWorkpadService(); const workpadResolve = workpadService.resolve; - const platformService = usePlatformService(); const dispatch = useDispatch(); const storedWorkpad = useSelector(getWorkpad); const [error, setError] = useState(undefined); @@ -85,7 +84,7 @@ export const useWorkpad = ( }); } })(); - }, [workpadId, resolveInfo, getRedirectPath, platformService]); + }, [workpadId, resolveInfo, getRedirectPath]); return [storedWorkpad.id === workpadId ? storedWorkpad : undefined, error]; }; diff --git a/x-pack/plugins/canvas/public/services/canvas_filters_service.ts b/x-pack/plugins/canvas/public/services/canvas_filters_service.ts new file mode 100644 index 0000000000000..b46c7fbda8b33 --- /dev/null +++ b/x-pack/plugins/canvas/public/services/canvas_filters_service.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// @ts-expect-error untyped local +import { getState, getStore } from '../state/store'; +import { State } from '../../types'; +import { getGlobalFilters, getWorkpadVariablesAsObject } from '../state/selectors/workpad'; +// @ts-expect-error untyped local +import { setFilter } from '../state/actions/elements'; + +class FiltersService { + constructor() {} + + getFilters(state: State = getState()) { + return getGlobalFilters(state); + } + + updateFilter(filterId: string, filterExpression: string) { + const { dispatch } = getStore(); + dispatch(setFilter(filterExpression, filterId, true)); + } + + getFiltersContext(state: State = getState()) { + const variables = getWorkpadVariablesAsObject(state); + return { variables }; + } +} + +let canvasFiltersService: FiltersService; + +export const getCanvasFiltersService = () => { + if (!canvasFiltersService) { + canvasFiltersService = new FiltersService(); + } + return canvasFiltersService; +}; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index 3112edc595327..c0f493fedf48a 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -12,7 +12,7 @@ import { PluginServices } from '@kbn/presentation-util-plugin/public'; import { CanvasCustomElementService } from './custom_element'; import { CanvasDataViewsService } from './data_views'; import { CanvasEmbeddablesService } from './embeddables'; -import { CanvasExpressionsService } from './canvas_expressions_service'; +import { CanvasExpressionsService, getCanvasExpressionService } from './canvas_expressions_service'; import { CanvasFiltersService } from './filters'; import { CanvasLabsService } from './labs'; import { CanvasNavLinkService } from './nav_link'; @@ -24,6 +24,7 @@ import { CanvasWorkpadService } from './workpad'; import { CanvasUiActionsService } from './ui_actions'; import { useMemo } from 'react'; import { getCanvasNotifyService } from './canvas_notify_service'; +import { getCanvasFiltersService } from './canvas_filters_service'; export interface CanvasPluginServices { customElement: CanvasCustomElementService; @@ -45,20 +46,19 @@ export const pluginServices = new PluginServices(); export const useCustomElementService = () => (() => pluginServices.getHooks().customElement.useService())(); -export const useEmbeddablesService = () => - (() => pluginServices.getHooks().embeddables.useService())(); -export const useExpressionsService = () => - (() => pluginServices.getHooks().expressions.useService())(); -export const useFiltersService = () => (() => pluginServices.getHooks().filters.useService())(); -export const useLabsService = () => (() => pluginServices.getHooks().labs.useService())(); -export const useNavLinkService = () => (() => pluginServices.getHooks().navLink.useService())(); + +export const useExpressionsService = () => { + const canvasExpressionService = useMemo(() => getCanvasExpressionService(), []); + return canvasExpressionService; +}; +export const useFiltersService = () => { + const canvasFiltersService = useMemo(() => getCanvasFiltersService(), []); + return canvasFiltersService; +}; export const useNotifyService = () => { - const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); + const canvasNotifyService: CanvasNotifyService = useMemo(() => getCanvasNotifyService(), []); return canvasNotifyService; }; -export const usePlatformService = () => (() => pluginServices.getHooks().platform.useService())(); + export const useReportingService = () => (() => pluginServices.getHooks().reporting.useService())(); -export const useVisualizationsService = () => - (() => pluginServices.getHooks().visualizations.useService())(); export const useWorkpadService = () => (() => pluginServices.getHooks().workpad.useService())(); -export const useUiActionsService = () => (() => pluginServices.getHooks().uiActions.useService())(); diff --git a/x-pack/plugins/canvas/public/state/actions/elements.js b/x-pack/plugins/canvas/public/state/actions/elements.js index aba2869c28f62..68970c40e7dc4 100644 --- a/x-pack/plugins/canvas/public/state/actions/elements.js +++ b/x-pack/plugins/canvas/public/state/actions/elements.js @@ -23,7 +23,7 @@ import { getValue as getResolvedArgsValue } from '../selectors/resolved_args'; import { getDefaultElement } from '../defaults'; import { ErrorStrings } from '../../../i18n'; import { subMultitree } from '../../lib/aeroelastic/functional'; -import { pluginServices } from '../../services'; +import { getCanvasExpressionService } from '../../services/canvas_expressions_service'; import { getCanvasNotifyService } from '../../services/canvas_notify_service'; import { selectToplevelNodes } from './transient'; import * as args from './resolved_args'; @@ -102,7 +102,7 @@ const fetchContextFn = ({ dispatch, getState }, index, element, fullRefresh = fa const variables = getWorkpadVariablesAsObject(getState()); - const { expressions } = pluginServices.getServices(); + const expressions = getCanvasExpressionService(); const elementWithNewAst = set(element, pathToTarget, astChain); // get context data from a partial AST @@ -130,7 +130,7 @@ const fetchRenderableWithContextFn = ({ dispatch, getState }, element, ast, cont }); const variables = getWorkpadVariablesAsObject(getState()); - const { expressions } = pluginServices.getServices(); + const expressions = getCanvasExpressionService(); const notify = getCanvasNotifyService(); return expressions @@ -179,7 +179,8 @@ export const fetchAllRenderables = createThunk( const argumentPath = [element.id, 'expressionRenderable']; const variables = getWorkpadVariablesAsObject(getState()); - const { expressions, notify } = pluginServices.getServices(); + const expressions = getCanvasExpressionService(); + const notify = getCanvasNotifyService(); return expressions .runInterpreter(ast, null, variables, { castToRender: true }) @@ -304,7 +305,7 @@ const setAst = createThunk('setAst', ({ dispatch }, ast, element, pageId, doRend const expression = toExpression(ast); dispatch(setExpression(expression, element.id, pageId, doRender)); } catch (err) { - const notifyService = pluginServices.getServices().notify; + const notifyService = getCanvasNotifyService(); notifyService.error(err); // TODO: remove this, may have been added just to cause a re-render, but why? From bc029820f0e54be0cd184f12dac2b73e4548b3e3 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 1 Oct 2024 11:24:28 -0600 Subject: [PATCH 05/41] Refactor reporting service --- .../workpad_header/share_menu/share_menu.tsx | 27 ++++++------ .../plugins/canvas/public/services/filters.ts | 8 ---- .../plugins/canvas/public/services/index.ts | 23 +--------- .../canvas/public/services/kibana/filters.ts | 42 ------------------- .../canvas/public/services/kibana_services.ts | 8 ++-- .../public/services/legacy/reporting.ts | 42 ------------------- .../plugins/canvas/public/services/notify.ts | 15 ------- 7 files changed, 18 insertions(+), 147 deletions(-) delete mode 100644 x-pack/plugins/canvas/public/services/filters.ts delete mode 100644 x-pack/plugins/canvas/public/services/kibana/filters.ts delete mode 100644 x-pack/plugins/canvas/public/services/legacy/reporting.ts delete mode 100644 x-pack/plugins/canvas/public/services/notify.ts diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx index 2ec0d8c4281c7..a062a4b59d6c5 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx @@ -9,12 +9,11 @@ import React, { useCallback } from 'react'; import { useSelector } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { State } from '../../../../types'; -import { useReportingService } from '../../../services'; import { getPages, getWorkpad } from '../../../state/selectors/workpad'; import { useDownloadWorkpad } from '../../hooks'; import { ShareMenu as ShareMenuComponent } from './share_menu.component'; import { getPdfJobParams } from './utils'; -import { kibanaVersion } from '../../../services/kibana_services'; +import { kibanaVersion, reportingService } from '../../../services/kibana_services'; const strings = { getUnknownExportErrorMessage: (type: string) => @@ -28,31 +27,29 @@ const strings = { export const ShareMenu = () => { const downloadWorkpad = useDownloadWorkpad(); - const reportingService = useReportingService(); const { workpad, pageCount } = useSelector((state: State) => ({ workpad: getWorkpad(state), pageCount: getPages(state).length, })); - const ReportingPanelPDFComponent = reportingService.getReportingPanelPDFComponent(); + const ReportingPanelPDFComponent = reportingService?.getReportingPanelPDFComponent(); const sharingData = { workpad, pageCount, }; - const ReportingComponent = - ReportingPanelPDFComponent !== null - ? ({ onClose }: { onClose: () => void }) => ( - getPdfJobParams(sharingData, kibanaVersion)} - layoutOption="canvas" - onClose={onClose} - objectId={workpad.id} - /> - ) - : null; + const ReportingComponent = ReportingPanelPDFComponent + ? ({ onClose }: { onClose: () => void }) => ( + getPdfJobParams(sharingData, kibanaVersion)} + layoutOption="canvas" + onClose={onClose} + objectId={workpad.id} + /> + ) + : null; const onExport = useCallback( (type: string) => { diff --git a/x-pack/plugins/canvas/public/services/filters.ts b/x-pack/plugins/canvas/public/services/filters.ts deleted file mode 100644 index 1ced3d15f6e10..0000000000000 --- a/x-pack/plugins/canvas/public/services/filters.ts +++ /dev/null @@ -1,8 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export type { CanvasFiltersService } from './kibana/filters'; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index c0f493fedf48a..b0a75eeab26c2 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -6,40 +6,22 @@ */ export * from './legacy'; +import { useMemo } from 'react'; import { PluginServices } from '@kbn/presentation-util-plugin/public'; import { CanvasCustomElementService } from './custom_element'; -import { CanvasDataViewsService } from './data_views'; -import { CanvasEmbeddablesService } from './embeddables'; -import { CanvasExpressionsService, getCanvasExpressionService } from './canvas_expressions_service'; +import { getCanvasExpressionService } from './canvas_expressions_service'; import { CanvasFiltersService } from './filters'; -import { CanvasLabsService } from './labs'; -import { CanvasNavLinkService } from './nav_link'; import { CanvasNotifyService } from './notify'; -import { CanvasPlatformService } from './platform'; -import { CanvasReportingService } from './reporting'; -import { CanvasVisualizationsService } from './visualizations'; -import { CanvasWorkpadService } from './workpad'; -import { CanvasUiActionsService } from './ui_actions'; -import { useMemo } from 'react'; import { getCanvasNotifyService } from './canvas_notify_service'; import { getCanvasFiltersService } from './canvas_filters_service'; export interface CanvasPluginServices { customElement: CanvasCustomElementService; - dataViews: CanvasDataViewsService; - embeddables: CanvasEmbeddablesService; - expressions: CanvasExpressionsService; filters: CanvasFiltersService; - labs: CanvasLabsService; - navLink: CanvasNavLinkService; notify: CanvasNotifyService; - platform: CanvasPlatformService; reporting: CanvasReportingService; - visualizations: CanvasVisualizationsService; - workpad: CanvasWorkpadService; - uiActions: CanvasUiActionsService; } export const pluginServices = new PluginServices(); @@ -60,5 +42,4 @@ export const useNotifyService = () => { return canvasNotifyService; }; -export const useReportingService = () => (() => pluginServices.getHooks().reporting.useService())(); export const useWorkpadService = () => (() => pluginServices.getHooks().workpad.useService())(); diff --git a/x-pack/plugins/canvas/public/services/kibana/filters.ts b/x-pack/plugins/canvas/public/services/kibana/filters.ts deleted file mode 100644 index 793b073aaf231..0000000000000 --- a/x-pack/plugins/canvas/public/services/kibana/filters.ts +++ /dev/null @@ -1,42 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; -// @ts-expect-error untyped local -import { getState, getStore } from '../../state/store'; -import { State } from '../../../types'; -import { getGlobalFilters, getWorkpadVariablesAsObject } from '../../state/selectors/workpad'; -import { CanvasStartDeps } from '../../plugin'; -// @ts-expect-error untyped local -import { setFilter } from '../../state/actions/elements'; - -export class FiltersService { - constructor() {} - - getFilters(state: State = getState()) { - return getGlobalFilters(state); - } - - updateFilter(filterId: string, filterExpression: string) { - const { dispatch } = getStore(); - dispatch(setFilter(filterExpression, filterId, true)); - } - - getFiltersContext(state: State = getState()) { - const variables = getWorkpadVariablesAsObject(state); - return { variables }; - } -} - -export type CanvasFiltersService = FiltersService; - -export type CanvasFiltersServiceFactory = KibanaPluginServiceFactory< - CanvasFiltersService, - CanvasStartDeps ->; - -export const filtersServiceFactory: CanvasFiltersServiceFactory = () => new FiltersService(); diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index 3e232043e5c96..acd4b2a9f577e 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -36,7 +36,7 @@ export let expressionsService: ExpressionsStart; export let dataViewsService: DataViewsPublicPluginStart; export let embeddableService: EmbeddableStart; export let presentationUtilService: PresentationUtilPluginStart; -// export let reportingService: ReportingStart | undefined; +export let reportingService: ReportingStart | undefined; export let spacesService: SpacesApi | undefined; export let uiActionsService: UiActionsPublicStart; export let visualizationsService: VisualizationsStart; @@ -60,9 +60,9 @@ export const setKibanaServices = ( dataViewsService = deps.dataViews; embeddableService = deps.embeddable; presentationUtilService = deps.presentationUtil; - // reportingService = kibanaCore.application.capabilities.canvas?.generatePdf - // ? deps.reporting - // : undefined; + reportingService = kibanaCore.application.capabilities.canvas?.generatePdf + ? deps.reporting + : undefined; spacesService = deps.spaces; uiActionsService = deps.uiActions; visualizationsService = deps.visualizations; diff --git a/x-pack/plugins/canvas/public/services/legacy/reporting.ts b/x-pack/plugins/canvas/public/services/legacy/reporting.ts deleted file mode 100644 index 411a892baed29..0000000000000 --- a/x-pack/plugins/canvas/public/services/legacy/reporting.ts +++ /dev/null @@ -1,42 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ReportingStart } from '@kbn/reporting-plugin/public'; -import { CanvasServiceFactory } from '.'; - -export interface ReportingService { - start?: ReportingStart; -} - -export const reportingServiceFactory: CanvasServiceFactory = ( - _coreSetup, - coreStart, - _setupPlugins, - startPlugins -): ReportingService => { - const { reporting } = startPlugins; - - const reportingEnabled = () => ({ start: reporting }); - const reportingDisabled = () => ({ start: undefined }); - - if (!reporting) { - // Reporting is not enabled - return reportingDisabled(); - } - - if (reporting.usesUiCapabilities()) { - if (coreStart.application.capabilities.canvas?.generatePdf === true) { - // Canvas has declared Reporting as a subfeature with the `generatePdf` UI Capability - return reportingEnabled(); - } else { - return reportingDisabled(); - } - } - - // Legacy/Deprecated: Reporting is enabled as an Elasticsearch feature - return reportingEnabled(); -}; diff --git a/x-pack/plugins/canvas/public/services/notify.ts b/x-pack/plugins/canvas/public/services/notify.ts deleted file mode 100644 index 83e7b4e71ee72..0000000000000 --- a/x-pack/plugins/canvas/public/services/notify.ts +++ /dev/null @@ -1,15 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ToastInputFields } from '@kbn/core/public'; - -export interface CanvasNotifyService { - error: (err: string | Error, opts?: ToastInputFields) => void; - warning: (err: string | Error, opts?: ToastInputFields) => void; - info: (err: string | Error, opts?: ToastInputFields) => void; - success: (err: string | Error, opts?: ToastInputFields) => void; -} From d0681b08da3824b04d2de100fdfa89185939d51c Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 1 Oct 2024 11:37:06 -0600 Subject: [PATCH 06/41] Refactor custom elements service --- ...nt.ts => canvas_custom_element_service.ts} | 27 +++++++++++-------- .../canvas/public/services/custom_element.ts | 21 --------------- .../plugins/canvas/public/services/index.ts | 26 +++++------------- .../canvas/public/services/kibana_services.ts | 4 +-- 4 files changed, 25 insertions(+), 53 deletions(-) rename x-pack/plugins/canvas/public/services/{kibana/custom_element.ts => canvas_custom_element_service.ts} (57%) delete mode 100644 x-pack/plugins/canvas/public/services/custom_element.ts diff --git a/x-pack/plugins/canvas/public/services/kibana/custom_element.ts b/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts similarity index 57% rename from x-pack/plugins/canvas/public/services/kibana/custom_element.ts rename to x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts index a548ccdc23b2f..28d233b85c013 100644 --- a/x-pack/plugins/canvas/public/services/kibana/custom_element.ts +++ b/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts @@ -5,20 +5,25 @@ * 2.0. */ -import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public'; +import { API_ROUTE_CUSTOM_ELEMENT } from '../../common/lib'; +import { CustomElement } from '../../types'; +import { coreServices } from './kibana_services'; -import { API_ROUTE_CUSTOM_ELEMENT } from '../../../common/lib/constants'; -import { CustomElement } from '../../../types'; -import { CanvasStartDeps } from '../../plugin'; -import { CanvasCustomElementService } from '../custom_element'; +export interface CustomElementFindResponse { + total: number; + customElements: CustomElement[]; +} -export type CanvasCustomElementServiceFactory = KibanaPluginServiceFactory< - CanvasCustomElementService, - CanvasStartDeps ->; +export interface CanvasCustomElementService { + create: (customElement: CustomElement) => Promise; + get: (customElementId: string) => Promise; + update: (id: string, element: Partial) => Promise; + remove: (id: string) => Promise; + find: (searchTerm: string) => Promise; +} -export const customElementServiceFactory: CanvasCustomElementServiceFactory = ({ coreStart }) => { - const { http } = coreStart; +export const getCustomElementService: () => CanvasCustomElementService = () => { + const { http } = coreServices; const apiPath = `${API_ROUTE_CUSTOM_ELEMENT}`; return { diff --git a/x-pack/plugins/canvas/public/services/custom_element.ts b/x-pack/plugins/canvas/public/services/custom_element.ts deleted file mode 100644 index 675a5a2f23c01..0000000000000 --- a/x-pack/plugins/canvas/public/services/custom_element.ts +++ /dev/null @@ -1,21 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { CustomElement } from '../../types'; - -export interface CustomElementFindResponse { - total: number; - customElements: CustomElement[]; -} - -export interface CanvasCustomElementService { - create: (customElement: CustomElement) => Promise; - get: (customElementId: string) => Promise; - update: (id: string, element: Partial) => Promise; - remove: (id: string) => Promise; - find: (searchTerm: string) => Promise; -} diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index b0a75eeab26c2..fdd4a8fcd83ca 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -8,27 +8,15 @@ export * from './legacy'; import { useMemo } from 'react'; -import { PluginServices } from '@kbn/presentation-util-plugin/public'; - -import { CanvasCustomElementService } from './custom_element'; +import { getCustomElementService } from './canvas_custom_element_service'; import { getCanvasExpressionService } from './canvas_expressions_service'; -import { CanvasFiltersService } from './filters'; -import { CanvasNotifyService } from './notify'; -import { getCanvasNotifyService } from './canvas_notify_service'; import { getCanvasFiltersService } from './canvas_filters_service'; +import { getCanvasNotifyService } from './canvas_notify_service'; -export interface CanvasPluginServices { - customElement: CanvasCustomElementService; - filters: CanvasFiltersService; - notify: CanvasNotifyService; - reporting: CanvasReportingService; -} - -export const pluginServices = new PluginServices(); - -export const useCustomElementService = () => - (() => pluginServices.getHooks().customElement.useService())(); - +export const useCustomElementService = () => { + const canvasCustomElementService = useMemo(() => getCustomElementService(), []); + return canvasCustomElementService; +}; export const useExpressionsService = () => { const canvasExpressionService = useMemo(() => getCanvasExpressionService(), []); return canvasExpressionService; @@ -38,7 +26,7 @@ export const useFiltersService = () => { return canvasFiltersService; }; export const useNotifyService = () => { - const canvasNotifyService: CanvasNotifyService = useMemo(() => getCanvasNotifyService(), []); + const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); return canvasNotifyService; }; diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index acd4b2a9f577e..b47c2f49d3eec 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -10,14 +10,14 @@ import { BehaviorSubject } from 'rxjs'; import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; import type { AppUpdater, CoreStart, PluginInitializerContext } from '@kbn/core/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { EmbeddableStart } from '@kbn/embeddable-plugin/public/plugin'; import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; +import type { ReportingStart } from '@kbn/reporting-plugin/public'; import type { SpacesApi } from '@kbn/spaces-plugin/public'; import type { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin'; import type { VisualizationsStart } from '@kbn/visualizations-plugin/public'; -import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; -// import type { ReportingStart } from '@kbn/reporting-plugin/public'; import { SESSIONSTORAGE_LASTPATH } from '../../common/lib'; import { getSessionStorage } from '../lib/storage'; From d10cb911e3d98a20045bd6696624729e8e5a9947 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 1 Oct 2024 13:10:03 -0600 Subject: [PATCH 07/41] Remove last of plugin services --- x-pack/plugins/canvas/public/application.tsx | 27 ++++++------------- .../components/asset_manager/asset_manager.ts | 4 +-- .../workpad_header/share_menu/share_menu.tsx | 23 ++++++++-------- .../public/lib/element_handler_creators.ts | 4 +-- x-pack/plugins/canvas/public/plugin.tsx | 15 +++-------- .../services/canvas_expressions_service.ts | 16 ++++++++--- .../public/services/canvas_workpad_service.ts | 2 +- .../plugins/canvas/public/services/index.ts | 7 +++-- .../canvas/public/services/kibana_services.ts | 6 ++--- 9 files changed, 49 insertions(+), 55 deletions(-) diff --git a/x-pack/plugins/canvas/public/application.tsx b/x-pack/plugins/canvas/public/application.tsx index d9a279e2d2619..b7bcfd31ef6b9 100644 --- a/x-pack/plugins/canvas/public/application.tsx +++ b/x-pack/plugins/canvas/public/application.tsx @@ -19,7 +19,6 @@ import { AppMountParameters, CoreStart, CoreSetup, AppUpdater } from '@kbn/core/ import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { PluginServices } from '@kbn/presentation-util-plugin/public'; import { CanvasStartDeps, CanvasSetupDeps } from './plugin'; import { App } from './components/app'; @@ -32,12 +31,7 @@ import { init as initStatsReporter } from './lib/ui_metric'; import { CapabilitiesStrings } from '../i18n'; -import { - startLegacyServices, - services, - LegacyServicesProvider, - CanvasPluginServices, -} from './services'; +import { startLegacyServices, services, LegacyServicesProvider } from './services'; import { initFunctions } from './functions'; // @ts-expect-error untyped local import { appUnload } from './state/actions/app'; @@ -56,32 +50,27 @@ export const renderApp = ({ startPlugins, params, canvasStore, - pluginServices, }: { coreStart: CoreStart; startPlugins: CanvasStartDeps; params: AppMountParameters; canvasStore: Store; - pluginServices: PluginServices; }) => { const { presentationUtil } = startPlugins; const { element } = params; element.classList.add('canvas'); element.classList.add('canvasContainerWrapper'); - const ServicesContextProvider = pluginServices.getContextProvider(); ReactDOM.render( - - - - - - - - - + + + + + + + , element diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts index 7f9ee9ecffa83..582c5174b663f 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.ts @@ -20,7 +20,7 @@ import { State, AssetType, CanvasWorkpad } from '../../../types'; import { AssetManager as Component } from './asset_manager.component'; import { getFullWorkpadPersisted } from '../../state/selectors/workpad'; -import { pluginServices } from '../../services'; +import { getCanvasWorkpadService } from '../../services/canvas_workpad_service'; export const AssetManager = connect( (state: State) => ({ @@ -31,7 +31,7 @@ export const AssetManager = connect( onAddAsset: (workpad: CanvasWorkpad, type: AssetType['type'], content: AssetType['value']) => { // make the ID here and pass it into the action const asset = createAsset(type, content); - const { workpad: workpadService } = pluginServices.getServices(); + const workpadService = getCanvasWorkpadService(); return workpadService .updateAssets(workpad.id, { ...workpad.assets, [asset.id]: asset }) diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx index a062a4b59d6c5..e4239864c1915 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/share_menu.tsx @@ -33,22 +33,23 @@ export const ShareMenu = () => { pageCount: getPages(state).length, })); - const ReportingPanelPDFComponent = reportingService?.getReportingPanelPDFComponent(); - const sharingData = { workpad, pageCount, }; - const ReportingComponent = ReportingPanelPDFComponent - ? ({ onClose }: { onClose: () => void }) => ( - getPdfJobParams(sharingData, kibanaVersion)} - layoutOption="canvas" - onClose={onClose} - objectId={workpad.id} - /> - ) + const ReportingComponent = reportingService + ? ({ onClose }: { onClose: () => void }) => { + const ReportingPanelPDFV2 = reportingService!.components.ReportingPanelPDFV2; + return ( + getPdfJobParams(sharingData, kibanaVersion)} + layoutOption="canvas" + onClose={onClose} + objectId={workpad.id} + /> + ); + } : null; const onExport = useCallback( diff --git a/x-pack/plugins/canvas/public/lib/element_handler_creators.ts b/x-pack/plugins/canvas/public/lib/element_handler_creators.ts index e767a482a87d3..72a7df3a26775 100644 --- a/x-pack/plugins/canvas/public/lib/element_handler_creators.ts +++ b/x-pack/plugins/canvas/public/lib/element_handler_creators.ts @@ -8,11 +8,11 @@ import { camelCase } from 'lodash'; import { getClipboardData, setClipboardData } from './clipboard'; import { cloneSubgraphs } from './clone_subgraphs'; -import { pluginServices } from '../services'; import { getId } from './get_id'; import { PositionedElement } from '../../types'; import { ELEMENT_NUDGE_OFFSET, ELEMENT_SHIFT_OFFSET } from '../../common/lib/constants'; import { getCanvasNotifyService } from '../services/canvas_notify_service'; +import { getCustomElementService } from '../services/canvas_custom_element_service'; const extractId = (node: { id: string }): string => node.id; @@ -73,7 +73,7 @@ export const basicHandlerCreators = { ({ selectedNodes }: Props) => (name = '', description = '', image = ''): void => { const notifyService = getCanvasNotifyService(); - const customElementService = pluginServices.getServices().customElement; + const customElementService = getCustomElementService(); if (selectedNodes.length) { const content = JSON.stringify({ selectedNodes }); diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx index 5f385ce5f079b..666cb28a4806a 100644 --- a/x-pack/plugins/canvas/public/plugin.tsx +++ b/x-pack/plugins/canvas/public/plugin.tsx @@ -38,6 +38,7 @@ import { initLoadingIndicator } from './lib/loading_indicator'; import { getPluginApi, CanvasApi } from './plugin_api'; import { setupExpressions } from './setup_expressions'; import { addCanvasElementTrigger } from './state/triggers/add_canvas_element_trigger'; +import { setKibanaServices } from './services/kibana_services'; export type { CoreStart, CoreSetup }; @@ -125,17 +126,7 @@ export class CanvasPlugin srcPlugin.start(coreStart, startPlugins); - const { pluginServices } = await import('./services'); - const { pluginServiceRegistry } = await import('./services/kibana'); - - pluginServices.setRegistry( - pluginServiceRegistry.start({ - coreStart, - startPlugins, - appUpdater: this.appUpdater, - initContext: this.initContext, - }) - ); + setKibanaServices(coreStart, startPlugins, this.appUpdater, this.initContext); const { expressions, presentationUtil } = startPlugins; await presentationUtil.registerExpressionsLanguage( @@ -154,7 +145,7 @@ export class CanvasPlugin this.appUpdater ); - const unmount = renderApp({ coreStart, startPlugins, params, canvasStore, pluginServices }); + const unmount = renderApp({ coreStart, startPlugins, params, canvasStore }); return () => { unmount(); diff --git a/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts b/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts index e3a8b277d5d7f..0621c3e89416c 100644 --- a/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts @@ -13,12 +13,22 @@ import { fromExpression, getType } from '@kbn/interpreter'; import { pluck } from 'rxjs'; import { buildEmbeddableFilters } from '../../common/lib/build_embeddable_filters'; import { expressionsService } from './kibana_services'; +import { getCanvasNotifyService } from './canvas_notify_service'; +import { getCanvasFiltersService } from './canvas_filters_service'; interface Options { castToRender?: boolean; } class ExpressionsService { + private notifyService; + private filtersService; + + constructor() { + this.notifyService = getCanvasNotifyService(); + this.filtersService = getCanvasFiltersService(); + } + async interpretAst( ast: ExpressionAstExpression, variables: Record, @@ -77,7 +87,7 @@ class ExpressionsService { throw new Error(`Ack! I don't know how to render a '${getType(renderable)}'`); } catch (err) { - this.notify.error(err); + this.notifyService.error(err); throw err; } } @@ -91,8 +101,8 @@ class ExpressionsService { } private async getFilters() { - const filtersList = this.filters.getFilters(); - const context = this.filters.getFiltersContext(); + const filtersList = this.filtersService.getFilters(); + const context = this.filtersService.getFiltersContext(); const filterExpression = filtersList.join(' | '); const filterAST = fromExpression(filterExpression); return await this.interpretAstWithContext(filterAST, null, context); diff --git a/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts index 6e252db689e96..9a4e83d52d1a4 100644 --- a/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts @@ -82,7 +82,7 @@ const sanitizeWorkpad = function (workpad: CanvasWorkpad) { return workpad; }; -export const workpadServiceFactory: () => CanvasWorkpadService = () => { +export const getCanvasWorkpadService: () => CanvasWorkpadService = () => { const getApiPath = function () { return `${API_ROUTE_WORKPAD}`; }; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index fdd4a8fcd83ca..37f88e7c1cded 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -12,6 +12,7 @@ import { getCustomElementService } from './canvas_custom_element_service'; import { getCanvasExpressionService } from './canvas_expressions_service'; import { getCanvasFiltersService } from './canvas_filters_service'; import { getCanvasNotifyService } from './canvas_notify_service'; +import { getCanvasWorkpadService } from './canvas_workpad_service'; export const useCustomElementService = () => { const canvasCustomElementService = useMemo(() => getCustomElementService(), []); @@ -29,5 +30,7 @@ export const useNotifyService = () => { const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); return canvasNotifyService; }; - -export const useWorkpadService = () => (() => pluginServices.getHooks().workpad.useService())(); +export const useWorkpadService = () => { + const canvasWorkpadService = useMemo(() => getCanvasWorkpadService(), []); + return canvasWorkpadService; +}; diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index b47c2f49d3eec..72ae963c609b1 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -48,8 +48,8 @@ const servicesReady$ = new BehaviorSubject(false); export const setKibanaServices = ( kibanaCore: CoreStart, deps: CanvasStartDeps, - initContext: PluginInitializerContext, - appUpdater?: BehaviorSubject + appUpdater: BehaviorSubject, + initContext: PluginInitializerContext ) => { kibanaVersion = initContext.env.packageInfo.version; @@ -69,7 +69,7 @@ export const setKibanaServices = ( navLinksService = { updatePath: (path: string) => { - appUpdater?.next(() => ({ + appUpdater.next(() => ({ defaultPath: `${path}`, })); From 49c8a617f56e7d975ff7ffc3549613d876b603a0 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 1 Oct 2024 14:47:09 -0600 Subject: [PATCH 08/41] Fix data views service hook --- .../components/embeddable_flyout/flyout.tsx | 4 +- .../es_data_view_select.component.tsx | 8 +-- .../es_data_view_select.tsx | 4 +- .../my_workpads/my_workpads.component.tsx | 2 +- .../home/my_workpads/my_workpads.tsx | 2 +- .../my_workpads/workpad_table.component.tsx | 2 +- .../workpad_table_tools.component.tsx | 2 +- .../services/canvas_custom_element_service.ts | 72 +++++++++++-------- .../plugins/canvas/public/services/index.ts | 27 ++++++- 9 files changed, 79 insertions(+), 44 deletions(-) diff --git a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx index d2772a04cdc2e..9d9b87fd3b446 100644 --- a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx +++ b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx @@ -15,7 +15,7 @@ import { getSelectedPage } from '../../state/selectors/workpad'; import { EmbeddableTypes } from '../../../canvas_plugin_src/expression_types/embeddable'; import { embeddableInputToExpression } from '../../../canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression'; import { State } from '../../../types'; -import { useLabsService } from '../../services'; +import { presentationUtilService } from '../../services/kibana_services'; const allowedEmbeddables = { [EmbeddableTypes.map]: (id: string) => { @@ -67,7 +67,7 @@ export const AddEmbeddablePanel: React.FunctionComponent = ({ availableEmbeddables, ...restProps }) => { - const labsService = useLabsService(); + const labsService = useMemo(() => presentationUtilService.labsService, []); const isByValueEnabled = labsService.isProjectEnabled('labs:canvas:byValueEmbeddable'); const dispatch = useDispatch(); diff --git a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx index 4539b1f7274fc..18a98630635cb 100644 --- a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx +++ b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.component.tsx @@ -7,14 +7,12 @@ import React, { FocusEventHandler } from 'react'; import { EuiComboBox } from '@elastic/eui'; -import { DataView } from '@kbn/data-views-plugin/common'; - -type DataViewOption = Pick; +import { DataViewListItem } from '@kbn/data-views-plugin/common'; export interface ESDataViewSelectProps { loading: boolean; value: string; - dataViews: DataViewOption[]; + dataViews: DataViewListItem[]; onChange: (string: string) => void; onBlur: FocusEventHandler | undefined; onFocus: FocusEventHandler | undefined; @@ -31,7 +29,7 @@ export const ESDataViewSelect: React.FunctionComponent = onFocus, onBlur, }) => { - const selectedDataView = dataViews.find((view) => value === view.title) as DataViewOption; + const selectedDataView = dataViews.find((view) => value === view.title); const selectedOption = selectedDataView ? { value: selectedDataView.title, label: selectedDataView.name || selectedDataView.title } diff --git a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx index 271662755d32a..d334544ee62a6 100644 --- a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx +++ b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { DataView } from '@kbn/data-views-plugin/common'; +import { DataViewListItem } from '@kbn/data-views-plugin/common'; import { sortBy } from 'lodash'; import React, { FC, useRef, useState } from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; @@ -20,7 +20,7 @@ type ESDataViewSelectProps = Omit; export const ESDataViewSelect: FC = (props) => { const { value, onChange } = props; - const [dataViews, setDataViews] = useState>>([]); + const [dataViews, setDataViews] = useState([]); const [loading, setLoading] = useState(true); const mounted = useRef(true); const { getDataViews } = useDataViewsService(); diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.component.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.component.tsx index d9e3f0e4e2c99..6f25bbf8720cf 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.component.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.component.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { FoundWorkpad } from '../../../services/workpad'; +import { FoundWorkpad } from '../../../services/canvas_workpad_service'; import { UploadDropzone } from './upload_dropzone'; import { HomeEmptyPrompt } from './empty_prompt'; import { WorkpadTable } from './workpad_table'; diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.tsx index b75c8864ad495..44b3c5938af6c 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.tsx @@ -7,7 +7,7 @@ import React, { useState, useEffect, createContext, Dispatch, SetStateAction } from 'react'; import { useFindWorkpads } from '../hooks'; -import { FoundWorkpad } from '../../../services/workpad'; +import { FoundWorkpad } from '../../../services/canvas_workpad_service'; import { Loading } from '../loading'; import { MyWorkpads as Component } from './my_workpads.component'; diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.component.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.component.tsx index c64ab50ad8a09..f8e349351ba4c 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.component.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.component.tsx @@ -21,7 +21,7 @@ import { import moment from 'moment'; import { RoutingLink } from '../../routing'; -import { FoundWorkpad } from '../../../services/workpad'; +import { FoundWorkpad } from '../../../services/canvas_workpad_service'; import { WorkpadTableTools } from './workpad_table_tools'; import { WorkpadImport } from './workpad_import'; diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table_tools.component.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table_tools.component.tsx index 251a40ff4d45d..148e1973352bc 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table_tools.component.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table_tools.component.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { EuiButton, EuiToolTip, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { ConfirmModal } from '../../confirm_modal'; -import { FoundWorkpad } from '../../../services/workpad'; +import { FoundWorkpad } from '../../../services/canvas_workpad_service'; export interface Props { workpads: FoundWorkpad[]; diff --git a/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts b/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts index 28d233b85c013..04559ee09fa5e 100644 --- a/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts @@ -14,36 +14,48 @@ export interface CustomElementFindResponse { customElements: CustomElement[]; } -export interface CanvasCustomElementService { - create: (customElement: CustomElement) => Promise; - get: (customElementId: string) => Promise; - update: (id: string, element: Partial) => Promise; - remove: (id: string) => Promise; - find: (searchTerm: string) => Promise; +class CanvasCustomElementService { + private apiPath = `${API_ROUTE_CUSTOM_ELEMENT}`; + private http; + + constructor() { + ({ http: this.http } = coreServices); + } + + public async create(customElement: CustomElement) { + this.http.post(this.apiPath, { body: JSON.stringify(customElement), version: '1' }); + } + + public async get(customElementId: string): Promise { + return this.http + .get<{ data: CustomElement }>(`${this.apiPath}/${customElementId}`, { version: '1' }) + .then(({ data: element }) => element); + } + + public async update(id: string, element: Partial) { + this.http.put(`${this.apiPath}/${id}`, { body: JSON.stringify(element), version: '1' }); + } + + public async remove(id: string) { + this.http.delete(`${this.apiPath}/${id}`, { version: '1' }); + } + + public async find(searchTerm: string): Promise { + return this.http.get(`${this.apiPath}/find`, { + query: { + name: searchTerm, + perPage: 10000, + }, + version: '1', + }); + } } -export const getCustomElementService: () => CanvasCustomElementService = () => { - const { http } = coreServices; - const apiPath = `${API_ROUTE_CUSTOM_ELEMENT}`; - - return { - create: (customElement) => - http.post(apiPath, { body: JSON.stringify(customElement), version: '1' }), - get: (customElementId) => - http - .get<{ data: CustomElement }>(`${apiPath}/${customElementId}`, { version: '1' }) - .then(({ data: element }) => element), - update: (id, element) => - http.put(`${apiPath}/${id}`, { body: JSON.stringify(element), version: '1' }), - remove: (id) => http.delete(`${apiPath}/${id}`, { version: '1' }), - find: async (name) => { - return http.get(`${apiPath}/find`, { - query: { - name, - perPage: 10000, - }, - version: '1', - }); - }, - }; +let canvasCustomElementService: CanvasCustomElementService; + +export const getCustomElementService = () => { + if (!canvasCustomElementService) { + canvasCustomElementService = new CanvasCustomElementService(); + } + return canvasCustomElementService; }; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index 37f88e7c1cded..c8fe403dcad0b 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -6,13 +6,15 @@ */ export * from './legacy'; -import { useMemo } from 'react'; +import { useCallback, useMemo } from 'react'; +import { ErrorStrings } from '../../i18n'; import { getCustomElementService } from './canvas_custom_element_service'; import { getCanvasExpressionService } from './canvas_expressions_service'; import { getCanvasFiltersService } from './canvas_filters_service'; import { getCanvasNotifyService } from './canvas_notify_service'; import { getCanvasWorkpadService } from './canvas_workpad_service'; +import { dataViewsService } from './kibana_services'; export const useCustomElementService = () => { const canvasCustomElementService = useMemo(() => getCustomElementService(), []); @@ -34,3 +36,26 @@ export const useWorkpadService = () => { const canvasWorkpadService = useMemo(() => getCanvasWorkpadService(), []); return canvasWorkpadService; }; +export const useDataViewsService = () => { + const notifyService = useNotifyService(); + + const getDataViews = useCallback(async () => { + try { + return await dataViewsService.getIdsWithTitle(); + } catch (e) { + const { esService: strings } = ErrorStrings; + notifyService.error(e, { title: strings.getIndicesFetchErrorMessage() }); + } + return []; + }, [notifyService]); + + const getFields = useCallback(async (dataViewTitle: string) => { + const dataView = await dataViewsService.create({ title: dataViewTitle }); + + return dataView.fields + .filter((field) => !field.name.startsWith('_')) + .map((field) => field.name); + }, []); + + return { getDataViews, getFields }; +}; From d0d28c2a3e9a5553f9285f8a05f7af0203d7491a Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 1 Oct 2024 16:32:50 -0600 Subject: [PATCH 09/41] Make workpad service a class --- .../public/services/canvas_workpad_service.ts | 256 +++++++++--------- 1 file changed, 133 insertions(+), 123 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts index 9a4e83d52d1a4..3fe3e88cb9fa1 100644 --- a/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts @@ -36,21 +36,6 @@ export interface ResolveWorkpadResponse { aliasPurpose?: ResolvedSimpleSavedObject['alias_purpose']; } -export interface CanvasWorkpadService { - get: (id: string) => Promise; - resolve: (id: string) => Promise; - create: (workpad: CanvasWorkpad) => Promise; - import: (workpad: CanvasWorkpad) => Promise; - createFromTemplate: (templateId: string) => Promise; - find: (term: string) => Promise; - remove: (id: string) => Promise; - findTemplates: () => Promise; - update: (id: string, workpad: CanvasWorkpad) => Promise; - updateWorkpad: (id: string, workpad: CanvasWorkpad) => Promise; - updateAssets: (id: string, assets: CanvasWorkpad['assets']) => Promise; - getRuntimeZip: (workpad: CanvasRenderedWorkpad) => Promise; -} - /* Remove any top level keys from the workpad which will be rejected by validation */ @@ -82,114 +67,139 @@ const sanitizeWorkpad = function (workpad: CanvasWorkpad) { return workpad; }; -export const getCanvasWorkpadService: () => CanvasWorkpadService = () => { - const getApiPath = function () { - return `${API_ROUTE_WORKPAD}`; - }; - - return { - get: async (id: string) => { - const workpad = await coreServices.http.get(`${getApiPath()}/${id}`, { version: '1' }); - - return { css: DEFAULT_WORKPAD_CSS, variables: [], ...workpad }; - }, - export: async (id: string) => { - const workpad = await coreServices.http.get>( - `${getApiPath()}/export/${id}`, - { version: '1' } - ); - const { attributes } = workpad; - - return { +class CanvasWorkpadService { + private apiPath = `${API_ROUTE_WORKPAD}`; + private http; + + constructor() { + ({ http: this.http } = coreServices); + } + + public async get(id: string): Promise { + const workpad = await this.http.get(`${this.apiPath}/${id}`, { version: '1' }); + + return { css: DEFAULT_WORKPAD_CSS, variables: [], ...workpad }; + } + + public async export(id: string) { + const workpad = await this.http.get>( + `${this.apiPath}/export/${id}`, + { version: '1' } + ); + const { attributes } = workpad; + + return { + ...workpad, + attributes: { + ...attributes, + css: attributes.css ?? DEFAULT_WORKPAD_CSS, + variables: attributes.variables ?? [], + }, + }; + } + + public async resolve(id: string): Promise { + const { workpad, ...resolveProps } = await this.http.get( + `${this.apiPath}/resolve/${id}`, + { version: '1' } + ); + + return { + ...resolveProps, + workpad: { + // @ts-ignore: Shimming legacy workpads that might not have CSS + css: DEFAULT_WORKPAD_CSS, + // @ts-ignore: Shimming legacy workpads that might not have variables + variables: [], ...workpad, - attributes: { - ...attributes, - css: attributes.css ?? DEFAULT_WORKPAD_CSS, - variables: attributes.variables ?? [], - }, - }; - }, - resolve: async (id: string) => { - const { workpad, ...resolveProps } = await coreServices.http.get( - `${getApiPath()}/resolve/${id}`, - { version: '1' } - ); - - return { - ...resolveProps, - workpad: { - // @ts-ignore: Shimming legacy workpads that might not have CSS - css: DEFAULT_WORKPAD_CSS, - // @ts-ignore: Shimming legacy workpads that might not have variables - variables: [], - ...workpad, - }, - }; - }, - create: (workpad: CanvasWorkpad) => { - return coreServices.http.post(getApiPath(), { - body: JSON.stringify({ - ...sanitizeWorkpad({ ...workpad }), - assets: workpad.assets || {}, - variables: workpad.variables || [], - }), - version: '1', - }); - }, - import: (workpad: CanvasWorkpad) => - coreServices.http.post(`${getApiPath()}/import`, { - body: JSON.stringify({ - ...sanitizeWorkpad({ ...workpad }), - assets: workpad.assets || {}, - variables: workpad.variables || [], - }), - version: '1', + }, + }; + } + + public async create(workpad: CanvasWorkpad): Promise { + return this.http.post(this.apiPath, { + body: JSON.stringify({ + ...sanitizeWorkpad({ ...workpad }), + assets: workpad.assets || {}, + variables: workpad.variables || [], + }), + version: '1', + }); + } + + public async import(workpad: CanvasWorkpad): Promise { + return this.http.post(`${this.apiPath}/import`, { + body: JSON.stringify({ + ...sanitizeWorkpad({ ...workpad }), + assets: workpad.assets || {}, + variables: workpad.variables || [], }), - createFromTemplate: (templateId: string) => { - return coreServices.http.post(getApiPath(), { - body: JSON.stringify({ templateId }), - version: '1', - }); - }, - findTemplates: async () => coreServices.http.get(API_ROUTE_TEMPLATES, { version: '1' }), - find: (searchTerm: string) => { - // TODO: this shouldn't be necessary. Check for usage. - const validSearchTerm = typeof searchTerm === 'string' && searchTerm.length > 0; - - return coreServices.http.get(`${getApiPath()}/find`, { - query: { - perPage: 10000, - name: validSearchTerm ? searchTerm : '', - }, - version: '1', - }); - }, - remove: (id: string) => { - return coreServices.http.delete(`${getApiPath()}/${id}`, { version: '1' }); - }, - update: (id, workpad) => { - return coreServices.http.put(`${getApiPath()}/${id}`, { - body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }), - version: '1', - }); - }, - updateWorkpad: (id, workpad) => { - return coreServices.http.put(`${API_ROUTE_WORKPAD_STRUCTURES}/${id}`, { - body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }), - version: '1', - }); - }, - updateAssets: (id, assets) => { - return coreServices.http.put(`${API_ROUTE_WORKPAD_ASSETS}/${id}`, { - body: JSON.stringify(assets), - version: '1', - }); - }, - getRuntimeZip: (workpad) => { - return coreServices.http.post(API_ROUTE_SHAREABLE_ZIP, { - body: JSON.stringify(workpad), - version: '1', - }); - }, - }; + version: '1', + }); + } + + public async createFromTemplate(templateId: string): Promise { + return this.http.post(this.apiPath, { + body: JSON.stringify({ templateId }), + version: '1', + }); + } + + public async findTemplates(): Promise { + return this.http.get(API_ROUTE_TEMPLATES, { version: '1' }); + } + + public async find(searchTerm: string): Promise { + // TODO: this shouldn't be necessary. Check for usage. + const validSearchTerm = typeof searchTerm === 'string' && searchTerm.length > 0; + + return this.http.get(`${this.apiPath}/find`, { + query: { + perPage: 10000, + name: validSearchTerm ? searchTerm : '', + }, + version: '1', + }); + } + + public async remove(id: string) { + this.http.delete(`${this.apiPath}/${id}`, { version: '1' }); + } + + public async update(id: string, workpad: CanvasWorkpad) { + this.http.put(`${this.apiPath}/${id}`, { + body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }), + version: '1', + }); + } + + public async updateWorkpad(id: string, workpad: CanvasWorkpad) { + this.http.put(`${API_ROUTE_WORKPAD_STRUCTURES}/${id}`, { + body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }), + version: '1', + }); + } + + public async updateAssets(id: string, assets: CanvasWorkpad['assets']) { + this.http.put(`${API_ROUTE_WORKPAD_ASSETS}/${id}`, { + body: JSON.stringify(assets), + version: '1', + }); + } + + public async getRuntimeZip(workpad: CanvasRenderedWorkpad): Promise { + return this.http.post(API_ROUTE_SHAREABLE_ZIP, { + body: JSON.stringify(workpad), + version: '1', + }); + } +} + +let canvasWorkpadService: CanvasWorkpadService; + +export const getCanvasWorkpadService: () => CanvasWorkpadService = () => { + if (!canvasWorkpadService) { + canvasWorkpadService = new CanvasWorkpadService(); + } + return canvasWorkpadService; }; From 258fc97bf83bf6ef63dd66590b682eefce1a0347 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 2 Oct 2024 09:14:08 -0600 Subject: [PATCH 10/41] Fix workpad service --- .../canvas/public/routes/workpad/hooks/use_workpad.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts index 40ab8d17d491c..45e077c25166a 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts @@ -34,7 +34,6 @@ export const useWorkpad = ( getRedirectPath: (workpadId: string) => string ): [CanvasWorkpad | undefined, string | Error | undefined] => { const workpadService = useWorkpadService(); - const workpadResolve = workpadService.resolve; const dispatch = useDispatch(); const storedWorkpad = useSelector(getWorkpad); const [error, setError] = useState(undefined); @@ -47,7 +46,7 @@ export const useWorkpad = ( const { workpad: { assets, ...workpad }, ...resolveProps - } = await workpadResolve(workpadId); + } = await workpadService.resolve(workpadId); setResolveInfo({ id: workpadId, ...resolveProps }); @@ -63,7 +62,7 @@ export const useWorkpad = ( setError(e as Error | string); } })(); - }, [workpadId, dispatch, setError, loadPages, workpadResolve, storedWorkpad.id]); + }, [workpadId, dispatch, setError, loadPages, workpadService, storedWorkpad.id]); useEffect(() => { // If the resolved info is not for the current workpad id, bail out From c5ada399753c73cc6aa3cb5bc16514b807cce6a9 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 2 Oct 2024 10:21:23 -0600 Subject: [PATCH 11/41] Trying to fix storybooks --- .../public/components/home/home.stories.tsx | 2 +- .../home/my_workpads/my_workpads.stories.tsx | 2 +- .../my_workpads/workpad_table.stories.tsx | 4 +- .../workpad_templates.stories.tsx | 2 +- .../canvas/public/services/kibana_services.ts | 4 +- .../plugins/canvas/public/services/mocks.ts | 127 ++++++++++++++++++ x-pack/plugins/canvas/storybook/constants.ts | 31 +++++ .../decorators/services_decorator.tsx | 23 +--- 8 files changed, 169 insertions(+), 26 deletions(-) create mode 100644 x-pack/plugins/canvas/public/services/mocks.ts diff --git a/x-pack/plugins/canvas/public/components/home/home.stories.tsx b/x-pack/plugins/canvas/public/components/home/home.stories.tsx index 0130f9f3f894b..cfebd509c80ef 100644 --- a/x-pack/plugins/canvas/public/components/home/home.stories.tsx +++ b/x-pack/plugins/canvas/public/components/home/home.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { reduxDecorator } from '../../../storybook'; -import { argTypes } from '../../services/storybook'; +import { argTypes } from '../../../storybook/constants'; import { Home } from './home'; diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.stories.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.stories.tsx index 52afd552bbc49..967419e9b8b06 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.stories.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/my_workpads.stories.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { EuiPanel } from '@elastic/eui'; import { reduxDecorator } from '../../../../storybook'; -import { argTypes } from '../../../services/storybook'; +import { argTypes } from '../../../../storybook/constants'; import { MyWorkpads as Component } from './my_workpads'; diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.stories.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.stories.tsx index 6675dea238cc4..f9418f35e6256 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.stories.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/workpad_table.stories.tsx @@ -9,9 +9,9 @@ import React, { useState, useEffect } from 'react'; import { EuiPanel } from '@elastic/eui'; import { reduxDecorator } from '../../../../storybook'; +import { argTypes } from '../../../../storybook/constants'; -import { argTypes } from '../../../services/storybook'; -import { getSomeWorkpads } from '../../../services/stubs/workpad'; +import { getSomeWorkpads } from '../../../services/mocks'; import { WorkpadTable as Component } from './workpad_table'; import { WorkpadsContext } from './my_workpads'; diff --git a/x-pack/plugins/canvas/public/components/home/workpad_templates/workpad_templates.stories.tsx b/x-pack/plugins/canvas/public/components/home/workpad_templates/workpad_templates.stories.tsx index 92583ca845aa8..c6a3347f6c39a 100644 --- a/x-pack/plugins/canvas/public/components/home/workpad_templates/workpad_templates.stories.tsx +++ b/x-pack/plugins/canvas/public/components/home/workpad_templates/workpad_templates.stories.tsx @@ -9,7 +9,7 @@ import { EuiPanel } from '@elastic/eui'; import React from 'react'; import { reduxDecorator } from '../../../../storybook'; -import { argTypes } from '../../../services/storybook'; +import { argTypes } from '../../../../storybook/constants'; import { WorkpadTemplates as Component } from './workpad_templates'; diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index 72ae963c609b1..f53b1044fe37c 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -32,9 +32,9 @@ export let kibanaVersion: string; export let coreServices: CoreStart; export let contentManagementService: ContentManagementPublicStart; export let dataService: DataPublicPluginStart; -export let expressionsService: ExpressionsStart; export let dataViewsService: DataViewsPublicPluginStart; export let embeddableService: EmbeddableStart; +export let expressionsService: ExpressionsStart; export let presentationUtilService: PresentationUtilPluginStart; export let reportingService: ReportingStart | undefined; export let spacesService: SpacesApi | undefined; @@ -56,9 +56,9 @@ export const setKibanaServices = ( coreServices = kibanaCore; contentManagementService = deps.contentManagement; dataService = deps.data; - expressionsService = deps.expressions; dataViewsService = deps.dataViews; embeddableService = deps.embeddable; + expressionsService = deps.expressions; presentationUtilService = deps.presentationUtil; reportingService = kibanaCore.application.capabilities.canvas?.generatePdf ? deps.reporting diff --git a/x-pack/plugins/canvas/public/services/mocks.ts b/x-pack/plugins/canvas/public/services/mocks.ts new file mode 100644 index 0000000000000..43abd8cb2d41c --- /dev/null +++ b/x-pack/plugins/canvas/public/services/mocks.ts @@ -0,0 +1,127 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { BehaviorSubject } from 'rxjs'; +import moment from 'moment'; + +import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; +import { contentManagementMock } from '@kbn/content-management-plugin/public/mocks'; +import { AppUpdater, CoreStart } from '@kbn/core/public'; +import { coreMock } from '@kbn/core/public/mocks'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks'; +import { expressionsPluginMock } from '@kbn/expressions-plugin/public/mocks'; +import { inspectorPluginMock } from '@kbn/inspector-plugin/public/mocks'; +import { presentationUtilPluginMock } from '@kbn/presentation-util-plugin/public/mocks'; +import { reportingPluginMock } from '@kbn/reporting-plugin/public/mocks'; +import { spacesPluginMock } from '@kbn/spaces-plugin/public/mocks'; +import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; +import { visualizationsPluginMock } from '@kbn/visualizations-plugin/public/mocks'; + +import { setKibanaServices } from './kibana_services'; +import { getId } from '../lib/get_id'; +// @ts-expect-error +import { getDefaultWorkpad } from '../state/defaults'; + +const setDefaultPresentationUtilCapabilities = (core: CoreStart) => { + core.application.capabilities = { + ...core.application.capabilities, + dashboard: { + show: true, + createNew: true, + }, + visualize: { + save: true, + }, + advancedSettings: { + save: true, + }, + }; +}; + +export const setStubKibanaServices = () => { + const core: CoreStart = coreMock.createStart(); + + setDefaultPresentationUtilCapabilities(core); + setKibanaServices( + core, + { + charts: chartPluginMock.createStartContract(), + contentManagement: contentManagementMock.createStartContract(), + data: dataPluginMock.createStartContract(), + dataViews: dataViewPluginMocks.createStartContract(), + embeddable: embeddablePluginMock.createStartContract(), + expressions: expressionsPluginMock.createStartContract(), + inspector: inspectorPluginMock.createStartContract(), + presentationUtil: presentationUtilPluginMock.createStartContract(core), + reporting: reportingPluginMock.createStartContract(), + spaces: spacesPluginMock.createStartContract(), + uiActions: uiActionsPluginMock.createStartContract(), + visualizations: visualizationsPluginMock.createStartContract(), + }, + new BehaviorSubject(() => ({})), + coreMock.createPluginInitializerContext() + ); +}; + +const TIMEOUT = 500; + +export const getSomeWorkpads = (count = 3, useStaticData = false) => { + if (useStaticData) { + const DAY = 86400000; + const JAN_1_2000 = 946684800000; + + const workpads = []; + for (let i = 0; i < count; i++) { + workpads[i] = { + ...getDefaultWorkpad(), + name: `Workpad ${i}`, + id: `workpad-${i}`, + '@created': moment(JAN_1_2000 + DAY * i).toDate(), + '@timestamp': moment(JAN_1_2000 + DAY * (i + 1)).toDate(), + }; + } + return workpads; + } else { + return Array.from({ length: count }, () => ({ + '@created': getRandomDate( + moment().subtract(3, 'days').toDate(), + moment().subtract(10, 'days').toDate() + ), + '@timestamp': getRandomDate(), + id: getId('workpad'), + name: getRandomName(), + })); + } +}; + +export const findSomeWorkpads = + (count = 3, useStaticData = false, timeout = TIMEOUT) => + (_term: string) => { + return Promise.resolve() + .then(promiseTimeout(timeout)) + .then(() => ({ + total: count, + workpads: getSomeWorkpads(count, useStaticData), + })); + }; + +const promiseTimeout = (time: number) => () => new Promise((resolve) => setTimeout(resolve, time)); + +const getRandomName = () => { + const lorem = + 'Lorem ipsum dolor sit amet consectetur adipiscing elit Fusce lobortis aliquet arcu ut turpis duis'.split( + ' ' + ); + return [1, 2, 3].map(() => lorem[Math.floor(Math.random() * lorem.length)]).join(' '); +}; + +const getRandomDate = ( + start: Date = moment().toDate(), + end: Date = moment().subtract(7, 'days').toDate() +) => new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())).toISOString(); diff --git a/x-pack/plugins/canvas/storybook/constants.ts b/x-pack/plugins/canvas/storybook/constants.ts index 711b939179452..4f0ad2a602da0 100644 --- a/x-pack/plugins/canvas/storybook/constants.ts +++ b/x-pack/plugins/canvas/storybook/constants.ts @@ -8,3 +8,34 @@ import path from 'path'; export const KIBANA_ROOT = path.resolve(__dirname, '../../../..'); + +export const argTypes = { + hasTemplates: { + name: 'Has templates?', + type: { + name: 'boolean', + }, + defaultValue: true, + control: { + type: 'boolean', + }, + }, + useStaticData: { + name: 'Use static data?', + type: { + name: 'boolean', + }, + defaultValue: false, + control: { + type: 'boolean', + }, + }, + workpadCount: { + name: 'Number of workpads', + type: { name: 'number' }, + defaultValue: 5, + control: { + type: 'range', + }, + }, +}; diff --git a/x-pack/plugins/canvas/storybook/decorators/services_decorator.tsx b/x-pack/plugins/canvas/storybook/decorators/services_decorator.tsx index 4c610a943a1f2..c99f5df184cd4 100644 --- a/x-pack/plugins/canvas/storybook/decorators/services_decorator.tsx +++ b/x-pack/plugins/canvas/storybook/decorators/services_decorator.tsx @@ -10,36 +10,21 @@ import React from 'react'; import { DecoratorFn } from '@storybook/react'; import { I18nProvider } from '@kbn/i18n-react'; -import { PluginServiceRegistry } from '@kbn/presentation-util-plugin/public'; -import { pluginServices, CanvasPluginServices } from '../../public/services'; -import { pluginServiceProviders, StorybookParams } from '../../public/services/storybook'; import { LegacyServicesProvider } from '../../public/services/legacy'; -import { startServices } from '../../public/services/legacy/stubs'; +import { setStubKibanaServices } from '../../public/services/mocks'; export const servicesContextDecorator = (): DecoratorFn => { - const pluginServiceRegistry = new PluginServiceRegistry( - pluginServiceProviders - ); - - pluginServices.setRegistry(pluginServiceRegistry.start({})); - return (story: Function, storybook) => { if (process.env.JEST_WORKER_ID !== undefined) { storybook.args.useStaticData = true; } - pluginServices.setRegistry(pluginServiceRegistry.start(storybook.args)); - const ContextProvider = pluginServices.getContextProvider(); - - return ( - - {story()} - - ); + return {story()}; }; }; export const legacyContextDecorator = () => { - startServices(); + setStubKibanaServices(); + return (story: Function) => {story()}; }; From 4a9d90f99bff0d7e32f08198d6662b371026c932 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 2 Oct 2024 12:11:43 -0600 Subject: [PATCH 12/41] Move hooks --- .../asset_manager/asset.component.tsx | 2 +- .../datasource/datasource_preview/index.js | 2 +- .../components/element_content/index.tsx | 2 +- .../es_data_view_select.tsx | 2 +- .../components/es_field_select/index.tsx | 2 +- .../es_fields_select/es_fields_select.tsx | 2 +- .../public/components/expression/index.tsx | 2 +- .../public/components/function_form/index.tsx | 2 +- .../home/hooks/use_clone_workpad.ts | 2 +- .../home/hooks/use_create_from_template.ts | 2 +- .../home/hooks/use_create_workpad.ts | 2 +- .../home/hooks/use_delete_workpad.ts | 2 +- .../home/hooks/use_find_templates.ts | 2 +- .../components/home/hooks/use_find_workpad.ts | 2 +- .../home/hooks/use_import_workpad.ts | 2 +- .../home/hooks/use_upload_workpad.ts | 2 +- .../home/my_workpads/upload_dropzone.tsx | 2 +- .../hooks/workpad/use_download_workpad.ts | 2 +- .../hooks/workpad/use_incoming_embeddable.ts | 2 +- .../render_with_fn/render_with_fn.tsx | 2 +- .../saved_elements_modal.tsx | 2 +- .../public/components/var_config/index.tsx | 2 +- .../hooks/use_canvas_filters.ts | 2 +- .../share_menu/flyout/flyout.component.tsx | 2 +- .../flyout/hooks/use_download_runtime.ts | 2 +- x-pack/plugins/canvas/public/plugin.tsx | 3 +- .../routes/workpad/hooks/use_workpad.ts | 2 +- .../workpad/hooks/use_workpad_persist.ts | 2 +- .../public/routes/workpad/workpad_route.tsx | 2 +- .../plugins/canvas/public/services/hooks.ts | 61 +++++++++++++++++++ .../plugins/canvas/public/services/index.ts | 53 ---------------- 31 files changed, 90 insertions(+), 83 deletions(-) create mode 100644 x-pack/plugins/canvas/public/services/hooks.ts diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx b/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx index 024137f640636..fc144c313e4a3 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx @@ -19,7 +19,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useNotifyService } from '../../services'; +import { useNotifyService } from '../../services/hooks'; import { ConfirmModal } from '../confirm_modal'; import { Clipboard } from '../clipboard'; diff --git a/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js b/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js index 1ca674bfb6f9d..e85f19b19d700 100644 --- a/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js +++ b/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js @@ -8,7 +8,7 @@ import React, { useState, useEffect } from 'react'; import { PropTypes } from 'prop-types'; import { Loading } from '../../loading'; -import { useExpressionsService } from '../../../services'; +import { useExpressionsService } from '../../../services/hooks'; import { DatasourcePreview as Component } from './datasource_preview'; export const DatasourcePreview = (props) => { diff --git a/x-pack/plugins/canvas/public/components/element_content/index.tsx b/x-pack/plugins/canvas/public/components/element_content/index.tsx index bdbfc205d4c81..bb333062f144b 100644 --- a/x-pack/plugins/canvas/public/components/element_content/index.tsx +++ b/x-pack/plugins/canvas/public/components/element_content/index.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { getSelectedPage, getPageById } from '../../state/selectors/workpad'; -import { useExpressionsService } from '../../services'; +import { useExpressionsService } from '../../services/hooks'; import { ElementContent as Component, Props as ComponentProps } from './element_content'; import { State } from '../../../types'; diff --git a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx index d334544ee62a6..036373caceb18 100644 --- a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx +++ b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx @@ -9,7 +9,7 @@ import { DataViewListItem } from '@kbn/data-views-plugin/common'; import { sortBy } from 'lodash'; import React, { FC, useRef, useState } from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { useDataViewsService } from '../../services'; +import { useDataViewsService } from '../../services/hooks'; import { ESDataViewSelect as Component, ESDataViewSelectProps as Props, diff --git a/x-pack/plugins/canvas/public/components/es_field_select/index.tsx b/x-pack/plugins/canvas/public/components/es_field_select/index.tsx index 653eec22d77d9..6fbaf70e751ba 100644 --- a/x-pack/plugins/canvas/public/components/es_field_select/index.tsx +++ b/x-pack/plugins/canvas/public/components/es_field_select/index.tsx @@ -6,7 +6,7 @@ */ import React, { useState, useEffect, useRef } from 'react'; -import { useDataViewsService } from '../../services'; +import { useDataViewsService } from '../../services/hooks'; import { ESFieldSelect as Component, ESFieldSelectProps as Props } from './es_field_select'; type ESFieldSelectProps = Omit; diff --git a/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx b/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx index c929203f9e094..bb13662b3791d 100644 --- a/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx +++ b/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx @@ -8,7 +8,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { isEqual } from 'lodash'; import usePrevious from 'react-use/lib/usePrevious'; -import { useDataViewsService } from '../../services'; +import { useDataViewsService } from '../../services/hooks'; import { ESFieldsSelect as Component, ESFieldsSelectProps as Props, diff --git a/x-pack/plugins/canvas/public/components/expression/index.tsx b/x-pack/plugins/canvas/public/components/expression/index.tsx index 37bbbd1f5a4c1..7b0bad223017a 100644 --- a/x-pack/plugins/canvas/public/components/expression/index.tsx +++ b/x-pack/plugins/canvas/public/components/expression/index.tsx @@ -8,7 +8,7 @@ import React, { FC, useState, useCallback, useMemo, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { fromExpression } from '@kbn/interpreter'; -import { useExpressionsService } from '../../services'; +import { useExpressionsService } from '../../services/hooks'; import { getSelectedPage, getSelectedElement } from '../../state/selectors/workpad'; // @ts-expect-error import { setExpression, flushContext } from '../../state/actions/elements'; diff --git a/x-pack/plugins/canvas/public/components/function_form/index.tsx b/x-pack/plugins/canvas/public/components/function_form/index.tsx index 46da2403c22b7..308d6dffc63b0 100644 --- a/x-pack/plugins/canvas/public/components/function_form/index.tsx +++ b/x-pack/plugins/canvas/public/components/function_form/index.tsx @@ -34,7 +34,7 @@ import { findExistingAsset } from '../../lib/find_existing_asset'; import { FunctionForm as Component } from './function_form'; import { Args, ArgType, ArgTypeDef } from '../../expression_types/types'; import { State, ExpressionContext, CanvasElement, AssetType } from '../../../types'; -import { useWorkpadService } from '../../services'; +import { useWorkpadService } from '../../services/hooks'; import { createAsset, notifyError } from '../../lib/assets'; interface FunctionFormProps { diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts index 001a711a58a72..f398b9a0e0602 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts @@ -9,7 +9,7 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService, useWorkpadService } from '../../../services/hooks'; import { getId } from '../../../lib/get_id'; export const useCloneWorkpad = () => { diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts index 968f9398ba857..0f5dcdca27cb9 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts @@ -9,7 +9,7 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { CanvasTemplate } from '../../../../types'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService, useWorkpadService } from '../../../services/hooks'; export const useCreateFromTemplate = () => { const workpadService = useWorkpadService(); diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts index 3290bc8227a29..83b8a533fcf70 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; // @ts-expect-error import { getDefaultWorkpad } from '../../../state/defaults'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService, useWorkpadService } from '../../../services/hooks'; import type { CanvasWorkpad } from '../../../../types'; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts index 3143b19fa8130..f9e51b49276a3 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts @@ -8,7 +8,7 @@ import { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { useWorkpadService } from '../../../services'; +import { useWorkpadService } from '../../../services/hooks'; import { getCanvasNotifyService } from '../../../services/canvas_notify_service'; export const useDeleteWorkpads = () => { diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts index 9364a79987908..e0d0f48f483b2 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts @@ -7,7 +7,7 @@ import { useCallback } from 'react'; -import { useWorkpadService } from '../../../services'; +import { useWorkpadService } from '../../../services/hooks'; export const useFindTemplates = () => { const workpadService = useWorkpadService(); diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts index 10352d0472e8c..f410c60882b8d 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts @@ -8,7 +8,7 @@ import { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService, useWorkpadService } from '../../../services/hooks'; export const useFindWorkpads = () => { const workpadService = useWorkpadService(); diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts index bd780ee01507d..959e04192d111 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts @@ -9,7 +9,7 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService, useWorkpadService } from '../../../services/hooks'; import type { CanvasWorkpad } from '../../../../types'; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts index 3a9865b3cff29..d17f19680ab32 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { SavedObject } from '@kbn/core/public'; import { CANVAS, JSON as JSONString } from '../../../../i18n/constants'; -import { useNotifyService } from '../../../services'; +import { useNotifyService } from '../../../services/hooks'; import { getId } from '../../../lib/get_id'; import { useImportWorkpad as useImportWorkpadHook } from './use_import_workpad'; import type { CanvasWorkpad } from '../../../../types'; diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx index 10ba1c3e06b70..c2994f77ba348 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx @@ -7,7 +7,7 @@ import React, { FC, PropsWithChildren, useState } from 'react'; -import { useNotifyService } from '../../../services'; +import { useNotifyService } from '../../../services/hooks'; import { ErrorStrings } from '../../../../i18n'; import { useImportWorkpad } from '../hooks'; diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts index dadf03a8fac5a..9228b09795945 100644 --- a/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts @@ -8,7 +8,7 @@ import { useCallback } from 'react'; import fileSaver from 'file-saver'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService, useWorkpadService } from '../../../services/hooks'; import { CanvasWorkpad } from '../../../../types'; import type { CanvasRenderedWorkpad } from '../../../../shareable_runtime/types'; diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts index 50c3e527bbbae..9587f803bb2ef 100644 --- a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts @@ -12,7 +12,7 @@ import { ErrorStrings } from '../../../../i18n'; import { CANVAS_APP } from '../../../../common/lib'; import { decode } from '../../../../common/lib/embeddable_dataurl'; import { CanvasElement, CanvasPage } from '../../../../types'; -import { useNotifyService } from '../../../services'; +import { useNotifyService } from '../../../services/hooks'; // @ts-expect-error unconverted file import { addElement, fetchAllRenderables } from '../../../state/actions/elements'; // @ts-expect-error unconverted file diff --git a/x-pack/plugins/canvas/public/components/render_with_fn/render_with_fn.tsx b/x-pack/plugins/canvas/public/components/render_with_fn/render_with_fn.tsx index a48bef994dd9d..e540fbba4ce2a 100644 --- a/x-pack/plugins/canvas/public/components/render_with_fn/render_with_fn.tsx +++ b/x-pack/plugins/canvas/public/components/render_with_fn/render_with_fn.tsx @@ -9,7 +9,7 @@ import React, { useState, useEffect, useRef, FC, useCallback } from 'react'; import { isEqual } from 'lodash'; -import { useNotifyService } from '../../services'; +import { useNotifyService } from '../../services/hooks'; import { RenderToDom } from '../render_to_dom'; import { ErrorStrings } from '../../../i18n'; import { RendererHandlers } from '../../../types'; diff --git a/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx b/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx index 19e786edfd5fb..08eeef0fbd0a4 100644 --- a/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx +++ b/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx @@ -9,7 +9,7 @@ import React, { useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { camelCase } from 'lodash'; import { cloneSubgraphs } from '../../lib/clone_subgraphs'; -import { useNotifyService, useCustomElementService } from '../../services'; +import { useNotifyService, useCustomElementService } from '../../services/hooks'; // @ts-expect-error untyped local import { selectToplevelNodes } from '../../state/actions/transient'; // @ts-expect-error untyped local diff --git a/x-pack/plugins/canvas/public/components/var_config/index.tsx b/x-pack/plugins/canvas/public/components/var_config/index.tsx index db2a84e93a5dc..9fc2fa4991547 100644 --- a/x-pack/plugins/canvas/public/components/var_config/index.tsx +++ b/x-pack/plugins/canvas/public/components/var_config/index.tsx @@ -10,7 +10,7 @@ import copy from 'copy-to-clipboard'; import { i18n } from '@kbn/i18n'; import { VarConfig as ChildComponent } from './var_config'; -import { useNotifyService } from '../../services'; +import { useNotifyService } from '../../services/hooks'; import { CanvasVariable } from '../../../types'; const strings = { diff --git a/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts b/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts index bdccc8040c5de..3848e34f2268e 100644 --- a/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts +++ b/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts @@ -10,7 +10,7 @@ import { shallowEqual, useSelector } from 'react-redux'; import { State } from '../../../../types'; import { getFiltersByFilterExpressions } from '../../../lib/filter'; import { adaptCanvasFilter } from '../../../lib/filter_adapters'; -import { useFiltersService } from '../../../services'; +import { useFiltersService } from '../../../services/hooks'; const extractExpressionAST = (filters: string[]) => fromExpression(filters.join(' | ')); diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/flyout.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/flyout.component.tsx index 57a8a90ce160c..34b567150c4d9 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/flyout.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/flyout.component.tsx @@ -32,7 +32,7 @@ import { OnCloseFn } from '../share_menu.component'; import { WorkpadStep } from './workpad_step'; import { RuntimeStep } from './runtime_step'; import { SnippetsStep } from './snippets_step'; -import { useNotifyService } from '../../../../services'; +import { useNotifyService } from '../../../../services/hooks'; const strings = { getCopyShareConfigMessage: () => diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts index 27b93269f4352..8e688d1d02e87 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts @@ -12,7 +12,7 @@ import { API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD } from '../../../../../../common/l import { ZIP } from '../../../../../../i18n/constants'; import type { CanvasRenderedWorkpad } from '../../../../../../shareable_runtime/types'; -import { useNotifyService, useWorkpadService } from '../../../../../services'; +import { useNotifyService, useWorkpadService } from '../../../../../services/hooks'; import { coreServices } from '../../../../../services/kibana_services'; const strings = { diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx index 666cb28a4806a..4cdeb30a4aa66 100644 --- a/x-pack/plugins/canvas/public/plugin.tsx +++ b/x-pack/plugins/canvas/public/plugin.tsx @@ -126,8 +126,6 @@ export class CanvasPlugin srcPlugin.start(coreStart, startPlugins); - setKibanaServices(coreStart, startPlugins, this.appUpdater, this.initContext); - const { expressions, presentationUtil } = startPlugins; await presentationUtil.registerExpressionsLanguage( Object.values(expressions.getFunctions()) @@ -181,6 +179,7 @@ export class CanvasPlugin } public start(coreStart: CoreStart, startPlugins: CanvasStartDeps) { + setKibanaServices(coreStart, startPlugins, this.appUpdater, this.initContext); initLoadingIndicator(coreStart.http.addLoadingCountSource); } } diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts index 45e077c25166a..f81499b41c68d 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts @@ -8,7 +8,7 @@ import { useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { useDispatch, useSelector } from 'react-redux'; -import { useWorkpadService } from '../../../services'; +import { useWorkpadService } from '../../../services/hooks'; import { getWorkpad } from '../../../state/selectors/workpad'; import { setWorkpad } from '../../../state/actions/workpad'; // @ts-expect-error diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts index f63d3bf8e32a1..cc2ab9be52543 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts @@ -10,7 +10,7 @@ import { useSelector } from 'react-redux'; import { CanvasWorkpad, State } from '../../../../types'; import { getWorkpad } from '../../../state/selectors/workpad'; import { canUserWrite } from '../../../state/selectors/app'; -import { useWorkpadService } from '../../../services'; +import { useWorkpadService } from '../../../services/hooks'; import { notifyError } from '../../../lib/assets'; export const useWorkpadPersist = () => { diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx index 733a0b2d2b9af..93da523dc93ae 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx @@ -14,7 +14,7 @@ import { ExportApp } from '../../components/export_app'; import { CanvasLoading } from '../../components/canvas_loading'; // @ts-expect-error import { fetchAllRenderables } from '../../state/actions/elements'; -import { useNotifyService } from '../../services'; +import { useNotifyService } from '../../services/hooks'; import { CanvasWorkpad } from '../../../types'; import { ErrorStrings } from '../../../i18n'; import { useWorkpad } from './hooks/use_workpad'; diff --git a/x-pack/plugins/canvas/public/services/hooks.ts b/x-pack/plugins/canvas/public/services/hooks.ts new file mode 100644 index 0000000000000..c8fe403dcad0b --- /dev/null +++ b/x-pack/plugins/canvas/public/services/hooks.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './legacy'; +import { useCallback, useMemo } from 'react'; + +import { ErrorStrings } from '../../i18n'; +import { getCustomElementService } from './canvas_custom_element_service'; +import { getCanvasExpressionService } from './canvas_expressions_service'; +import { getCanvasFiltersService } from './canvas_filters_service'; +import { getCanvasNotifyService } from './canvas_notify_service'; +import { getCanvasWorkpadService } from './canvas_workpad_service'; +import { dataViewsService } from './kibana_services'; + +export const useCustomElementService = () => { + const canvasCustomElementService = useMemo(() => getCustomElementService(), []); + return canvasCustomElementService; +}; +export const useExpressionsService = () => { + const canvasExpressionService = useMemo(() => getCanvasExpressionService(), []); + return canvasExpressionService; +}; +export const useFiltersService = () => { + const canvasFiltersService = useMemo(() => getCanvasFiltersService(), []); + return canvasFiltersService; +}; +export const useNotifyService = () => { + const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); + return canvasNotifyService; +}; +export const useWorkpadService = () => { + const canvasWorkpadService = useMemo(() => getCanvasWorkpadService(), []); + return canvasWorkpadService; +}; +export const useDataViewsService = () => { + const notifyService = useNotifyService(); + + const getDataViews = useCallback(async () => { + try { + return await dataViewsService.getIdsWithTitle(); + } catch (e) { + const { esService: strings } = ErrorStrings; + notifyService.error(e, { title: strings.getIndicesFetchErrorMessage() }); + } + return []; + }, [notifyService]); + + const getFields = useCallback(async (dataViewTitle: string) => { + const dataView = await dataViewsService.create({ title: dataViewTitle }); + + return dataView.fields + .filter((field) => !field.name.startsWith('_')) + .map((field) => field.name); + }, []); + + return { getDataViews, getFields }; +}; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index c8fe403dcad0b..13450be8e5b8a 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -6,56 +6,3 @@ */ export * from './legacy'; -import { useCallback, useMemo } from 'react'; - -import { ErrorStrings } from '../../i18n'; -import { getCustomElementService } from './canvas_custom_element_service'; -import { getCanvasExpressionService } from './canvas_expressions_service'; -import { getCanvasFiltersService } from './canvas_filters_service'; -import { getCanvasNotifyService } from './canvas_notify_service'; -import { getCanvasWorkpadService } from './canvas_workpad_service'; -import { dataViewsService } from './kibana_services'; - -export const useCustomElementService = () => { - const canvasCustomElementService = useMemo(() => getCustomElementService(), []); - return canvasCustomElementService; -}; -export const useExpressionsService = () => { - const canvasExpressionService = useMemo(() => getCanvasExpressionService(), []); - return canvasExpressionService; -}; -export const useFiltersService = () => { - const canvasFiltersService = useMemo(() => getCanvasFiltersService(), []); - return canvasFiltersService; -}; -export const useNotifyService = () => { - const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); - return canvasNotifyService; -}; -export const useWorkpadService = () => { - const canvasWorkpadService = useMemo(() => getCanvasWorkpadService(), []); - return canvasWorkpadService; -}; -export const useDataViewsService = () => { - const notifyService = useNotifyService(); - - const getDataViews = useCallback(async () => { - try { - return await dataViewsService.getIdsWithTitle(); - } catch (e) { - const { esService: strings } = ErrorStrings; - notifyService.error(e, { title: strings.getIndicesFetchErrorMessage() }); - } - return []; - }, [notifyService]); - - const getFields = useCallback(async (dataViewTitle: string) => { - const dataView = await dataViewsService.create({ title: dataViewTitle }); - - return dataView.fields - .filter((field) => !field.name.startsWith('_')) - .map((field) => field.name); - }, []); - - return { getDataViews, getFields }; -}; From f8253aa5ac92639224076641bc2ce800a1ee71d9 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 2 Oct 2024 15:03:00 -0600 Subject: [PATCH 13/41] Fix hooks --- x-pack/plugins/canvas/public/services/hooks.ts | 5 +++++ x-pack/plugins/canvas/public/services/index.ts | 1 + 2 files changed, 6 insertions(+) diff --git a/x-pack/plugins/canvas/public/services/hooks.ts b/x-pack/plugins/canvas/public/services/hooks.ts index c8fe403dcad0b..7ff949318f271 100644 --- a/x-pack/plugins/canvas/public/services/hooks.ts +++ b/x-pack/plugins/canvas/public/services/hooks.ts @@ -20,22 +20,27 @@ export const useCustomElementService = () => { const canvasCustomElementService = useMemo(() => getCustomElementService(), []); return canvasCustomElementService; }; + export const useExpressionsService = () => { const canvasExpressionService = useMemo(() => getCanvasExpressionService(), []); return canvasExpressionService; }; + export const useFiltersService = () => { const canvasFiltersService = useMemo(() => getCanvasFiltersService(), []); return canvasFiltersService; }; + export const useNotifyService = () => { const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); return canvasNotifyService; }; + export const useWorkpadService = () => { const canvasWorkpadService = useMemo(() => getCanvasWorkpadService(), []); return canvasWorkpadService; }; + export const useDataViewsService = () => { const notifyService = useNotifyService(); diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index 13450be8e5b8a..8a916b2d79424 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -5,4 +5,5 @@ * 2.0. */ +export { useNotifyService } from './hooks'; export * from './legacy'; From e93c62ac0dd1eb2b1c0a325a9a1ad3c4f9339189 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 2 Oct 2024 16:16:45 -0600 Subject: [PATCH 14/41] Move things out of `hooks` and fix (?) public export --- .../asset_manager/asset.component.tsx | 2 +- .../datasource/datasource_preview/index.js | 2 +- .../components/element_content/index.tsx | 2 +- .../es_data_view_select.tsx | 2 +- .../components/es_field_select/index.tsx | 2 +- .../es_fields_select/es_fields_select.tsx | 2 +- .../public/components/expression/index.tsx | 2 +- .../public/components/function_form/index.tsx | 2 +- .../home/hooks/use_clone_workpad.ts | 2 +- .../home/hooks/use_create_from_template.ts | 2 +- .../home/hooks/use_create_workpad.ts | 2 +- .../home/hooks/use_delete_workpad.ts | 2 +- .../home/hooks/use_find_templates.ts | 2 +- .../components/home/hooks/use_find_workpad.ts | 2 +- .../home/hooks/use_import_workpad.ts | 2 +- .../home/hooks/use_upload_workpad.ts | 2 +- .../home/my_workpads/upload_dropzone.tsx | 2 +- .../hooks/workpad/use_download_workpad.ts | 2 +- .../hooks/workpad/use_incoming_embeddable.ts | 2 +- .../render_with_fn/render_with_fn.tsx | 2 +- .../saved_elements_modal.tsx | 2 +- .../public/components/var_config/index.tsx | 2 +- .../hooks/use_canvas_filters.ts | 2 +- .../share_menu/flyout/flyout.component.tsx | 2 +- .../flyout/hooks/use_download_runtime.ts | 2 +- x-pack/plugins/canvas/public/plugin.tsx | 7 +- .../routes/workpad/hooks/use_workpad.ts | 2 +- .../workpad/hooks/use_workpad_persist.ts | 2 +- .../public/routes/workpad/workpad_route.tsx | 2 +- .../services/canvas_custom_element_service.ts | 17 ++--- .../services/canvas_expressions_service.ts | 4 +- .../public/services/canvas_workpad_service.ts | 33 ++++------ .../plugins/canvas/public/services/hooks.ts | 66 ------------------- .../plugins/canvas/public/services/index.ts | 59 ++++++++++++++++- 34 files changed, 113 insertions(+), 129 deletions(-) delete mode 100644 x-pack/plugins/canvas/public/services/hooks.ts diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx b/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx index fc144c313e4a3..024137f640636 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset.component.tsx @@ -19,7 +19,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useNotifyService } from '../../services/hooks'; +import { useNotifyService } from '../../services'; import { ConfirmModal } from '../confirm_modal'; import { Clipboard } from '../clipboard'; diff --git a/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js b/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js index e85f19b19d700..1ca674bfb6f9d 100644 --- a/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js +++ b/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js @@ -8,7 +8,7 @@ import React, { useState, useEffect } from 'react'; import { PropTypes } from 'prop-types'; import { Loading } from '../../loading'; -import { useExpressionsService } from '../../../services/hooks'; +import { useExpressionsService } from '../../../services'; import { DatasourcePreview as Component } from './datasource_preview'; export const DatasourcePreview = (props) => { diff --git a/x-pack/plugins/canvas/public/components/element_content/index.tsx b/x-pack/plugins/canvas/public/components/element_content/index.tsx index bb333062f144b..bdbfc205d4c81 100644 --- a/x-pack/plugins/canvas/public/components/element_content/index.tsx +++ b/x-pack/plugins/canvas/public/components/element_content/index.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { getSelectedPage, getPageById } from '../../state/selectors/workpad'; -import { useExpressionsService } from '../../services/hooks'; +import { useExpressionsService } from '../../services'; import { ElementContent as Component, Props as ComponentProps } from './element_content'; import { State } from '../../../types'; diff --git a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx index 036373caceb18..d334544ee62a6 100644 --- a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx +++ b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx @@ -9,7 +9,7 @@ import { DataViewListItem } from '@kbn/data-views-plugin/common'; import { sortBy } from 'lodash'; import React, { FC, useRef, useState } from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { useDataViewsService } from '../../services/hooks'; +import { useDataViewsService } from '../../services'; import { ESDataViewSelect as Component, ESDataViewSelectProps as Props, diff --git a/x-pack/plugins/canvas/public/components/es_field_select/index.tsx b/x-pack/plugins/canvas/public/components/es_field_select/index.tsx index 6fbaf70e751ba..653eec22d77d9 100644 --- a/x-pack/plugins/canvas/public/components/es_field_select/index.tsx +++ b/x-pack/plugins/canvas/public/components/es_field_select/index.tsx @@ -6,7 +6,7 @@ */ import React, { useState, useEffect, useRef } from 'react'; -import { useDataViewsService } from '../../services/hooks'; +import { useDataViewsService } from '../../services'; import { ESFieldSelect as Component, ESFieldSelectProps as Props } from './es_field_select'; type ESFieldSelectProps = Omit; diff --git a/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx b/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx index bb13662b3791d..c929203f9e094 100644 --- a/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx +++ b/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx @@ -8,7 +8,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { isEqual } from 'lodash'; import usePrevious from 'react-use/lib/usePrevious'; -import { useDataViewsService } from '../../services/hooks'; +import { useDataViewsService } from '../../services'; import { ESFieldsSelect as Component, ESFieldsSelectProps as Props, diff --git a/x-pack/plugins/canvas/public/components/expression/index.tsx b/x-pack/plugins/canvas/public/components/expression/index.tsx index 7b0bad223017a..37bbbd1f5a4c1 100644 --- a/x-pack/plugins/canvas/public/components/expression/index.tsx +++ b/x-pack/plugins/canvas/public/components/expression/index.tsx @@ -8,7 +8,7 @@ import React, { FC, useState, useCallback, useMemo, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { fromExpression } from '@kbn/interpreter'; -import { useExpressionsService } from '../../services/hooks'; +import { useExpressionsService } from '../../services'; import { getSelectedPage, getSelectedElement } from '../../state/selectors/workpad'; // @ts-expect-error import { setExpression, flushContext } from '../../state/actions/elements'; diff --git a/x-pack/plugins/canvas/public/components/function_form/index.tsx b/x-pack/plugins/canvas/public/components/function_form/index.tsx index 308d6dffc63b0..46da2403c22b7 100644 --- a/x-pack/plugins/canvas/public/components/function_form/index.tsx +++ b/x-pack/plugins/canvas/public/components/function_form/index.tsx @@ -34,7 +34,7 @@ import { findExistingAsset } from '../../lib/find_existing_asset'; import { FunctionForm as Component } from './function_form'; import { Args, ArgType, ArgTypeDef } from '../../expression_types/types'; import { State, ExpressionContext, CanvasElement, AssetType } from '../../../types'; -import { useWorkpadService } from '../../services/hooks'; +import { useWorkpadService } from '../../services'; import { createAsset, notifyError } from '../../lib/assets'; interface FunctionFormProps { diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts index f398b9a0e0602..001a711a58a72 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts @@ -9,7 +9,7 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services/hooks'; +import { useNotifyService, useWorkpadService } from '../../../services'; import { getId } from '../../../lib/get_id'; export const useCloneWorkpad = () => { diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts index 0f5dcdca27cb9..968f9398ba857 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts @@ -9,7 +9,7 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { CanvasTemplate } from '../../../../types'; -import { useNotifyService, useWorkpadService } from '../../../services/hooks'; +import { useNotifyService, useWorkpadService } from '../../../services'; export const useCreateFromTemplate = () => { const workpadService = useWorkpadService(); diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts index 83b8a533fcf70..3290bc8227a29 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; // @ts-expect-error import { getDefaultWorkpad } from '../../../state/defaults'; -import { useNotifyService, useWorkpadService } from '../../../services/hooks'; +import { useNotifyService, useWorkpadService } from '../../../services'; import type { CanvasWorkpad } from '../../../../types'; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts index f9e51b49276a3..3143b19fa8130 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts @@ -8,7 +8,7 @@ import { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { useWorkpadService } from '../../../services/hooks'; +import { useWorkpadService } from '../../../services'; import { getCanvasNotifyService } from '../../../services/canvas_notify_service'; export const useDeleteWorkpads = () => { diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts index e0d0f48f483b2..9364a79987908 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts @@ -7,7 +7,7 @@ import { useCallback } from 'react'; -import { useWorkpadService } from '../../../services/hooks'; +import { useWorkpadService } from '../../../services'; export const useFindTemplates = () => { const workpadService = useWorkpadService(); diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts index f410c60882b8d..10352d0472e8c 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts @@ -8,7 +8,7 @@ import { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services/hooks'; +import { useNotifyService, useWorkpadService } from '../../../services'; export const useFindWorkpads = () => { const workpadService = useWorkpadService(); diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts index 959e04192d111..bd780ee01507d 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts @@ -9,7 +9,7 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services/hooks'; +import { useNotifyService, useWorkpadService } from '../../../services'; import type { CanvasWorkpad } from '../../../../types'; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts index d17f19680ab32..3a9865b3cff29 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { SavedObject } from '@kbn/core/public'; import { CANVAS, JSON as JSONString } from '../../../../i18n/constants'; -import { useNotifyService } from '../../../services/hooks'; +import { useNotifyService } from '../../../services'; import { getId } from '../../../lib/get_id'; import { useImportWorkpad as useImportWorkpadHook } from './use_import_workpad'; import type { CanvasWorkpad } from '../../../../types'; diff --git a/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx b/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx index c2994f77ba348..10ba1c3e06b70 100644 --- a/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx +++ b/x-pack/plugins/canvas/public/components/home/my_workpads/upload_dropzone.tsx @@ -7,7 +7,7 @@ import React, { FC, PropsWithChildren, useState } from 'react'; -import { useNotifyService } from '../../../services/hooks'; +import { useNotifyService } from '../../../services'; import { ErrorStrings } from '../../../../i18n'; import { useImportWorkpad } from '../hooks'; diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts index 9228b09795945..dadf03a8fac5a 100644 --- a/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts @@ -8,7 +8,7 @@ import { useCallback } from 'react'; import fileSaver from 'file-saver'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services/hooks'; +import { useNotifyService, useWorkpadService } from '../../../services'; import { CanvasWorkpad } from '../../../../types'; import type { CanvasRenderedWorkpad } from '../../../../shareable_runtime/types'; diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts index 9587f803bb2ef..50c3e527bbbae 100644 --- a/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/use_incoming_embeddable.ts @@ -12,7 +12,7 @@ import { ErrorStrings } from '../../../../i18n'; import { CANVAS_APP } from '../../../../common/lib'; import { decode } from '../../../../common/lib/embeddable_dataurl'; import { CanvasElement, CanvasPage } from '../../../../types'; -import { useNotifyService } from '../../../services/hooks'; +import { useNotifyService } from '../../../services'; // @ts-expect-error unconverted file import { addElement, fetchAllRenderables } from '../../../state/actions/elements'; // @ts-expect-error unconverted file diff --git a/x-pack/plugins/canvas/public/components/render_with_fn/render_with_fn.tsx b/x-pack/plugins/canvas/public/components/render_with_fn/render_with_fn.tsx index e540fbba4ce2a..a48bef994dd9d 100644 --- a/x-pack/plugins/canvas/public/components/render_with_fn/render_with_fn.tsx +++ b/x-pack/plugins/canvas/public/components/render_with_fn/render_with_fn.tsx @@ -9,7 +9,7 @@ import React, { useState, useEffect, useRef, FC, useCallback } from 'react'; import { isEqual } from 'lodash'; -import { useNotifyService } from '../../services/hooks'; +import { useNotifyService } from '../../services'; import { RenderToDom } from '../render_to_dom'; import { ErrorStrings } from '../../../i18n'; import { RendererHandlers } from '../../../types'; diff --git a/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx b/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx index 08eeef0fbd0a4..19e786edfd5fb 100644 --- a/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx +++ b/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx @@ -9,7 +9,7 @@ import React, { useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { camelCase } from 'lodash'; import { cloneSubgraphs } from '../../lib/clone_subgraphs'; -import { useNotifyService, useCustomElementService } from '../../services/hooks'; +import { useNotifyService, useCustomElementService } from '../../services'; // @ts-expect-error untyped local import { selectToplevelNodes } from '../../state/actions/transient'; // @ts-expect-error untyped local diff --git a/x-pack/plugins/canvas/public/components/var_config/index.tsx b/x-pack/plugins/canvas/public/components/var_config/index.tsx index 9fc2fa4991547..db2a84e93a5dc 100644 --- a/x-pack/plugins/canvas/public/components/var_config/index.tsx +++ b/x-pack/plugins/canvas/public/components/var_config/index.tsx @@ -10,7 +10,7 @@ import copy from 'copy-to-clipboard'; import { i18n } from '@kbn/i18n'; import { VarConfig as ChildComponent } from './var_config'; -import { useNotifyService } from '../../services/hooks'; +import { useNotifyService } from '../../services'; import { CanvasVariable } from '../../../types'; const strings = { diff --git a/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts b/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts index 3848e34f2268e..bdccc8040c5de 100644 --- a/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts +++ b/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts @@ -10,7 +10,7 @@ import { shallowEqual, useSelector } from 'react-redux'; import { State } from '../../../../types'; import { getFiltersByFilterExpressions } from '../../../lib/filter'; import { adaptCanvasFilter } from '../../../lib/filter_adapters'; -import { useFiltersService } from '../../../services/hooks'; +import { useFiltersService } from '../../../services'; const extractExpressionAST = (filters: string[]) => fromExpression(filters.join(' | ')); diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/flyout.component.tsx b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/flyout.component.tsx index 34b567150c4d9..57a8a90ce160c 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/flyout.component.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/flyout.component.tsx @@ -32,7 +32,7 @@ import { OnCloseFn } from '../share_menu.component'; import { WorkpadStep } from './workpad_step'; import { RuntimeStep } from './runtime_step'; import { SnippetsStep } from './snippets_step'; -import { useNotifyService } from '../../../../services/hooks'; +import { useNotifyService } from '../../../../services'; const strings = { getCopyShareConfigMessage: () => diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts index 8e688d1d02e87..27b93269f4352 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts @@ -12,7 +12,7 @@ import { API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD } from '../../../../../../common/l import { ZIP } from '../../../../../../i18n/constants'; import type { CanvasRenderedWorkpad } from '../../../../../../shareable_runtime/types'; -import { useNotifyService, useWorkpadService } from '../../../../../services/hooks'; +import { useNotifyService, useWorkpadService } from '../../../../../services'; import { coreServices } from '../../../../../services/kibana_services'; const strings = { diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx index 4cdeb30a4aa66..a0178c749dd45 100644 --- a/x-pack/plugins/canvas/public/plugin.tsx +++ b/x-pack/plugins/canvas/public/plugin.tsx @@ -38,7 +38,7 @@ import { initLoadingIndicator } from './lib/loading_indicator'; import { getPluginApi, CanvasApi } from './plugin_api'; import { setupExpressions } from './setup_expressions'; import { addCanvasElementTrigger } from './state/triggers/add_canvas_element_trigger'; -import { setKibanaServices } from './services/kibana_services'; +import { setKibanaServices, untilPluginStartServicesReady } from './services/kibana_services'; export type { CoreStart, CoreSetup }; @@ -122,7 +122,10 @@ export class CanvasPlugin setupExpressions({ coreSetup, setupPlugins }); // Get start services - const [coreStart, startPlugins] = await coreSetup.getStartServices(); + const [[coreStart, startPlugins]] = await Promise.all([ + coreSetup.getStartServices(), + untilPluginStartServicesReady(), + ]); srcPlugin.start(coreStart, startPlugins); diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts index f81499b41c68d..45e077c25166a 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts @@ -8,7 +8,7 @@ import { useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { useDispatch, useSelector } from 'react-redux'; -import { useWorkpadService } from '../../../services/hooks'; +import { useWorkpadService } from '../../../services'; import { getWorkpad } from '../../../state/selectors/workpad'; import { setWorkpad } from '../../../state/actions/workpad'; // @ts-expect-error diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts index cc2ab9be52543..f63d3bf8e32a1 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts @@ -10,7 +10,7 @@ import { useSelector } from 'react-redux'; import { CanvasWorkpad, State } from '../../../../types'; import { getWorkpad } from '../../../state/selectors/workpad'; import { canUserWrite } from '../../../state/selectors/app'; -import { useWorkpadService } from '../../../services/hooks'; +import { useWorkpadService } from '../../../services'; import { notifyError } from '../../../lib/assets'; export const useWorkpadPersist = () => { diff --git a/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx b/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx index 93da523dc93ae..733a0b2d2b9af 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/workpad_route.tsx @@ -14,7 +14,7 @@ import { ExportApp } from '../../components/export_app'; import { CanvasLoading } from '../../components/canvas_loading'; // @ts-expect-error import { fetchAllRenderables } from '../../state/actions/elements'; -import { useNotifyService } from '../../services/hooks'; +import { useNotifyService } from '../../services'; import { CanvasWorkpad } from '../../../types'; import { ErrorStrings } from '../../../i18n'; import { useWorkpad } from './hooks/use_workpad'; diff --git a/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts b/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts index 04559ee09fa5e..4b96351cee39d 100644 --- a/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts @@ -15,33 +15,28 @@ export interface CustomElementFindResponse { } class CanvasCustomElementService { - private apiPath = `${API_ROUTE_CUSTOM_ELEMENT}`; - private http; - - constructor() { - ({ http: this.http } = coreServices); - } + public apiPath = `${API_ROUTE_CUSTOM_ELEMENT}`; public async create(customElement: CustomElement) { - this.http.post(this.apiPath, { body: JSON.stringify(customElement), version: '1' }); + coreServices.http.post(this.apiPath, { body: JSON.stringify(customElement), version: '1' }); } public async get(customElementId: string): Promise { - return this.http + return coreServices.http .get<{ data: CustomElement }>(`${this.apiPath}/${customElementId}`, { version: '1' }) .then(({ data: element }) => element); } public async update(id: string, element: Partial) { - this.http.put(`${this.apiPath}/${id}`, { body: JSON.stringify(element), version: '1' }); + coreServices.http.put(`${this.apiPath}/${id}`, { body: JSON.stringify(element), version: '1' }); } public async remove(id: string) { - this.http.delete(`${this.apiPath}/${id}`, { version: '1' }); + coreServices.http.delete(`${this.apiPath}/${id}`, { version: '1' }); } public async find(searchTerm: string): Promise { - return this.http.get(`${this.apiPath}/find`, { + return coreServices.http.get(`${this.apiPath}/find`, { query: { name: searchTerm, perPage: 10000, diff --git a/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts b/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts index 0621c3e89416c..09f92e6998b04 100644 --- a/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts @@ -21,8 +21,8 @@ interface Options { } class ExpressionsService { - private notifyService; - private filtersService; + public notifyService; + public filtersService; constructor() { this.notifyService = getCanvasNotifyService(); diff --git a/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts index 3fe3e88cb9fa1..a54d02d09e4af 100644 --- a/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts @@ -68,21 +68,16 @@ const sanitizeWorkpad = function (workpad: CanvasWorkpad) { }; class CanvasWorkpadService { - private apiPath = `${API_ROUTE_WORKPAD}`; - private http; - - constructor() { - ({ http: this.http } = coreServices); - } + public apiPath = `${API_ROUTE_WORKPAD}`; public async get(id: string): Promise { - const workpad = await this.http.get(`${this.apiPath}/${id}`, { version: '1' }); + const workpad = await coreServices.http.get(`${this.apiPath}/${id}`, { version: '1' }); return { css: DEFAULT_WORKPAD_CSS, variables: [], ...workpad }; } public async export(id: string) { - const workpad = await this.http.get>( + const workpad = await coreServices.http.get>( `${this.apiPath}/export/${id}`, { version: '1' } ); @@ -99,7 +94,7 @@ class CanvasWorkpadService { } public async resolve(id: string): Promise { - const { workpad, ...resolveProps } = await this.http.get( + const { workpad, ...resolveProps } = await coreServices.http.get( `${this.apiPath}/resolve/${id}`, { version: '1' } ); @@ -117,7 +112,7 @@ class CanvasWorkpadService { } public async create(workpad: CanvasWorkpad): Promise { - return this.http.post(this.apiPath, { + return coreServices.http.post(this.apiPath, { body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }), assets: workpad.assets || {}, @@ -128,7 +123,7 @@ class CanvasWorkpadService { } public async import(workpad: CanvasWorkpad): Promise { - return this.http.post(`${this.apiPath}/import`, { + return coreServices.http.post(`${this.apiPath}/import`, { body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }), assets: workpad.assets || {}, @@ -139,21 +134,21 @@ class CanvasWorkpadService { } public async createFromTemplate(templateId: string): Promise { - return this.http.post(this.apiPath, { + return coreServices.http.post(this.apiPath, { body: JSON.stringify({ templateId }), version: '1', }); } public async findTemplates(): Promise { - return this.http.get(API_ROUTE_TEMPLATES, { version: '1' }); + return coreServices.http.get(API_ROUTE_TEMPLATES, { version: '1' }); } public async find(searchTerm: string): Promise { // TODO: this shouldn't be necessary. Check for usage. const validSearchTerm = typeof searchTerm === 'string' && searchTerm.length > 0; - return this.http.get(`${this.apiPath}/find`, { + return coreServices.http.get(`${this.apiPath}/find`, { query: { perPage: 10000, name: validSearchTerm ? searchTerm : '', @@ -163,32 +158,32 @@ class CanvasWorkpadService { } public async remove(id: string) { - this.http.delete(`${this.apiPath}/${id}`, { version: '1' }); + coreServices.http.delete(`${this.apiPath}/${id}`, { version: '1' }); } public async update(id: string, workpad: CanvasWorkpad) { - this.http.put(`${this.apiPath}/${id}`, { + coreServices.http.put(`${this.apiPath}/${id}`, { body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }), version: '1', }); } public async updateWorkpad(id: string, workpad: CanvasWorkpad) { - this.http.put(`${API_ROUTE_WORKPAD_STRUCTURES}/${id}`, { + coreServices.http.put(`${API_ROUTE_WORKPAD_STRUCTURES}/${id}`, { body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }), version: '1', }); } public async updateAssets(id: string, assets: CanvasWorkpad['assets']) { - this.http.put(`${API_ROUTE_WORKPAD_ASSETS}/${id}`, { + coreServices.http.put(`${API_ROUTE_WORKPAD_ASSETS}/${id}`, { body: JSON.stringify(assets), version: '1', }); } public async getRuntimeZip(workpad: CanvasRenderedWorkpad): Promise { - return this.http.post(API_ROUTE_SHAREABLE_ZIP, { + return coreServices.http.post(API_ROUTE_SHAREABLE_ZIP, { body: JSON.stringify(workpad), version: '1', }); diff --git a/x-pack/plugins/canvas/public/services/hooks.ts b/x-pack/plugins/canvas/public/services/hooks.ts deleted file mode 100644 index 7ff949318f271..0000000000000 --- a/x-pack/plugins/canvas/public/services/hooks.ts +++ /dev/null @@ -1,66 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './legacy'; -import { useCallback, useMemo } from 'react'; - -import { ErrorStrings } from '../../i18n'; -import { getCustomElementService } from './canvas_custom_element_service'; -import { getCanvasExpressionService } from './canvas_expressions_service'; -import { getCanvasFiltersService } from './canvas_filters_service'; -import { getCanvasNotifyService } from './canvas_notify_service'; -import { getCanvasWorkpadService } from './canvas_workpad_service'; -import { dataViewsService } from './kibana_services'; - -export const useCustomElementService = () => { - const canvasCustomElementService = useMemo(() => getCustomElementService(), []); - return canvasCustomElementService; -}; - -export const useExpressionsService = () => { - const canvasExpressionService = useMemo(() => getCanvasExpressionService(), []); - return canvasExpressionService; -}; - -export const useFiltersService = () => { - const canvasFiltersService = useMemo(() => getCanvasFiltersService(), []); - return canvasFiltersService; -}; - -export const useNotifyService = () => { - const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); - return canvasNotifyService; -}; - -export const useWorkpadService = () => { - const canvasWorkpadService = useMemo(() => getCanvasWorkpadService(), []); - return canvasWorkpadService; -}; - -export const useDataViewsService = () => { - const notifyService = useNotifyService(); - - const getDataViews = useCallback(async () => { - try { - return await dataViewsService.getIdsWithTitle(); - } catch (e) { - const { esService: strings } = ErrorStrings; - notifyService.error(e, { title: strings.getIndicesFetchErrorMessage() }); - } - return []; - }, [notifyService]); - - const getFields = useCallback(async (dataViewTitle: string) => { - const dataView = await dataViewsService.create({ title: dataViewTitle }); - - return dataView.fields - .filter((field) => !field.name.startsWith('_')) - .map((field) => field.name); - }, []); - - return { getDataViews, getFields }; -}; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index 8a916b2d79424..7ff949318f271 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -5,5 +5,62 @@ * 2.0. */ -export { useNotifyService } from './hooks'; export * from './legacy'; +import { useCallback, useMemo } from 'react'; + +import { ErrorStrings } from '../../i18n'; +import { getCustomElementService } from './canvas_custom_element_service'; +import { getCanvasExpressionService } from './canvas_expressions_service'; +import { getCanvasFiltersService } from './canvas_filters_service'; +import { getCanvasNotifyService } from './canvas_notify_service'; +import { getCanvasWorkpadService } from './canvas_workpad_service'; +import { dataViewsService } from './kibana_services'; + +export const useCustomElementService = () => { + const canvasCustomElementService = useMemo(() => getCustomElementService(), []); + return canvasCustomElementService; +}; + +export const useExpressionsService = () => { + const canvasExpressionService = useMemo(() => getCanvasExpressionService(), []); + return canvasExpressionService; +}; + +export const useFiltersService = () => { + const canvasFiltersService = useMemo(() => getCanvasFiltersService(), []); + return canvasFiltersService; +}; + +export const useNotifyService = () => { + const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); + return canvasNotifyService; +}; + +export const useWorkpadService = () => { + const canvasWorkpadService = useMemo(() => getCanvasWorkpadService(), []); + return canvasWorkpadService; +}; + +export const useDataViewsService = () => { + const notifyService = useNotifyService(); + + const getDataViews = useCallback(async () => { + try { + return await dataViewsService.getIdsWithTitle(); + } catch (e) { + const { esService: strings } = ErrorStrings; + notifyService.error(e, { title: strings.getIndicesFetchErrorMessage() }); + } + return []; + }, [notifyService]); + + const getFields = useCallback(async (dataViewTitle: string) => { + const dataView = await dataViewsService.create({ title: dataViewTitle }); + + return dataView.fields + .filter((field) => !field.name.startsWith('_')) + .map((field) => field.name); + }, []); + + return { getDataViews, getFields }; +}; From 419afbd343c4d17823d7cdae8dd2ae9ddaaf3c23 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 09:42:13 -0600 Subject: [PATCH 15/41] Remove unnecessary hooks --- x-pack/plugins/canvas/jest.config.js | 1 + x-pack/plugins/canvas/jest_setup.ts | 11 +++ .../datasource/datasource_preview/index.js | 7 +- .../components/element_content/index.tsx | 9 ++- .../public/components/expression/index.tsx | 7 +- .../public/components/function_form/index.tsx | 7 +- .../home/hooks/use_clone_workpad.ts | 7 +- .../home/hooks/use_create_from_template.ts | 7 +- .../home/hooks/use_create_workpad.ts | 7 +- .../home/hooks/use_delete_workpad.ts | 81 +++++++++---------- .../home/hooks/use_find_templates.ts | 6 +- .../components/home/hooks/use_find_workpad.ts | 8 +- .../home/hooks/use_import_workpad.ts | 7 +- .../hooks/workpad/use_download_workpad.ts | 7 +- .../saved_elements_modal.tsx | 7 +- .../hooks/use_canvas_filters.ts | 6 +- .../flyout/hooks/use_download_runtime.ts | 8 +- .../routes/workpad/hooks/use_workpad.test.tsx | 18 +++-- .../routes/workpad/hooks/use_workpad.ts | 13 ++- .../hooks/use_workpad_persist.test.tsx | 15 ++-- .../workpad/hooks/use_workpad_persist.ts | 14 ++-- .../plugins/canvas/public/services/index.ts | 24 ------ 22 files changed, 137 insertions(+), 140 deletions(-) create mode 100644 x-pack/plugins/canvas/jest_setup.ts diff --git a/x-pack/plugins/canvas/jest.config.js b/x-pack/plugins/canvas/jest.config.js index 2bff284e94ad8..f7a9224795b4a 100644 --- a/x-pack/plugins/canvas/jest.config.js +++ b/x-pack/plugins/canvas/jest.config.js @@ -17,4 +17,5 @@ module.exports = { collectCoverageFrom: [ '/x-pack/plugins/canvas/{canvas_plugin_src,common,i18n,public,server,shareable_runtime}/**/*.{js,ts,tsx}', ], + setupFiles: ['/x-pack/plugins/canvas/jest_setup.ts'], }; diff --git a/x-pack/plugins/canvas/jest_setup.ts b/x-pack/plugins/canvas/jest_setup.ts new file mode 100644 index 0000000000000..d9c0c26ea5a38 --- /dev/null +++ b/x-pack/plugins/canvas/jest_setup.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setStubKibanaServices } from './public/services/mocks'; + +// Start the kibana services with stubs +setStubKibanaServices(); diff --git a/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js b/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js index 1ca674bfb6f9d..f6f535058ea21 100644 --- a/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js +++ b/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js @@ -8,18 +8,17 @@ import React, { useState, useEffect } from 'react'; import { PropTypes } from 'prop-types'; import { Loading } from '../../loading'; -import { useExpressionsService } from '../../../services'; +import { getCanvasExpressionService } from '../../../services/canvas_expressions_service'; import { DatasourcePreview as Component } from './datasource_preview'; export const DatasourcePreview = (props) => { const [datatable, setDatatable] = useState(); - const expressionsService = useExpressionsService(); useEffect(() => { - expressionsService + getCanvasExpressionService() .interpretAst({ type: 'expression', chain: [props.function] }, {}) .then(setDatatable); - }, [expressionsService, props.function, setDatatable]); + }, [props.function, setDatatable]); if (!datatable) { return ; diff --git a/x-pack/plugins/canvas/public/components/element_content/index.tsx b/x-pack/plugins/canvas/public/components/element_content/index.tsx index bdbfc205d4c81..72ff04cbf2055 100644 --- a/x-pack/plugins/canvas/public/components/element_content/index.tsx +++ b/x-pack/plugins/canvas/public/components/element_content/index.tsx @@ -5,23 +5,24 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; import { getSelectedPage, getPageById } from '../../state/selectors/workpad'; -import { useExpressionsService } from '../../services'; import { ElementContent as Component, Props as ComponentProps } from './element_content'; import { State } from '../../../types'; +import { getCanvasExpressionService } from '../../services/canvas_expressions_service'; export type Props = Omit; export const ElementContent = (props: Props) => { - const expressionsService = useExpressionsService(); const selectedPageId = useSelector(getSelectedPage); const backgroundColor = useSelector((state: State) => getPageById(state, selectedPageId)?.style.background) || ''; const { renderable } = props; - const renderFunction = renderable ? expressionsService.getRenderer(renderable.as) : null; + const renderFunction = useMemo(() => { + return renderable ? getCanvasExpressionService().getRenderer(renderable.as) : null; + }, [renderable]); return ; }; diff --git a/x-pack/plugins/canvas/public/components/expression/index.tsx b/x-pack/plugins/canvas/public/components/expression/index.tsx index 37bbbd1f5a4c1..1d0c9915bf347 100644 --- a/x-pack/plugins/canvas/public/components/expression/index.tsx +++ b/x-pack/plugins/canvas/public/components/expression/index.tsx @@ -8,7 +8,6 @@ import React, { FC, useState, useCallback, useMemo, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { fromExpression } from '@kbn/interpreter'; -import { useExpressionsService } from '../../services'; import { getSelectedPage, getSelectedElement } from '../../state/selectors/workpad'; // @ts-expect-error import { setExpression, flushContext } from '../../state/actions/elements'; @@ -16,6 +15,7 @@ import { setExpression, flushContext } from '../../state/actions/elements'; import { ElementNotSelected } from './element_not_selected'; import { Expression as Component } from './expression'; import { State, CanvasElement } from '../../../types'; +import { getCanvasExpressionService } from '../../services/canvas_expressions_service'; interface ExpressionProps { done: () => void; @@ -45,7 +45,6 @@ export const Expression: FC = ({ done }) => { }; const ExpressionContainer: FC = ({ done, element, pageId }) => { - const expressions = useExpressionsService(); const dispatch = useDispatch(); const [isCompact, setCompact] = useState(true); const toggleCompactView = useCallback(() => { @@ -111,8 +110,8 @@ const ExpressionContainer: FC = ({ done, element, page }, [element, setFormState, formState]); const functionDefinitions = useMemo( - () => Object.values(expressions.getFunctions()), - [expressions] + () => Object.values(getCanvasExpressionService().getFunctions()), + [] ); return ( diff --git a/x-pack/plugins/canvas/public/components/function_form/index.tsx b/x-pack/plugins/canvas/public/components/function_form/index.tsx index 46da2403c22b7..f58eb496f7139 100644 --- a/x-pack/plugins/canvas/public/components/function_form/index.tsx +++ b/x-pack/plugins/canvas/public/components/function_form/index.tsx @@ -34,8 +34,8 @@ import { findExistingAsset } from '../../lib/find_existing_asset'; import { FunctionForm as Component } from './function_form'; import { Args, ArgType, ArgTypeDef } from '../../expression_types/types'; import { State, ExpressionContext, CanvasElement, AssetType } from '../../../types'; -import { useWorkpadService } from '../../services'; import { createAsset, notifyError } from '../../lib/assets'; +import { getCanvasWorkpadService } from '../../services/canvas_workpad_service'; interface FunctionFormProps { name: string; @@ -54,7 +54,6 @@ interface FunctionFormProps { export const FunctionForm: React.FunctionComponent = (props) => { const { expressionIndex, ...restProps } = props; const { nextArgType, path, parentPath, argType } = restProps; - const service = useWorkpadService(); const dispatch = useDispatch(); const context = useSelector( @@ -112,7 +111,7 @@ export const FunctionForm: React.FunctionComponent = (props) // make the ID here and pass it into the action const asset = createAsset(type, content); - return service + return getCanvasWorkpadService() .updateAssets(workpad.id, { ...workpad.assets, [asset.id]: asset }) .then((res) => { dispatch(setAsset(asset)); @@ -121,7 +120,7 @@ export const FunctionForm: React.FunctionComponent = (props) }) .catch((error) => notifyError(error)); }, - [dispatch, service, workpad.assets, workpad.id] + [dispatch, workpad.assets, workpad.id] ); const onAssetAdd = useCallback( diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts index 001a711a58a72..90a7c4c33de89 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_clone_workpad.ts @@ -9,16 +9,17 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService } from '../../../services'; import { getId } from '../../../lib/get_id'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; export const useCloneWorkpad = () => { - const workpadService = useWorkpadService(); const notifyService = useNotifyService(); const history = useHistory(); return useCallback( async (workpadId: string) => { + const workpadService = getCanvasWorkpadService(); try { let workpad = await workpadService.get(workpadId); @@ -35,7 +36,7 @@ export const useCloneWorkpad = () => { notifyService.error(err, { title: errors.getCloneFailureErrorMessage() }); } }, - [notifyService, workpadService, history] + [notifyService, history] ); }; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts index 968f9398ba857..6b57cf61ca905 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_create_from_template.ts @@ -9,15 +9,16 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { CanvasTemplate } from '../../../../types'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService } from '../../../services'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; export const useCreateFromTemplate = () => { - const workpadService = useWorkpadService(); const notifyService = useNotifyService(); const history = useHistory(); return useCallback( async (template: CanvasTemplate) => { + const workpadService = getCanvasWorkpadService(); try { const result = await workpadService.createFromTemplate(template.id); history.push(`/workpad/${result.id}/page/1`); @@ -27,6 +28,6 @@ export const useCreateFromTemplate = () => { }); } }, - [workpadService, notifyService, history] + [notifyService, history] ); }; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts index 3290bc8227a29..f950a4adcd037 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts @@ -11,17 +11,18 @@ import { i18n } from '@kbn/i18n'; // @ts-expect-error import { getDefaultWorkpad } from '../../../state/defaults'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService } from '../../../services'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; import type { CanvasWorkpad } from '../../../../types'; export const useCreateWorkpad = () => { - const workpadService = useWorkpadService(); const notifyService = useNotifyService(); const history = useHistory(); return useCallback( async (_workpad?: CanvasWorkpad | null) => { + const workpadService = getCanvasWorkpadService(); const workpad = _workpad || (getDefaultWorkpad() as CanvasWorkpad); try { @@ -34,7 +35,7 @@ export const useCreateWorkpad = () => { } return; }, - [notifyService, history, workpadService] + [notifyService, history] ); }; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts index 3143b19fa8130..dc52fe2e82d5c 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_delete_workpad.ts @@ -8,51 +8,48 @@ import { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { useWorkpadService } from '../../../services'; import { getCanvasNotifyService } from '../../../services/canvas_notify_service'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; export const useDeleteWorkpads = () => { - const workpadService = useWorkpadService(); - - return useCallback( - async (workpadIds: string[]) => { - const removedWorkpads = workpadIds.map(async (id) => { - try { - await workpadService.remove(id); - return { id, err: null }; - } catch (err) { - return { id, err }; - } - }); - - return Promise.all(removedWorkpads).then((results) => { - const [passes, errored] = results.reduce<[string[], string[]]>( - ([passesArr, errorsArr], result) => { - if (result.err) { - errorsArr.push(result.id); - } else { - passesArr.push(result.id); - } - - return [passesArr, errorsArr]; - }, - [[], []] - ); - - const removedIds = workpadIds.filter((id) => passes.includes(id)); - - if (errored.length > 0) { - getCanvasNotifyService().error(errors.getDeleteFailureErrorMessage()); - } - - return { - removedIds, - errored, - }; - }); - }, - [workpadService] - ); + return useCallback(async (workpadIds: string[]) => { + const workpadService = getCanvasWorkpadService(); + + const removedWorkpads = workpadIds.map(async (id) => { + try { + await workpadService.remove(id); + return { id, err: null }; + } catch (err) { + return { id, err }; + } + }); + + return Promise.all(removedWorkpads).then((results) => { + const [passes, errored] = results.reduce<[string[], string[]]>( + ([passesArr, errorsArr], result) => { + if (result.err) { + errorsArr.push(result.id); + } else { + passesArr.push(result.id); + } + + return [passesArr, errorsArr]; + }, + [[], []] + ); + + const removedIds = workpadIds.filter((id) => passes.includes(id)); + + if (errored.length > 0) { + getCanvasNotifyService().error(errors.getDeleteFailureErrorMessage()); + } + + return { + removedIds, + errored, + }; + }); + }, []); }; const errors = { diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts index 9364a79987908..426b612774762 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_find_templates.ts @@ -6,10 +6,8 @@ */ import { useCallback } from 'react'; - -import { useWorkpadService } from '../../../services'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; export const useFindTemplates = () => { - const workpadService = useWorkpadService(); - return useCallback(async () => await workpadService.findTemplates(), [workpadService]); + return useCallback(async () => await getCanvasWorkpadService().findTemplates(), []); }; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts index 10352d0472e8c..59ff5cd0561b5 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_find_workpad.ts @@ -8,21 +8,21 @@ import { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService } from '../../../services'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; export const useFindWorkpads = () => { - const workpadService = useWorkpadService(); const notifyService = useNotifyService(); return useCallback( async (text = '') => { try { - return await workpadService.find(text); + return await getCanvasWorkpadService().find(text); } catch (err) { notifyService.error(err, { title: errors.getFindFailureErrorMessage() }); } }, - [notifyService, workpadService] + [notifyService] ); }; diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts index bd780ee01507d..bb3f447cd107b 100644 --- a/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts +++ b/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts @@ -9,17 +9,18 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService } from '../../../services'; import type { CanvasWorkpad } from '../../../../types'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; export const useImportWorkpad = () => { - const workpadService = useWorkpadService(); const notifyService = useNotifyService(); const history = useHistory(); return useCallback( async (workpad: CanvasWorkpad) => { + const workpadService = getCanvasWorkpadService(); try { const importedWorkpad = await workpadService.import(workpad); history.push(`/workpad/${importedWorkpad.id}/page/1`); @@ -30,7 +31,7 @@ export const useImportWorkpad = () => { } return; }, - [notifyService, history, workpadService] + [notifyService, history] ); }; diff --git a/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts b/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts index dadf03a8fac5a..394274b1eb133 100644 --- a/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts +++ b/x-pack/plugins/canvas/public/components/hooks/workpad/use_download_workpad.ts @@ -8,9 +8,10 @@ import { useCallback } from 'react'; import fileSaver from 'file-saver'; import { i18n } from '@kbn/i18n'; -import { useNotifyService, useWorkpadService } from '../../../services'; +import { useNotifyService } from '../../../services'; import { CanvasWorkpad } from '../../../../types'; import type { CanvasRenderedWorkpad } from '../../../../shareable_runtime/types'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; const strings = { getDownloadFailureErrorMessage: () => @@ -28,12 +29,12 @@ const strings = { export const useDownloadWorkpad = () => { const notifyService = useNotifyService(); - const workpadService = useWorkpadService(); const download = useDownloadWorkpadBlob(); return useCallback( async (workpadId: string) => { try { + const workpadService = getCanvasWorkpadService(); const workpad = await workpadService.get(workpadId); download(workpad, `canvas-workpad-${workpad.name}-${workpad.id}`); @@ -41,7 +42,7 @@ export const useDownloadWorkpad = () => { notifyService.error(err, { title: strings.getDownloadFailureErrorMessage() }); } }, - [workpadService, notifyService, download] + [notifyService, download] ); }; diff --git a/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx b/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx index 19e786edfd5fb..5aeb8847ab887 100644 --- a/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx +++ b/x-pack/plugins/canvas/public/components/saved_elements_modal/saved_elements_modal.tsx @@ -5,11 +5,11 @@ * 2.0. */ -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { camelCase } from 'lodash'; import { cloneSubgraphs } from '../../lib/clone_subgraphs'; -import { useNotifyService, useCustomElementService } from '../../services'; +import { useNotifyService } from '../../services'; // @ts-expect-error untyped local import { selectToplevelNodes } from '../../state/actions/transient'; // @ts-expect-error untyped local @@ -21,6 +21,7 @@ import { Props as ComponentProps, } from './saved_elements_modal.component'; import { PositionedElement, CustomElement } from '../../../types'; +import { getCustomElementService } from '../../services/canvas_custom_element_service'; const customElementAdded = 'elements-custom-added'; @@ -28,7 +29,7 @@ export type Props = Pick; export const SavedElementsModal = ({ onClose }: Props) => { const notifyService = useNotifyService(); - const customElementService = useCustomElementService(); + const customElementService = useMemo(() => getCustomElementService(), []); const dispatch = useDispatch(); const pageId = useSelector(getSelectedPage); const [customElements, setCustomElements] = useState([]); diff --git a/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts b/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts index bdccc8040c5de..9aa9aecdfd516 100644 --- a/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts +++ b/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts @@ -5,17 +5,19 @@ * 2.0. */ +import { useMemo } from 'react'; import { AstFunction, fromExpression } from '@kbn/interpreter'; import { shallowEqual, useSelector } from 'react-redux'; + import { State } from '../../../../types'; import { getFiltersByFilterExpressions } from '../../../lib/filter'; import { adaptCanvasFilter } from '../../../lib/filter_adapters'; -import { useFiltersService } from '../../../services'; +import { getCanvasFiltersService } from '../../../services/canvas_filters_service'; const extractExpressionAST = (filters: string[]) => fromExpression(filters.join(' | ')); export function useCanvasFilters(filterExprsToGroupBy: AstFunction[] = []) { - const filtersService = useFiltersService(); + const filtersService = useMemo(() => getCanvasFiltersService(), []); const filterExpressions = useSelector( (state: State) => filtersService.getFilters(state), shallowEqual diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts index 27b93269f4352..0998e91f50a1b 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts @@ -12,8 +12,9 @@ import { API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD } from '../../../../../../common/l import { ZIP } from '../../../../../../i18n/constants'; import type { CanvasRenderedWorkpad } from '../../../../../../shareable_runtime/types'; -import { useNotifyService, useWorkpadService } from '../../../../../services'; +import { useNotifyService } from '../../../../../services'; import { coreServices } from '../../../../../services/kibana_services'; +import { getCanvasWorkpadService } from '../../../../../services/canvas_workpad_service'; const strings = { getDownloadRuntimeFailureErrorMessage: () => @@ -52,11 +53,12 @@ export const useDownloadRuntime = () => { }; export const useDownloadZippedRuntime = () => { - const workpadService = useWorkpadService(); const notifyService = useNotifyService(); const downloadZippedRuntime = useCallback( (workpad: CanvasRenderedWorkpad) => { + const workpadService = getCanvasWorkpadService(); + const downloadZip = async () => { try { let runtimeZipBlob: Blob | undefined; @@ -80,7 +82,7 @@ export const useDownloadZippedRuntime = () => { downloadZip(); }, - [notifyService, workpadService] + [notifyService] ); return downloadZippedRuntime; }; diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.test.tsx b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.test.tsx index 0d73fe49601c8..1ba0dacd8c143 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.test.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.test.tsx @@ -7,6 +7,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { useWorkpad } from './use_workpad'; +import { spacesService } from '../../../services/kibana_services'; const mockDispatch = jest.fn(); const mockSelector = jest.fn(); @@ -25,21 +26,22 @@ const workpadResponse = { assets, }; -// Mock the hooks and actions used by the UseWorkpad hook +// Mock the hooks, actions, and services used by the UseWorkpad hook jest.mock('react-redux', () => ({ useDispatch: () => mockDispatch, useSelector: () => mockSelector, })); -jest.mock('../../../services', () => ({ - useWorkpadService: () => ({ - resolve: mockResolveWorkpad, - }), - usePlatformService: () => ({ - redirectLegacyUrl: mockRedirectLegacyUrl, - }), +jest.mock('../../../services/canvas_workpad_service', () => ({ + getCanvasWorkpadService: () => { + return { + resolve: mockResolveWorkpad, + }; + }, })); +spacesService!.ui.redirectLegacyUrl = mockRedirectLegacyUrl; + jest.mock('../../../state/actions/workpad', () => ({ setWorkpad: (payload: any) => ({ type: 'setWorkpad', diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts index 45e077c25166a..152256d0188ba 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts @@ -8,7 +8,6 @@ import { useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { useDispatch, useSelector } from 'react-redux'; -import { useWorkpadService } from '../../../services'; import { getWorkpad } from '../../../state/selectors/workpad'; import { setWorkpad } from '../../../state/actions/workpad'; // @ts-expect-error @@ -16,7 +15,10 @@ import { setAssets } from '../../../state/actions/assets'; // @ts-expect-error import { setZoomScale } from '../../../state/actions/transient'; import { CanvasWorkpad } from '../../../../types'; -import { ResolveWorkpadResponse } from '../../../services/canvas_workpad_service'; +import { + ResolveWorkpadResponse, + getCanvasWorkpadService, +} from '../../../services/canvas_workpad_service'; import { spacesService } from '../../../services/kibana_services'; const getWorkpadLabel = () => @@ -33,7 +35,6 @@ export const useWorkpad = ( loadPages: boolean = true, getRedirectPath: (workpadId: string) => string ): [CanvasWorkpad | undefined, string | Error | undefined] => { - const workpadService = useWorkpadService(); const dispatch = useDispatch(); const storedWorkpad = useSelector(getWorkpad); const [error, setError] = useState(undefined); @@ -46,14 +47,12 @@ export const useWorkpad = ( const { workpad: { assets, ...workpad }, ...resolveProps - } = await workpadService.resolve(workpadId); - + } = await getCanvasWorkpadService().resolve(workpadId); setResolveInfo({ id: workpadId, ...resolveProps }); // If it's an alias match, we know we are going to redirect so don't even dispatch that we got the workpad if (storedWorkpad.id !== workpadId && resolveProps.outcome !== 'aliasMatch') { workpad.aliasId = resolveProps.aliasId; - dispatch(setAssets(assets)); dispatch(setWorkpad(workpad, { loadPages })); dispatch(setZoomScale(1)); @@ -62,7 +61,7 @@ export const useWorkpad = ( setError(e as Error | string); } })(); - }, [workpadId, dispatch, setError, loadPages, workpadService, storedWorkpad.id]); + }, [workpadId, dispatch, setError, loadPages, storedWorkpad.id]); useEffect(() => { // If the resolved info is not for the current workpad id, bail out diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.test.tsx b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.test.tsx index 395cf774760fd..3193ad3dd79e5 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.test.tsx +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.test.tsx @@ -19,12 +19,17 @@ jest.mock('react-redux', () => ({ useSelector: (selector: any) => selector(mockGetState()), })); +jest.mock('../../../services/canvas_workpad_service', () => ({ + getCanvasWorkpadService: () => { + return { + updateWorkpad: mockUpdateWorkpad, + updateAssets: mockUpdateAssets, + update: mockUpdate, + }; + }, +})); + jest.mock('../../../services', () => ({ - useWorkpadService: () => ({ - updateWorkpad: mockUpdateWorkpad, - updateAssets: mockUpdateAssets, - update: mockUpdate, - }), useNotifyService: () => ({ error: mockNotifyError, }), diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts index f63d3bf8e32a1..f0f885c94eabc 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad_persist.ts @@ -10,12 +10,10 @@ import { useSelector } from 'react-redux'; import { CanvasWorkpad, State } from '../../../../types'; import { getWorkpad } from '../../../state/selectors/workpad'; import { canUserWrite } from '../../../state/selectors/app'; -import { useWorkpadService } from '../../../services'; import { notifyError } from '../../../lib/assets'; +import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service'; export const useWorkpadPersist = () => { - const service = useWorkpadService(); - // Watch for workpad state and then persist those changes const [workpad, canWrite]: [CanvasWorkpad, boolean] = useSelector((state: State) => [ getWorkpad(state), @@ -29,10 +27,12 @@ export const useWorkpadPersist = () => { useEffect(() => { if (canWrite) { if (workpadChanged) { - service.updateWorkpad(workpad.id, workpad).catch((err) => { - notifyError(err); - }); + getCanvasWorkpadService() + .updateWorkpad(workpad.id, workpad) + .catch((err) => { + notifyError(err); + }); } } - }, [service, workpad, workpadChanged, canWrite]); + }, [workpad, workpadChanged, canWrite]); }; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index 7ff949318f271..a3892b3fd86e5 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -9,38 +9,14 @@ export * from './legacy'; import { useCallback, useMemo } from 'react'; import { ErrorStrings } from '../../i18n'; -import { getCustomElementService } from './canvas_custom_element_service'; -import { getCanvasExpressionService } from './canvas_expressions_service'; -import { getCanvasFiltersService } from './canvas_filters_service'; import { getCanvasNotifyService } from './canvas_notify_service'; -import { getCanvasWorkpadService } from './canvas_workpad_service'; import { dataViewsService } from './kibana_services'; -export const useCustomElementService = () => { - const canvasCustomElementService = useMemo(() => getCustomElementService(), []); - return canvasCustomElementService; -}; - -export const useExpressionsService = () => { - const canvasExpressionService = useMemo(() => getCanvasExpressionService(), []); - return canvasExpressionService; -}; - -export const useFiltersService = () => { - const canvasFiltersService = useMemo(() => getCanvasFiltersService(), []); - return canvasFiltersService; -}; - export const useNotifyService = () => { const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); return canvasNotifyService; }; -export const useWorkpadService = () => { - const canvasWorkpadService = useMemo(() => getCanvasWorkpadService(), []); - return canvasWorkpadService; -}; - export const useDataViewsService = () => { const notifyService = useNotifyService(); From 8d8ab839a19b733c1a99352912433fa1bd331437 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 09:59:28 -0600 Subject: [PATCH 16/41] Update `tsconfig` --- x-pack/plugins/canvas/tsconfig.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/canvas/tsconfig.json b/x-pack/plugins/canvas/tsconfig.json index 85121b72c868c..251deca87c4ee 100644 --- a/x-pack/plugins/canvas/tsconfig.json +++ b/x-pack/plugins/canvas/tsconfig.json @@ -12,6 +12,7 @@ "allowJs": false }, "include": [ + "*.ts", "../../../typings/**/*", "__fixtures__/**/*", "canvas_plugin_src/**/*", @@ -88,9 +89,7 @@ "@kbn/presentation-containers", "@kbn/presentation-publishing", "@kbn/react-kibana-context-render", - "@kbn/search-types", + "@kbn/search-types" ], - "exclude": [ - "target/**/*", - ] + "exclude": ["target/**/*"] } From 2d33d9929463562f32baa87c7de085fb761fe284 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 11:09:37 -0600 Subject: [PATCH 17/41] Fix bundle size --- x-pack/plugins/canvas/public/application.tsx | 4 +++- .../canvas/public/components/app/index.tsx | 22 ++++++++++++++---- x-pack/plugins/canvas/public/plugin.tsx | 10 ++++++-- .../plugins/canvas/public/services/index.ts | 20 ++++++++-------- .../canvas/public/services/kibana_services.ts | 23 ++----------------- 5 files changed, 41 insertions(+), 38 deletions(-) diff --git a/x-pack/plugins/canvas/public/application.tsx b/x-pack/plugins/canvas/public/application.tsx index b7bcfd31ef6b9..91ef7c6173644 100644 --- a/x-pack/plugins/canvas/public/application.tsx +++ b/x-pack/plugins/canvas/public/application.tsx @@ -50,11 +50,13 @@ export const renderApp = ({ startPlugins, params, canvasStore, + appUpdater, }: { coreStart: CoreStart; startPlugins: CanvasStartDeps; params: AppMountParameters; canvasStore: Store; + appUpdater: BehaviorSubject; }) => { const { presentationUtil } = startPlugins; const { element } = params; @@ -67,7 +69,7 @@ export const renderApp = ({ - + diff --git a/x-pack/plugins/canvas/public/components/app/index.tsx b/x-pack/plugins/canvas/public/components/app/index.tsx index c038cd4b3b6f4..5874c1e1ad468 100644 --- a/x-pack/plugins/canvas/public/components/app/index.tsx +++ b/x-pack/plugins/canvas/public/components/app/index.tsx @@ -5,14 +5,17 @@ * 2.0. */ -import { ScopedHistory } from '@kbn/core/public'; +import { AppUpdater, ScopedHistory } from '@kbn/core/public'; import PropTypes from 'prop-types'; import React, { FC, useEffect } from 'react'; +import { BehaviorSubject } from 'rxjs'; // @ts-expect-error import { shortcutManager } from '../../lib/shortcut_manager'; import { CanvasRouter } from '../../routes'; -import { navLinksService } from '../../services/kibana_services'; import { Flyouts } from '../flyouts'; +import { getSessionStorage } from '../../lib/storage'; +import { SESSIONSTORAGE_LASTPATH } from '../../../common/lib'; +import { coreServices } from '../../services/kibana_services'; class ShortcutManagerContextWrapper extends React.Component> { static childContextTypes = { @@ -28,10 +31,21 @@ class ShortcutManagerContextWrapper extends React.Component = ({ history }) => { +export const App: FC<{ history: ScopedHistory; appUpdater: BehaviorSubject }> = ({ + history, + appUpdater, +}) => { useEffect(() => { return history.listen(({ pathname, search }) => { - navLinksService.updatePath(pathname + search); + const path = pathname + search; + appUpdater.next(() => ({ + defaultPath: `${path}`, + })); + + getSessionStorage().set( + `${SESSIONSTORAGE_LASTPATH}:${coreServices.http.basePath.get()}`, + path + ); }); }); diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx index a0178c749dd45..bd4e920a56f7e 100644 --- a/x-pack/plugins/canvas/public/plugin.tsx +++ b/x-pack/plugins/canvas/public/plugin.tsx @@ -146,7 +146,13 @@ export class CanvasPlugin this.appUpdater ); - const unmount = renderApp({ coreStart, startPlugins, params, canvasStore }); + const unmount = renderApp({ + coreStart, + startPlugins, + params, + canvasStore, + appUpdater: this.appUpdater, + }); return () => { unmount(); @@ -182,7 +188,7 @@ export class CanvasPlugin } public start(coreStart: CoreStart, startPlugins: CanvasStartDeps) { - setKibanaServices(coreStart, startPlugins, this.appUpdater, this.initContext); + setKibanaServices(coreStart, startPlugins, this.initContext); initLoadingIndicator(coreStart.http.addLoadingCountSource); } } diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index a3892b3fd86e5..6a2aacef9302d 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -6,29 +6,29 @@ */ export * from './legacy'; -import { useCallback, useMemo } from 'react'; +import { useCallback } from 'react'; -import { ErrorStrings } from '../../i18n'; -import { getCanvasNotifyService } from './canvas_notify_service'; import { dataViewsService } from './kibana_services'; -export const useNotifyService = () => { - const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); - return canvasNotifyService; -}; +// export const useNotifyService = () => { +// const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); +// return canvasNotifyService; +// }; export const useDataViewsService = () => { - const notifyService = useNotifyService(); + // const notifyService = useNotifyService(); const getDataViews = useCallback(async () => { try { return await dataViewsService.getIdsWithTitle(); } catch (e) { + const { ErrorStrings } = await import('../../i18n'); + const { getCanvasNotifyService } = await import('./canvas_notify_service'); const { esService: strings } = ErrorStrings; - notifyService.error(e, { title: strings.getIndicesFetchErrorMessage() }); + getCanvasNotifyService().error(e, { title: strings.getIndicesFetchErrorMessage() }); } return []; - }, [notifyService]); + }, []); const getFields = useCallback(async (dataViewTitle: string) => { const dataView = await dataViewsService.create({ title: dataViewTitle }); diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index f53b1044fe37c..90b74adc5f446 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -8,7 +8,7 @@ import { BehaviorSubject } from 'rxjs'; import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; -import type { AppUpdater, CoreStart, PluginInitializerContext } from '@kbn/core/public'; +import type { CoreStart, PluginInitializerContext } from '@kbn/core/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import type { EmbeddableStart } from '@kbn/embeddable-plugin/public/plugin'; @@ -19,13 +19,7 @@ import type { SpacesApi } from '@kbn/spaces-plugin/public'; import type { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin'; import type { VisualizationsStart } from '@kbn/visualizations-plugin/public'; -import { SESSIONSTORAGE_LASTPATH } from '../../common/lib'; -import { getSessionStorage } from '../lib/storage'; -import { CanvasStartDeps } from '../plugin'; - -export interface CanvasNavLinkService { - updatePath: (path: string) => void; -} +import type { CanvasStartDeps } from '../plugin'; export let kibanaVersion: string; @@ -41,14 +35,11 @@ export let spacesService: SpacesApi | undefined; export let uiActionsService: UiActionsPublicStart; export let visualizationsService: VisualizationsStart; -export let navLinksService: CanvasNavLinkService; - const servicesReady$ = new BehaviorSubject(false); export const setKibanaServices = ( kibanaCore: CoreStart, deps: CanvasStartDeps, - appUpdater: BehaviorSubject, initContext: PluginInitializerContext ) => { kibanaVersion = initContext.env.packageInfo.version; @@ -67,16 +58,6 @@ export const setKibanaServices = ( uiActionsService = deps.uiActions; visualizationsService = deps.visualizations; - navLinksService = { - updatePath: (path: string) => { - appUpdater.next(() => ({ - defaultPath: `${path}`, - })); - - getSessionStorage().set(`${SESSIONSTORAGE_LASTPATH}:${kibanaCore.http.basePath.get()}`, path); - }, - }; - servicesReady$.next(true); }; From 81a28ae16f6c9634b0feed1c2677f4bbd3f438d5 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 11:17:24 -0600 Subject: [PATCH 18/41] Re-add `useNotifyService` --- x-pack/plugins/canvas/public/services/index.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index 6a2aacef9302d..f38f8fa3a68c8 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -6,24 +6,22 @@ */ export * from './legacy'; -import { useCallback } from 'react'; +import { useCallback, useMemo } from 'react'; import { dataViewsService } from './kibana_services'; +import { getCanvasNotifyService } from './canvas_notify_service'; +import { ErrorStrings } from '../../i18n'; -// export const useNotifyService = () => { -// const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); -// return canvasNotifyService; -// }; +export const useNotifyService = () => { + const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); + return canvasNotifyService; +}; export const useDataViewsService = () => { - // const notifyService = useNotifyService(); - const getDataViews = useCallback(async () => { try { return await dataViewsService.getIdsWithTitle(); } catch (e) { - const { ErrorStrings } = await import('../../i18n'); - const { getCanvasNotifyService } = await import('./canvas_notify_service'); const { esService: strings } = ErrorStrings; getCanvasNotifyService().error(e, { title: strings.getIndicesFetchErrorMessage() }); } From aa88d854976348ceb53407b35e63b2325366be81 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 11:32:51 -0600 Subject: [PATCH 19/41] Remove data views service --- .../es_data_view_select.tsx | 3 +-- .../components/es_field_select/index.tsx | 7 +++-- .../es_fields_select/es_fields_select.tsx | 5 ++-- .../canvas/public/lib/data_view_helpers.ts | 26 +++++++++++++++++++ .../plugins/canvas/public/services/index.ts | 26 +------------------ 5 files changed, 33 insertions(+), 34 deletions(-) create mode 100644 x-pack/plugins/canvas/public/lib/data_view_helpers.ts diff --git a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx index d334544ee62a6..217b7c79c8e75 100644 --- a/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx +++ b/x-pack/plugins/canvas/public/components/es_data_view_select/es_data_view_select.tsx @@ -9,11 +9,11 @@ import { DataViewListItem } from '@kbn/data-views-plugin/common'; import { sortBy } from 'lodash'; import React, { FC, useRef, useState } from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; -import { useDataViewsService } from '../../services'; import { ESDataViewSelect as Component, ESDataViewSelectProps as Props, } from './es_data_view_select.component'; +import { getDataViews } from '../../lib/data_view_helpers'; type ESDataViewSelectProps = Omit; @@ -23,7 +23,6 @@ export const ESDataViewSelect: FC = (props) => { const [dataViews, setDataViews] = useState([]); const [loading, setLoading] = useState(true); const mounted = useRef(true); - const { getDataViews } = useDataViewsService(); useEffectOnce(() => { getDataViews().then((newDataViews) => { diff --git a/x-pack/plugins/canvas/public/components/es_field_select/index.tsx b/x-pack/plugins/canvas/public/components/es_field_select/index.tsx index 653eec22d77d9..f41f67bb6ee95 100644 --- a/x-pack/plugins/canvas/public/components/es_field_select/index.tsx +++ b/x-pack/plugins/canvas/public/components/es_field_select/index.tsx @@ -6,8 +6,8 @@ */ import React, { useState, useEffect, useRef } from 'react'; -import { useDataViewsService } from '../../services'; import { ESFieldSelect as Component, ESFieldSelectProps as Props } from './es_field_select'; +import { getDataViewFields } from '../../lib/data_view_helpers'; type ESFieldSelectProps = Omit; @@ -15,17 +15,16 @@ export const ESFieldSelect: React.FunctionComponent = (props const { index, value, onChange } = props; const [fields, setFields] = useState([]); const loadingFields = useRef(false); - const { getFields } = useDataViewsService(); useEffect(() => { loadingFields.current = true; - getFields(index) + getDataViewFields(index) .then((newFields) => setFields(newFields || [])) .finally(() => { loadingFields.current = false; }); - }, [index, getFields]); + }, [index]); useEffect(() => { if (!loadingFields.current && value && !fields.includes(value)) { diff --git a/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx b/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx index c929203f9e094..b10d9f52966fa 100644 --- a/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx +++ b/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx @@ -8,11 +8,11 @@ import React, { useState, useEffect, useRef } from 'react'; import { isEqual } from 'lodash'; import usePrevious from 'react-use/lib/usePrevious'; -import { useDataViewsService } from '../../services'; import { ESFieldsSelect as Component, ESFieldsSelectProps as Props, } from './es_fields_select.component'; +import { getDataViewFields } from '../../lib/data_view_helpers'; type ESFieldsSelectProps = Omit & { index: string }; @@ -21,11 +21,10 @@ export const ESFieldsSelect: React.FunctionComponent = (pro const [fields, setFields] = useState([]); const prevIndex = usePrevious(index); const mounted = useRef(true); - const { getFields } = useDataViewsService(); useEffect(() => { if (prevIndex !== index) { - getFields(index).then((newFields) => { + getDataViewFields(index).then((newFields) => { if (!mounted.current) { return; } diff --git a/x-pack/plugins/canvas/public/lib/data_view_helpers.ts b/x-pack/plugins/canvas/public/lib/data_view_helpers.ts new file mode 100644 index 0000000000000..0bec688f6788a --- /dev/null +++ b/x-pack/plugins/canvas/public/lib/data_view_helpers.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { dataViewsService } from '../services/kibana_services'; +import { getCanvasNotifyService } from '../services/canvas_notify_service'; +import { ErrorStrings } from '../../i18n'; + +export const getDataViews = async () => { + try { + return await dataViewsService.getIdsWithTitle(); + } catch (e) { + const { esService: strings } = ErrorStrings; + getCanvasNotifyService().error(e, { title: strings.getIndicesFetchErrorMessage() }); + } + return []; +}; + +export const getDataViewFields = async (dataViewTitle: string) => { + const dataView = await dataViewsService.create({ title: dataViewTitle }); + + return dataView.fields.filter((field) => !field.name.startsWith('_')).map((field) => field.name); +}; diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts index f38f8fa3a68c8..92b5f0ef3936a 100644 --- a/x-pack/plugins/canvas/public/services/index.ts +++ b/x-pack/plugins/canvas/public/services/index.ts @@ -6,35 +6,11 @@ */ export * from './legacy'; -import { useCallback, useMemo } from 'react'; +import { useMemo } from 'react'; -import { dataViewsService } from './kibana_services'; import { getCanvasNotifyService } from './canvas_notify_service'; -import { ErrorStrings } from '../../i18n'; export const useNotifyService = () => { const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []); return canvasNotifyService; }; - -export const useDataViewsService = () => { - const getDataViews = useCallback(async () => { - try { - return await dataViewsService.getIdsWithTitle(); - } catch (e) { - const { esService: strings } = ErrorStrings; - getCanvasNotifyService().error(e, { title: strings.getIndicesFetchErrorMessage() }); - } - return []; - }, []); - - const getFields = useCallback(async (dataViewTitle: string) => { - const dataView = await dataViewsService.create({ title: dataViewTitle }); - - return dataView.fields - .filter((field) => !field.name.startsWith('_')) - .map((field) => field.name); - }, []); - - return { getDataViews, getFields }; -}; From 8ebd8cea7d20bfa936a277d9946a166ecc5c98ec Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 12:17:05 -0600 Subject: [PATCH 20/41] Fix mock services --- x-pack/plugins/canvas/public/services/mocks.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/canvas/public/services/mocks.ts b/x-pack/plugins/canvas/public/services/mocks.ts index 43abd8cb2d41c..128db9dd26448 100644 --- a/x-pack/plugins/canvas/public/services/mocks.ts +++ b/x-pack/plugins/canvas/public/services/mocks.ts @@ -64,7 +64,6 @@ export const setStubKibanaServices = () => { uiActions: uiActionsPluginMock.createStartContract(), visualizations: visualizationsPluginMock.createStartContract(), }, - new BehaviorSubject(() => ({})), coreMock.createPluginInitializerContext() ); }; From 435d5c2eb4806ae7f37b692b97ab0f749b9c8040 Mon Sep 17 00:00:00 2001 From: Catherine Liu Date: Thu, 3 Oct 2024 14:00:34 -0700 Subject: [PATCH 21/41] Add filters actions --- .../plugins/canvas/public/state/actions/filters.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 x-pack/plugins/canvas/public/state/actions/filters.js diff --git a/x-pack/plugins/canvas/public/state/actions/filters.js b/x-pack/plugins/canvas/public/state/actions/filters.js new file mode 100644 index 0000000000000..3347925dc5a15 --- /dev/null +++ b/x-pack/plugins/canvas/public/state/actions/filters.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { createAction } from 'redux-actions'; +import { createThunk } from '../../lib/create_thunk'; + +export const setFilter = createThunk('setFilter', ({ dispatch }, filter, elementId) => { + const _setFilter = createAction('setFilter'); + dispatch(_setFilter({ filter, elementId })); +}); From e451ebbeb3d795cbdb42b2ff10dacd34515013a6 Mon Sep 17 00:00:00 2001 From: Catherine Liu Date: Thu, 3 Oct 2024 14:00:20 -0700 Subject: [PATCH 22/41] Fix circular deps --- .../public/services/canvas_filters_service.ts | 4 +-- .../canvas/public/state/actions/elements.js | 19 ++++------ .../canvas/public/state/reducers/elements.js | 15 ++++---- .../public/state/reducers/resolved_args.js | 10 +++--- .../canvas/public/state/reducers/transient.js | 21 +++-------- .../canvas/public/state/reducers/workpad.js | 36 +++++++++---------- 6 files changed, 42 insertions(+), 63 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/canvas_filters_service.ts b/x-pack/plugins/canvas/public/services/canvas_filters_service.ts index b46c7fbda8b33..3c956c16cd72e 100644 --- a/x-pack/plugins/canvas/public/services/canvas_filters_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_filters_service.ts @@ -10,7 +10,7 @@ import { getState, getStore } from '../state/store'; import { State } from '../../types'; import { getGlobalFilters, getWorkpadVariablesAsObject } from '../state/selectors/workpad'; // @ts-expect-error untyped local -import { setFilter } from '../state/actions/elements'; +import { setFilter } from '../state/actions/filters'; class FiltersService { constructor() {} @@ -21,7 +21,7 @@ class FiltersService { updateFilter(filterId: string, filterExpression: string) { const { dispatch } = getStore(); - dispatch(setFilter(filterExpression, filterId, true)); + dispatch(setFilter(filterExpression, filterId)); } getFiltersContext(state: State = getState()) { diff --git a/x-pack/plugins/canvas/public/state/actions/elements.js b/x-pack/plugins/canvas/public/state/actions/elements.js index 68970c40e7dc4..c9e4ddc37b6a9 100644 --- a/x-pack/plugins/canvas/public/state/actions/elements.js +++ b/x-pack/plugins/canvas/public/state/actions/elements.js @@ -27,6 +27,7 @@ import { getCanvasExpressionService } from '../../services/canvas_expressions_se import { getCanvasNotifyService } from '../../services/canvas_notify_service'; import { selectToplevelNodes } from './transient'; import * as args from './resolved_args'; +import { setFilter } from './filters'; const { actionsElements: strings } = ErrorStrings; @@ -263,18 +264,6 @@ export const removeElements = createThunk( } ); -export const setFilter = createThunk( - 'setFilter', - ({ dispatch }, filter, elementId, doRender = true) => { - const _setFilter = createAction('setFilter'); - dispatch(_setFilter({ filter, elementId })); - - if (doRender === true) { - dispatch(fetchAllRenderables()); - } - } -); - export const setExpression = createThunk('setExpression', setExpressionFn); function setExpressionFn({ dispatch, getState }, expression, elementId, pageId, doRender = true) { // dispatch action to update the element in state @@ -293,7 +282,11 @@ function setExpressionFn({ dispatch, getState }, expression, elementId, pageId, ) ) { const filter = ''; - dispatch(setFilter(filter, elementId, pageId, doRender)); + dispatch(setFilter(filter, elementId, pageId)); + + if(doRender) { + dispatch(fetchAllRenderables(updatedElement)); + } // setFilter will trigger a re-render so we can skip the fetch here } else if (doRender === true) { dispatch(fetchRenderable(updatedElement)); diff --git a/x-pack/plugins/canvas/public/state/reducers/elements.js b/x-pack/plugins/canvas/public/state/reducers/elements.js index 2be1cf519ee13..52a52a66317c4 100644 --- a/x-pack/plugins/canvas/public/state/reducers/elements.js +++ b/x-pack/plugins/canvas/public/state/reducers/elements.js @@ -8,7 +8,6 @@ import { handleActions } from 'redux-actions'; import immutable from 'object-path-immutable'; import { get } from 'lodash'; -import * as actions from '../actions/elements'; const { assign, push, del, set } = immutable; @@ -103,16 +102,16 @@ const getPageWithElementId = (workpad, elementId) => { export const elementsReducer = handleActions( { // TODO: This takes the entire element, which is not necessary, it could just take the id. - [actions.setExpression]: (workpadState, { payload }) => { + ['setExpression']: (workpadState, { payload }) => { const { expression, pageId, elementId } = payload; return assignNodeProperties(workpadState, pageId, elementId, { expression }); }, - [actions.setFilter]: (workpadState, { payload }) => { + ['setFilter']: (workpadState, { payload }) => { const { filter, elementId } = payload; const pageId = getPageWithElementId(workpadState, elementId); return assignNodeProperties(workpadState, pageId, elementId, { filter }); }, - [actions.setMultiplePositions]: (workpadState, { payload }) => + ['setMultiplePositions']: (workpadState, { payload }) => payload.repositionedElements.reduce( (previousWorkpadState, { position, pageId, elementId }) => assignNodeProperties(previousWorkpadState, pageId, elementId, { @@ -120,11 +119,11 @@ export const elementsReducer = handleActions( }), workpadState ), - [actions.elementLayer]: (workpadState, { payload: { pageId, elementId, movement } }) => { + ['elementLayer']: (workpadState, { payload: { pageId, elementId, movement } }) => { const location = getLocationFromIds(workpadState, pageId, elementId); return moveNodeLayer(workpadState, pageId, elementId, movement, location); }, - [actions.addElement]: (workpadState, { payload: { pageId, element } }) => { + ['addElement']: (workpadState, { payload: { pageId, element } }) => { const pageIndex = getPageIndexById(workpadState, pageId); if (pageIndex < 0) { return workpadState; @@ -143,7 +142,7 @@ export const elementsReducer = handleActions( trimElement(element) ); }, - [actions.insertNodes]: (workpadState, { payload: { pageId, elements } }) => { + ['insertNodes']: (workpadState, { payload: { pageId, elements } }) => { const pageIndex = getPageIndexById(workpadState, pageId); if (pageIndex < 0) { return workpadState; @@ -158,7 +157,7 @@ export const elementsReducer = handleActions( workpadState ); }, - [actions.removeElements]: (workpadState, { payload: { pageId, elementIds } }) => { + ['removeElements']: (workpadState, { payload: { pageId, elementIds } }) => { const pageIndex = getPageIndexById(workpadState, pageId); if (pageIndex < 0) { return workpadState; diff --git a/x-pack/plugins/canvas/public/state/reducers/resolved_args.js b/x-pack/plugins/canvas/public/state/reducers/resolved_args.js index 3514036cafc0d..1a03a8e6cee4c 100644 --- a/x-pack/plugins/canvas/public/state/reducers/resolved_args.js +++ b/x-pack/plugins/canvas/public/state/reducers/resolved_args.js @@ -10,8 +10,8 @@ import immutable from 'object-path-immutable'; import { get } from 'lodash'; import { prepend } from '../../lib/modify_path'; import * as actions from '../actions/resolved_args'; -import { flushContext, flushContextAfterIndex } from '../actions/elements'; -import { setWorkpad } from '../actions/workpad'; +// import { flushContext, flushContextAfterIndex } from '../actions/elements'; +// import { setWorkpad } from '../actions/workpad'; const { set, del } = immutable; /* @@ -114,14 +114,14 @@ export const resolvedArgsReducer = handleActions( /* * Flush all cached contexts */ - [flushContext]: (transientState, { payload: elementId }) => { + ['flushContext']: (transientState, { payload: elementId }) => { return del(transientState, getFullPath([elementId, 'expressionContext'])); }, /* * Flush cached context indices from the given index to the last */ - [flushContextAfterIndex]: (transientState, { payload }) => { + ['flushContextAfterIndex']: (transientState, { payload }) => { const { elementId, index } = payload; const expressionContext = get(transientState, getFullPath([elementId, 'expressionContext'])); @@ -139,7 +139,7 @@ export const resolvedArgsReducer = handleActions( return state; }, transientState); }, - [setWorkpad]: (transientState, {}) => { + ['setWorkpad']: (transientState, {}) => { return set(transientState, 'resolvedArgs', {}); }, }, diff --git a/x-pack/plugins/canvas/public/state/reducers/transient.js b/x-pack/plugins/canvas/public/state/reducers/transient.js index e41ab5e4822a9..e2591121418fc 100644 --- a/x-pack/plugins/canvas/public/state/reducers/transient.js +++ b/x-pack/plugins/canvas/public/state/reducers/transient.js @@ -10,10 +10,8 @@ import immutable from 'object-path-immutable'; import { restoreHistory } from '../actions/history'; import * as pageActions from '../actions/pages'; import * as transientActions from '../actions/transient'; -import { removeElements } from '../actions/elements'; -import { setRefreshInterval, enableAutoplay, setAutoplayInterval } from '../actions/workpad'; -const { set, del } = immutable; +const { set } = immutable; export const transientReducer = handleActions( { @@ -21,17 +19,6 @@ export const transientReducer = handleActions( // TODO: we shouldn't need to reset the resolved args for history [restoreHistory]: (transientState) => set(transientState, 'resolvedArgs', {}), - [removeElements]: (transientState, { payload: { elementIds } }) => { - const { selectedToplevelNodes } = transientState; - return del( - { - ...transientState, - selectedToplevelNodes: selectedToplevelNodes.filter((n) => elementIds.indexOf(n) < 0), - }, - ['resolvedArgs', elementIds] - ); - }, - [transientActions.setFirstLoad]: (transientState, { payload }) => { return set(transientState, 'isFirstLoad', Boolean(payload)); }, @@ -70,15 +57,15 @@ export const transientReducer = handleActions( return { ...transientState, selectedToplevelNodes: [] }; }, - [setRefreshInterval]: (transientState, { payload }) => { + ['setRefreshInterval']: (transientState, { payload }) => { return { ...transientState, refresh: { interval: Number(payload) || 0 } }; }, - [enableAutoplay]: (transientState, { payload }) => { + ['enableAutoplay']: (transientState, { payload }) => { return set(transientState, 'autoplay.enabled', Boolean(payload) || false); }, - [setAutoplayInterval]: (transientState, { payload }) => { + ['setAutoplayInterval']: (transientState, { payload }) => { return set(transientState, 'autoplay.interval', Number(payload) || 0); }, }, diff --git a/x-pack/plugins/canvas/public/state/reducers/workpad.js b/x-pack/plugins/canvas/public/state/reducers/workpad.js index 61ff2dc8978be..9fc9d45299ebe 100644 --- a/x-pack/plugins/canvas/public/state/reducers/workpad.js +++ b/x-pack/plugins/canvas/public/state/reducers/workpad.js @@ -8,22 +8,22 @@ import { handleActions } from 'redux-actions'; import { coreServices } from '../../services/kibana_services'; import { getDefaultWorkpad } from '../defaults'; -import { - setWorkpad, - sizeWorkpad, - setColors, - setName, - setWriteable, - setWorkpadCSS, - setWorkpadVariables, - resetWorkpad, -} from '../actions/workpad'; +// import { +// setWorkpad, +// sizeWorkpad, +// setColors, +// setName, +// setWriteable, +// setWorkpadCSS, +// setWorkpadVariables, +// resetWorkpad, +// } from '../actions/workpad'; import { APP_ROUTE_WORKPAD } from '../../../common/lib/constants'; export const workpadReducer = handleActions( { - [setWorkpad]: (workpadState, { payload }) => { + ['setWorkpad']: (workpadState, { payload }) => { coreServices.chrome.recentlyAccessed.add( `${APP_ROUTE_WORKPAD}/${payload.id}`, payload.name, @@ -32,15 +32,15 @@ export const workpadReducer = handleActions( return payload; }, - [sizeWorkpad]: (workpadState, { payload }) => { + ['sizeWorkpad']: (workpadState, { payload }) => { return { ...workpadState, ...payload }; }, - [setColors]: (workpadState, { payload }) => { + ['setColors']: (workpadState, { payload }) => { return { ...workpadState, colors: payload }; }, - [setName]: (workpadState, { payload }) => { + ['setName']: (workpadState, { payload }) => { coreServices.chrome.recentlyAccessed.add( `${APP_ROUTE_WORKPAD}/${workpadState.id}`, payload, @@ -49,19 +49,19 @@ export const workpadReducer = handleActions( return { ...workpadState, name: payload }; }, - [setWriteable]: (workpadState, { payload }) => { + ['setWriteable']: (workpadState, { payload }) => { return { ...workpadState, isWriteable: Boolean(payload) }; }, - [setWorkpadCSS]: (workpadState, { payload }) => { + ['setWorkpadCSS']: (workpadState, { payload }) => { return { ...workpadState, css: payload }; }, - [setWorkpadVariables]: (workpadState, { payload }) => { + ['setWorkpadVariables']: (workpadState, { payload }) => { return { ...workpadState, variables: payload }; }, - [resetWorkpad]: () => ({ ...getDefaultWorkpad() }), + ['resetWorkpad']: () => ({ ...getDefaultWorkpad() }), }, {} ); From 0988e322626f04299b7ebeb901d2a499a35d71fc Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 15:43:16 -0600 Subject: [PATCH 23/41] Cleanup + fix undefined expression service --- .../components/function_form_list/index.js | 2 +- .../canvas/public/state/reducers/elements.js | 1 - .../canvas/public/state/reducers/transient.js | 34 ++++++++++++------- .../canvas/public/state/reducers/workpad.js | 10 ------ 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/x-pack/plugins/canvas/public/components/function_form_list/index.js b/x-pack/plugins/canvas/public/components/function_form_list/index.js index 53ce940563887..6de7b81b12b01 100644 --- a/x-pack/plugins/canvas/public/components/function_form_list/index.js +++ b/x-pack/plugins/canvas/public/components/function_form_list/index.js @@ -78,7 +78,7 @@ const componentFactory = ({ parentPath, removable, }) => { - const { expressions } = getCanvasExpressionService(); + const expressions = getCanvasExpressionService(); return { args, nestedFunctionsArgs: argsWithExprFunctions, diff --git a/x-pack/plugins/canvas/public/state/reducers/elements.js b/x-pack/plugins/canvas/public/state/reducers/elements.js index 52a52a66317c4..fdb15a5621222 100644 --- a/x-pack/plugins/canvas/public/state/reducers/elements.js +++ b/x-pack/plugins/canvas/public/state/reducers/elements.js @@ -101,7 +101,6 @@ const getPageWithElementId = (workpad, elementId) => { export const elementsReducer = handleActions( { - // TODO: This takes the entire element, which is not necessary, it could just take the id. ['setExpression']: (workpadState, { payload }) => { const { expression, pageId, elementId } = payload; return assignNodeProperties(workpadState, pageId, elementId, { expression }); diff --git a/x-pack/plugins/canvas/public/state/reducers/transient.js b/x-pack/plugins/canvas/public/state/reducers/transient.js index e2591121418fc..2f0e7bd66126c 100644 --- a/x-pack/plugins/canvas/public/state/reducers/transient.js +++ b/x-pack/plugins/canvas/public/state/reducers/transient.js @@ -7,53 +7,61 @@ import { handleActions } from 'redux-actions'; import immutable from 'object-path-immutable'; -import { restoreHistory } from '../actions/history'; -import * as pageActions from '../actions/pages'; -import * as transientActions from '../actions/transient'; -const { set } = immutable; +const { set, del } = immutable; export const transientReducer = handleActions( { // clear all the resolved args when restoring the history // TODO: we shouldn't need to reset the resolved args for history - [restoreHistory]: (transientState) => set(transientState, 'resolvedArgs', {}), + ['restoreHistory']: (transientState) => set(transientState, 'resolvedArgs', {}), - [transientActions.setFirstLoad]: (transientState, { payload }) => { + ['removeElements']: (transientState, { payload: { elementIds } }) => { + const { selectedToplevelNodes } = transientState; + return del( + { + ...transientState, + selectedToplevelNodes: selectedToplevelNodes.filter((n) => elementIds.indexOf(n) < 0), + }, + ['resolvedArgs', elementIds] + ); + }, + + ['setFirstLoad']: (transientState, { payload }) => { return set(transientState, 'isFirstLoad', Boolean(payload)); }, - [transientActions.setFullscreen]: (transientState, { payload }) => { + ['setFullscreen']: (transientState, { payload }) => { return set(transientState, 'fullscreen', Boolean(payload)); }, - [transientActions.setElementStats]: (transientState, { payload }) => { + ['setElementStats']: (transientState, { payload }) => { return set(transientState, 'elementStats', payload); }, - [transientActions.selectToplevelNodes]: (transientState, { payload }) => { + ['selectToplevelNodes']: (transientState, { payload }) => { return { ...transientState, selectedToplevelNodes: payload, }; }, - [transientActions.setZoomScale]: (transientState, { payload }) => { + ['setZoomScale']: (transientState, { payload }) => { return { ...transientState, zoomScale: payload || 1, }; }, - [pageActions.setPage]: (transientState) => { + ['setPage']: (transientState) => { return { ...transientState, selectedToplevelNodes: [] }; }, - [pageActions.addPage]: (transientState) => { + ['addPage']: (transientState) => { return { ...transientState, selectedToplevelNodes: [] }; }, - [pageActions.duplicatePage]: (transientState) => { + ['duplicatePage']: (transientState) => { return { ...transientState, selectedToplevelNodes: [] }; }, diff --git a/x-pack/plugins/canvas/public/state/reducers/workpad.js b/x-pack/plugins/canvas/public/state/reducers/workpad.js index 9fc9d45299ebe..9c337f965ae3a 100644 --- a/x-pack/plugins/canvas/public/state/reducers/workpad.js +++ b/x-pack/plugins/canvas/public/state/reducers/workpad.js @@ -8,16 +8,6 @@ import { handleActions } from 'redux-actions'; import { coreServices } from '../../services/kibana_services'; import { getDefaultWorkpad } from '../defaults'; -// import { -// setWorkpad, -// sizeWorkpad, -// setColors, -// setName, -// setWriteable, -// setWorkpadCSS, -// setWorkpadVariables, -// resetWorkpad, -// } from '../actions/workpad'; import { APP_ROUTE_WORKPAD } from '../../../common/lib/constants'; From 6bccb2247196a2207191be4c5dd83f4da9b9674e Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 15:47:19 -0600 Subject: [PATCH 24/41] Add fetch all renderables --- x-pack/plugins/canvas/public/lib/create_handlers.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugins/canvas/public/lib/create_handlers.ts b/x-pack/plugins/canvas/public/lib/create_handlers.ts index 43ef4a3e8b97d..8b78914d77071 100644 --- a/x-pack/plugins/canvas/public/lib/create_handlers.ts +++ b/x-pack/plugins/canvas/public/lib/create_handlers.ts @@ -14,6 +14,8 @@ import { updateEmbeddableExpression, fetchEmbeddableRenderable } from '../state/ import { RendererHandlers, CanvasElement } from '../../types'; import { getCanvasFiltersService } from '../services/canvas_filters_service'; import { clearValue } from '../state/actions/resolved_args'; +// @ts-expect-error unconverted file +import { fetchAllRenderables } from '../state/actions/elements'; // This class creates stub handlers to ensure every element and renderer fulfills the contract. // TODO: consider warning if these methods are invoked but not implemented by the renderer...? @@ -94,6 +96,7 @@ export const createDispatchedHandlerFactory = ( break; case 'applyFilterAction': filters.updateFilter(element.id, event.data); + dispatch(fetchAllRenderables()); break; case 'onComplete': this.onComplete(event.data); From ad5231dffe3aee8cf57a54ad8b75fdfcdf02c37c Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 15:48:00 -0600 Subject: [PATCH 25/41] Clean up commented out imports --- x-pack/plugins/canvas/public/state/reducers/resolved_args.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/plugins/canvas/public/state/reducers/resolved_args.js b/x-pack/plugins/canvas/public/state/reducers/resolved_args.js index 1a03a8e6cee4c..3652a8d462fb8 100644 --- a/x-pack/plugins/canvas/public/state/reducers/resolved_args.js +++ b/x-pack/plugins/canvas/public/state/reducers/resolved_args.js @@ -10,8 +10,6 @@ import immutable from 'object-path-immutable'; import { get } from 'lodash'; import { prepend } from '../../lib/modify_path'; import * as actions from '../actions/resolved_args'; -// import { flushContext, flushContextAfterIndex } from '../actions/elements'; -// import { setWorkpad } from '../actions/workpad'; const { set, del } = immutable; /* From ce06331b8d93ad695913f20f54eb7d74dc756144 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 15:50:21 -0600 Subject: [PATCH 26/41] Remove unused imports --- x-pack/plugins/canvas/public/services/mocks.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/mocks.ts b/x-pack/plugins/canvas/public/services/mocks.ts index 128db9dd26448..80d46a13e3a98 100644 --- a/x-pack/plugins/canvas/public/services/mocks.ts +++ b/x-pack/plugins/canvas/public/services/mocks.ts @@ -5,12 +5,11 @@ * 2.0. */ -import { BehaviorSubject } from 'rxjs'; import moment from 'moment'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { contentManagementMock } from '@kbn/content-management-plugin/public/mocks'; -import { AppUpdater, CoreStart } from '@kbn/core/public'; +import { CoreStart } from '@kbn/core/public'; import { coreMock } from '@kbn/core/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; From 0b7dade32b78448f7288cd94b871cda6bb24c065 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Thu, 3 Oct 2024 15:51:38 -0600 Subject: [PATCH 27/41] Fix linting --- x-pack/plugins/canvas/public/state/actions/elements.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/canvas/public/state/actions/elements.js b/x-pack/plugins/canvas/public/state/actions/elements.js index c9e4ddc37b6a9..57b7da1ce1fef 100644 --- a/x-pack/plugins/canvas/public/state/actions/elements.js +++ b/x-pack/plugins/canvas/public/state/actions/elements.js @@ -284,7 +284,7 @@ function setExpressionFn({ dispatch, getState }, expression, elementId, pageId, const filter = ''; dispatch(setFilter(filter, elementId, pageId)); - if(doRender) { + if (doRender) { dispatch(fetchAllRenderables(updatedElement)); } // setFilter will trigger a re-render so we can skip the fetch here From 6acbf926a3a7716ce7573031a58961992f30368d Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Fri, 4 Oct 2024 13:12:35 -0600 Subject: [PATCH 28/41] Fix unit tests --- .../__snapshots__/app.test.tsx.snap | 2 +- .../shareable_runtime/components/app.test.tsx | 14 ++++++------- .../__snapshots__/settings.test.tsx.snap | 20 ++++++++++++++----- .../footer/settings/settings.test.tsx | 14 +++++++------ .../shareable_runtime/test/selectors.ts | 2 +- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__snapshots__/app.test.tsx.snap b/x-pack/plugins/canvas/shareable_runtime/components/__snapshots__/app.test.tsx.snap index 010847e63a023..4aa379aa194bc 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/__snapshots__/app.test.tsx.snap +++ b/x-pack/plugins/canvas/shareable_runtime/components/__snapshots__/app.test.tsx.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` App renders properly 1`] = `"
markdown mock
markdown mock

Page level controls

My Canvas Workpad

There is a new region landmark with page level controls at the end of the document.

"`; +exports[` App renders properly 1`] = `"
markdown mock
markdown mock

Page level controls

My Canvas Workpad

There is a new region landmark with page level controls at the end of the document.

"`; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/app.test.tsx b/x-pack/plugins/canvas/shareable_runtime/components/app.test.tsx index ec4ea09e8fcc7..30d55c8531b1d 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/app.test.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/app.test.tsx @@ -13,6 +13,7 @@ import { mount, ReactWrapper } from 'enzyme'; import React from 'react'; + // import { act } from 'react-dom/test-utils'; import { App } from './app'; import { sharedWorkpads, WorkpadNames, tick } from '../test'; @@ -34,17 +35,14 @@ import { openSettings, selectMenuItem } from '../test/interactions'; // Mock the renderers jest.mock('../supported_renderers'); +// @ts-ignore Importing this to mock +import * as Portal from '@elastic/eui/lib/components/portal/portal'; + // Mock the EuiPortal - `insertAdjacentElement is not supported in // `jsdom` 12. We're just going to render a `div` with the children // so the `enzyme` tests will be accurate. -jest.mock('@elastic/eui/lib/components/portal/portal', () => { - // Local constants are not supported in Jest mocks-- they must be - // imported within the mock. - // eslint-disable-next-line @typescript-eslint/no-shadow - const React = jest.requireActual('react'); - return { - EuiPortal: (props: any) =>
{props.children}
, - }; +jest.spyOn(Portal, 'EuiPortal').mockImplementation((props: any) => { + return
{props.children}
; }); const getWrapper: (name?: WorkpadNames) => ReactWrapper = (name = 'hello') => { diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__snapshots__/settings.test.tsx.snap b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__snapshots__/settings.test.tsx.snap index bf66b5df800ec..cfe41427b1ea1 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__snapshots__/settings.test.tsx.snap +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__snapshots__/settings.test.tsx.snap @@ -1,7 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` can navigate Autoplay Settings 1`] = ` -
+
@@ -94,7 +96,9 @@ exports[` can navigate Autoplay Settings 1`] = ` `; exports[` can navigate Autoplay Settings 2`] = ` -
+
@@ -338,7 +342,9 @@ exports[` can navigate Autoplay Settings 2`] = ` `; exports[` can navigate Toolbar Settings, closes when activated 1`] = ` -
+
@@ -431,7 +437,9 @@ exports[` can navigate Toolbar Settings, closes when activated 1`] = `; exports[` can navigate Toolbar Settings, closes when activated 2`] = ` -
+
@@ -606,7 +614,9 @@ exports[` can navigate Toolbar Settings, closes when activated 2`] = `; exports[` can navigate Toolbar Settings, closes when activated 3`] = ` -
+
diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/settings.test.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/settings.test.tsx index cc275dd983e3c..0ab9e13e36765 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/settings.test.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/settings.test.tsx @@ -21,12 +21,14 @@ import { Settings } from './settings'; jest.mock('../../../supported_renderers'); -jest.mock('@elastic/eui/lib/components/portal/portal', () => { - // eslint-disable-next-line @typescript-eslint/no-shadow - const React = jest.requireActual('react'); - return { - EuiPortal: (props: any) =>
{props.children}
, - }; +// @ts-ignore Importing this to mock +import * as Portal from '@elastic/eui/lib/components/portal/portal'; + +// Mock the EuiPortal - `insertAdjacentElement is not supported in +// `jsdom` 12. We're just going to render a `div` with the children +// so the `enzyme` tests will be accurate. +jest.spyOn(Portal, 'EuiPortal').mockImplementation((props: any) => { + return
{props.children}
; }); describe('', () => { diff --git a/x-pack/plugins/canvas/shareable_runtime/test/selectors.ts b/x-pack/plugins/canvas/shareable_runtime/test/selectors.ts index bcfe94adf94be..f4d4f8ac442d7 100644 --- a/x-pack/plugins/canvas/shareable_runtime/test/selectors.ts +++ b/x-pack/plugins/canvas/shareable_runtime/test/selectors.ts @@ -42,7 +42,7 @@ export const getSettingsTrigger = (wrapper: ReactWrapper) => export const getPopover = (wrapper: ReactWrapper) => wrapper.find('EuiPopover'); -export const getPortal = (wrapper: ReactWrapper) => wrapper.find('EuiPortal'); +export const getPortal = (wrapper: ReactWrapper) => wrapper.find('.mockedEuiPortal'); export const getContextMenu = (wrapper: ReactWrapper) => wrapper.find('EuiContextMenuClass'); From fe41745ad579bfda2a0afd0b17af395fc85c375d Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Fri, 4 Oct 2024 13:49:24 -0600 Subject: [PATCH 29/41] Fix custom element service --- .../services/canvas_custom_element_service.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts b/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts index 4b96351cee39d..1f0e13d2fbeae 100644 --- a/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_custom_element_service.ts @@ -18,25 +18,31 @@ class CanvasCustomElementService { public apiPath = `${API_ROUTE_CUSTOM_ELEMENT}`; public async create(customElement: CustomElement) { - coreServices.http.post(this.apiPath, { body: JSON.stringify(customElement), version: '1' }); + await coreServices.http.post(this.apiPath, { + body: JSON.stringify(customElement), + version: '1', + }); } public async get(customElementId: string): Promise { - return coreServices.http + return await coreServices.http .get<{ data: CustomElement }>(`${this.apiPath}/${customElementId}`, { version: '1' }) .then(({ data: element }) => element); } public async update(id: string, element: Partial) { - coreServices.http.put(`${this.apiPath}/${id}`, { body: JSON.stringify(element), version: '1' }); + await coreServices.http.put(`${this.apiPath}/${id}`, { + body: JSON.stringify(element), + version: '1', + }); } public async remove(id: string) { - coreServices.http.delete(`${this.apiPath}/${id}`, { version: '1' }); + await coreServices.http.delete(`${this.apiPath}/${id}`, { version: '1' }); } public async find(searchTerm: string): Promise { - return coreServices.http.get(`${this.apiPath}/find`, { + return await coreServices.http.get(`${this.apiPath}/find`, { query: { name: searchTerm, perPage: 10000, From 4aede23a315e6ac7c60531dfd3a3cde072b594f6 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Fri, 4 Oct 2024 14:17:10 -0600 Subject: [PATCH 30/41] Fix embeddable update --- x-pack/plugins/canvas/public/state/reducers/embeddable.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/canvas/public/state/reducers/embeddable.ts b/x-pack/plugins/canvas/public/state/reducers/embeddable.ts index 5b963e2c80c7e..8f79ed529cd96 100644 --- a/x-pack/plugins/canvas/public/state/reducers/embeddable.ts +++ b/x-pack/plugins/canvas/public/state/reducers/embeddable.ts @@ -9,10 +9,7 @@ import { fromExpression, toExpression } from '@kbn/interpreter'; import { handleActions } from 'redux-actions'; import { State } from '../../../types'; -import { - UpdateEmbeddableExpressionActionType, - UpdateEmbeddableExpressionPayload, -} from '../actions/embeddable'; +import { UpdateEmbeddableExpressionPayload } from '../actions/embeddable'; // @ts-expect-error untyped local import { assignNodeProperties } from './elements'; @@ -22,7 +19,7 @@ export const embeddableReducer = handleActions< UpdateEmbeddableExpressionPayload >( { - [UpdateEmbeddableExpressionActionType]: (workpadState, { payload }) => { + ['updateEmbeddableExpression']: (workpadState, { payload }) => { if (!payload) { return workpadState; } From e1c74da8d44b1eee4a64b2807b39dd57fbeda437 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Fri, 4 Oct 2024 15:18:36 -0600 Subject: [PATCH 31/41] Fix linting --- .../public/components/es_fields_select/es_fields_select.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx b/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx index b10d9f52966fa..0cde66199b4b3 100644 --- a/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx +++ b/x-pack/plugins/canvas/public/components/es_fields_select/es_fields_select.tsx @@ -36,7 +36,7 @@ export const ESFieldsSelect: React.FunctionComponent = (pro } }); } - }, [fields, index, onChange, prevIndex, selected, getFields]); + }, [fields, index, onChange, prevIndex, selected]); useEffect( () => () => { From 60b695e897e06c022867759f2d236bb8fb1a8d00 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Fri, 4 Oct 2024 16:22:27 -0600 Subject: [PATCH 32/41] Clean up? --- .../canvas/public/services/canvas_expressions_service.ts | 4 ++-- .../plugins/canvas/public/services/canvas_filters_service.ts | 2 -- .../plugins/canvas/public/services/canvas_workpad_service.ts | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts b/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts index 09f92e6998b04..0621c3e89416c 100644 --- a/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_expressions_service.ts @@ -21,8 +21,8 @@ interface Options { } class ExpressionsService { - public notifyService; - public filtersService; + private notifyService; + private filtersService; constructor() { this.notifyService = getCanvasNotifyService(); diff --git a/x-pack/plugins/canvas/public/services/canvas_filters_service.ts b/x-pack/plugins/canvas/public/services/canvas_filters_service.ts index 3c956c16cd72e..e678e9b30963f 100644 --- a/x-pack/plugins/canvas/public/services/canvas_filters_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_filters_service.ts @@ -13,8 +13,6 @@ import { getGlobalFilters, getWorkpadVariablesAsObject } from '../state/selector import { setFilter } from '../state/actions/filters'; class FiltersService { - constructor() {} - getFilters(state: State = getState()) { return getGlobalFilters(state); } diff --git a/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts index a54d02d09e4af..2672f6ef4a06e 100644 --- a/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_workpad_service.ts @@ -68,7 +68,7 @@ const sanitizeWorkpad = function (workpad: CanvasWorkpad) { }; class CanvasWorkpadService { - public apiPath = `${API_ROUTE_WORKPAD}`; + private apiPath = `${API_ROUTE_WORKPAD}`; public async get(id: string): Promise { const workpad = await coreServices.http.get(`${this.apiPath}/${id}`, { version: '1' }); From 35221929bec4b2bd46ccbd8771d807bc9e8d680c Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Mon, 7 Oct 2024 08:25:35 -0600 Subject: [PATCH 33/41] Try to fix linting error --- .../public/services/canvas_notify_service.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/canvas_notify_service.ts b/x-pack/plugins/canvas/public/services/canvas_notify_service.ts index f836d0590bbfc..1f00190f3fff9 100644 --- a/x-pack/plugins/canvas/public/services/canvas_notify_service.ts +++ b/x-pack/plugins/canvas/public/services/canvas_notify_service.ts @@ -11,13 +11,6 @@ import { ToastInputFields } from '@kbn/core/public'; import { formatMsg } from '../lib/format_msg'; import { coreServices } from './kibana_services'; -interface CanvasNotifyService { - error: (err: string | Error, opts?: ToastInputFields) => void; - warning: (err: string | Error, opts?: ToastInputFields) => void; - info: (err: string | Error, opts?: ToastInputFields) => void; - success: (err: string | Error, opts?: ToastInputFields) => void; -} - const getToast = (err: Error | string, opts: ToastInputFields = {}) => { const errData = (get(err, 'response') || err) as Error | string; const errBody = get(err, 'body', undefined); @@ -36,6 +29,13 @@ const getToast = (err: Error | string, opts: ToastInputFields = {}) => { }; }; +export interface CanvasNotifyService { + error: (err: string | Error, opts?: ToastInputFields) => void; + warning: (err: string | Error, opts?: ToastInputFields) => void; + info: (err: string | Error, opts?: ToastInputFields) => void; + success: (err: string | Error, opts?: ToastInputFields) => void; +} + export const getCanvasNotifyService = (): CanvasNotifyService => { const toasts = coreServices.notifications.toasts; From 9ccfb0c5e6019302b3bfa514c87a1ad8af0829c2 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Mon, 7 Oct 2024 10:56:32 -0600 Subject: [PATCH 34/41] Fix reporting service --- x-pack/plugins/canvas/public/services/kibana_services.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index 90b74adc5f446..a46723ac738ac 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -51,9 +51,11 @@ export const setKibanaServices = ( embeddableService = deps.embeddable; expressionsService = deps.expressions; presentationUtilService = deps.presentationUtil; - reportingService = kibanaCore.application.capabilities.canvas?.generatePdf - ? deps.reporting - : undefined; + reportingService = + deps.reporting.usesUiCapabilities() && + !Boolean(kibanaCore.application.capabilities.canvas?.generatePdf) + ? undefined + : deps.reporting; spacesService = deps.spaces; uiActionsService = deps.uiActions; visualizationsService = deps.visualizations; From 452bd899aaf0c712d119ce2479439fe9d06a2aef Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Mon, 7 Oct 2024 12:02:44 -0600 Subject: [PATCH 35/41] Fix undefined reporting --- .../plugins/canvas/public/services/kibana_services.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/canvas/public/services/kibana_services.ts b/x-pack/plugins/canvas/public/services/kibana_services.ts index a46723ac738ac..2b966e698a874 100644 --- a/x-pack/plugins/canvas/public/services/kibana_services.ts +++ b/x-pack/plugins/canvas/public/services/kibana_services.ts @@ -51,11 +51,11 @@ export const setKibanaServices = ( embeddableService = deps.embeddable; expressionsService = deps.expressions; presentationUtilService = deps.presentationUtil; - reportingService = - deps.reporting.usesUiCapabilities() && - !Boolean(kibanaCore.application.capabilities.canvas?.generatePdf) - ? undefined - : deps.reporting; + reportingService = Boolean( + deps.reporting?.usesUiCapabilities() && !kibanaCore.application.capabilities.canvas?.generatePdf + ) + ? undefined + : deps.reporting; spacesService = deps.spaces; uiActionsService = deps.uiActions; visualizationsService = deps.visualizations; From f6d892d1c9050c2f46d6b81411f86cd0f2c7e2a1 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Mon, 7 Oct 2024 16:01:56 -0600 Subject: [PATCH 36/41] Small cleanups --- .../share_menu/flyout/hooks/use_download_runtime.ts | 2 +- x-pack/plugins/canvas/public/lib/template_service.ts | 2 +- .../plugins/canvas/public/routes/workpad/hooks/use_workpad.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts index 0998e91f50a1b..49bd93c290ce8 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts +++ b/x-pack/plugins/canvas/public/components/workpad_header/share_menu/flyout/hooks/use_download_runtime.ts @@ -41,7 +41,7 @@ export const useDownloadRuntime = () => { const downloadRuntime = useCallback(() => { try { - const path = `${coreServices.http.basePath.get}${API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD}`; + const path = `${coreServices.http.basePath.get()}${API_ROUTE_SHAREABLE_RUNTIME_DOWNLOAD}`; window.open(path); return; } catch (err) { diff --git a/x-pack/plugins/canvas/public/lib/template_service.ts b/x-pack/plugins/canvas/public/lib/template_service.ts index cdcf0976f3ce8..481733b781d85 100644 --- a/x-pack/plugins/canvas/public/lib/template_service.ts +++ b/x-pack/plugins/canvas/public/lib/template_service.ts @@ -13,7 +13,7 @@ import { CanvasTemplate } from '../../types'; import { coreServices } from '../services/kibana_services'; const getApiPath = function () { - const basePath = coreServices.http.basePath.get; + const basePath = coreServices.http.basePath.get(); return `${basePath}${API_ROUTE_TEMPLATES}`; }; diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts index 152256d0188ba..c02432477a840 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_workpad.ts @@ -75,7 +75,7 @@ export const useWorkpad = ( const { aliasId, outcome, aliasPurpose } = resolveInfo; if (outcome === 'aliasMatch' && spacesService && aliasId) { const redirectPath = getRedirectPath(aliasId); - await spacesService?.ui.redirectLegacyUrl({ + await spacesService.ui.redirectLegacyUrl({ path: `#${redirectPath}`, aliasPurpose, objectNoun: getWorkpadLabel(), From 7b2eae77ddf5e339dae9327e6e33c1bcda14a9be Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 8 Oct 2024 09:21:17 -0600 Subject: [PATCH 37/41] Fix merge conflicts --- x-pack/plugins/canvas/public/application.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/canvas/public/application.tsx b/x-pack/plugins/canvas/public/application.tsx index e09cda760057c..be5544d5c6222 100644 --- a/x-pack/plugins/canvas/public/application.tsx +++ b/x-pack/plugins/canvas/public/application.tsx @@ -65,13 +65,11 @@ export const renderApp = ({ ReactDOM.render( - - - - - - - + + + {' '} + + , element From 71b386d1e1edd28d6e541e456c9f461d1a77f0d1 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 8 Oct 2024 09:29:51 -0600 Subject: [PATCH 38/41] Remove space from HTML --- x-pack/plugins/canvas/public/application.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/canvas/public/application.tsx b/x-pack/plugins/canvas/public/application.tsx index be5544d5c6222..222b64e4175e9 100644 --- a/x-pack/plugins/canvas/public/application.tsx +++ b/x-pack/plugins/canvas/public/application.tsx @@ -67,7 +67,7 @@ export const renderApp = ({ - {' '} + From ee5edadd98081c23f65937c6010d3b5082a4a716 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 8 Oct 2024 10:38:51 -0600 Subject: [PATCH 39/41] Remove `core` from presentation util --- x-pack/plugins/canvas/public/services/mocks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/canvas/public/services/mocks.ts b/x-pack/plugins/canvas/public/services/mocks.ts index 80d46a13e3a98..c35d8834253be 100644 --- a/x-pack/plugins/canvas/public/services/mocks.ts +++ b/x-pack/plugins/canvas/public/services/mocks.ts @@ -57,7 +57,7 @@ export const setStubKibanaServices = () => { embeddable: embeddablePluginMock.createStartContract(), expressions: expressionsPluginMock.createStartContract(), inspector: inspectorPluginMock.createStartContract(), - presentationUtil: presentationUtilPluginMock.createStartContract(core), + presentationUtil: presentationUtilPluginMock.createStartContract(), reporting: reportingPluginMock.createStartContract(), spaces: spacesPluginMock.createStartContract(), uiActions: uiActionsPluginMock.createStartContract(), From 78ee22bf218055686f3659cf75fd8bfb7b494504 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 8 Oct 2024 11:51:34 -0600 Subject: [PATCH 40/41] Review feedback --- .../plugins/canvas/public/components/app/index.tsx | 2 +- .../public/components/embeddable_flyout/flyout.tsx | 5 +++-- .../hooks/use_fullscreen_presentation_helper.ts | 14 ++++---------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/canvas/public/components/app/index.tsx b/x-pack/plugins/canvas/public/components/app/index.tsx index 5874c1e1ad468..0ae3fcf95e6be 100644 --- a/x-pack/plugins/canvas/public/components/app/index.tsx +++ b/x-pack/plugins/canvas/public/components/app/index.tsx @@ -39,7 +39,7 @@ export const App: FC<{ history: ScopedHistory; appUpdater: BehaviorSubject { const path = pathname + search; appUpdater.next(() => ({ - defaultPath: `${path}`, + defaultPath: path, })); getSessionStorage().set( diff --git a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx index 9d9b87fd3b446..3ecabeb8974f1 100644 --- a/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx +++ b/x-pack/plugins/canvas/public/components/embeddable_flyout/flyout.tsx @@ -67,8 +67,9 @@ export const AddEmbeddablePanel: React.FunctionComponent = ({ availableEmbeddables, ...restProps }) => { - const labsService = useMemo(() => presentationUtilService.labsService, []); - const isByValueEnabled = labsService.isProjectEnabled('labs:canvas:byValueEmbeddable'); + const isByValueEnabled = presentationUtilService.labsService.isProjectEnabled( + 'labs:canvas:byValueEmbeddable' + ); const dispatch = useDispatch(); const pageId = useSelector((state) => getSelectedPage(state)); diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts index 3e6837ca77b43..ca08605918420 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts @@ -13,29 +13,23 @@ const fullscreenClass = 'canvas-isFullscreen'; export const useFullscreenPresentationHelper = () => { const { isFullscreen } = useContext(WorkpadRoutingContext); - - const setFullscreen = useCallback( - (fullscreen: boolean) => coreServices.chrome.setIsVisible(fullscreen), - [] - ); - useEffect(() => { const body = document.querySelector('body'); const bodyClassList = body!.classList; const hasFullscreenClass = bodyClassList.contains(fullscreenClass); if (isFullscreen && !hasFullscreenClass) { - setFullscreen(false); + coreServices.chrome.setIsVisible(false); bodyClassList.add(fullscreenClass); } else if (!isFullscreen && hasFullscreenClass) { bodyClassList.remove(fullscreenClass); - setFullscreen(true); + coreServices.chrome.setIsVisible(true); } - }, [setFullscreen, isFullscreen]); + }, [isFullscreen]); // Remove fullscreen when component unmounts useEffectOnce(() => () => { - setFullscreen(true); + coreServices.chrome.setIsVisible(true); document.querySelector('body')?.classList.remove(fullscreenClass); }); }; From ad95d9cc26dc703d94a28363497af2437c585b8c Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Tue, 8 Oct 2024 12:52:42 -0600 Subject: [PATCH 41/41] Remove unused import --- .../routes/workpad/hooks/use_fullscreen_presentation_helper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts index ca08605918420..e517f74030c87 100644 --- a/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts +++ b/x-pack/plugins/canvas/public/routes/workpad/hooks/use_fullscreen_presentation_helper.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useCallback, useContext, useEffect } from 'react'; +import { useContext, useEffect } from 'react'; import useEffectOnce from 'react-use/lib/useEffectOnce'; import { WorkpadRoutingContext } from '..'; import { coreServices } from '../../../services/kibana_services';