[canvas] Create Platform Service; remove legacy service (#104113)

This commit is contained in:
Clint Andrew Hall 2021-07-01 16:49:52 -04:00 committed by GitHub
parent 975e361d50
commit cb163c9139
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 180 additions and 164 deletions

View file

@ -13,7 +13,7 @@ import {
SavedObjectFinderUi,
SavedObjectMetaData,
} from '../../../../../../src/plugins/saved_objects/public/';
import { useServices } from '../../services';
import { usePlatformService, useServices } from '../../services';
const strings = {
getNoItemsText: () =>
@ -33,9 +33,10 @@ export interface Props {
export const AddEmbeddableFlyout: FC<Props> = ({ onSelect, availableEmbeddables, onClose }) => {
const services = useServices();
const { embeddables, platform } = services;
const platformService = usePlatformService();
const { embeddables } = services;
const { getEmbeddableFactories } = embeddables;
const { getSavedObjects, getUISettings } = platform;
const { getSavedObjects, getUISettings } = platformService;
const onAddPanel = (id: string, savedObjectType: string, name: string) => {
const embeddableFactories = getEmbeddableFactories();

View file

@ -8,7 +8,6 @@
import { action } from '@storybook/addon-actions';
import { storiesOf } from '@storybook/react';
import React from 'react';
import { platformService } from '../../../../services/legacy/stubs/platform';
import { reportingService } from '../../../../services/legacy/stubs/reporting';
import { ShareMenu } from '../share_menu.component';
@ -18,7 +17,7 @@ storiesOf('components/WorkpadHeader/ShareMenu', module).add('minimal', () => (
workpad: { id: 'coolworkpad', name: 'Workpad of Cool', height: 10, width: 7 },
pageCount: 11,
}}
sharingServices={{ basePath: platformService.getBasePathInterface() }}
sharingServices={{}}
onExport={action('onExport')}
/>
));
@ -30,7 +29,6 @@ storiesOf('components/WorkpadHeader/ShareMenu', module).add('with Reporting', ()
pageCount: 11,
}}
sharingServices={{
basePath: platformService.getBasePathInterface(),
reporting: reportingService.start,
}}
onExport={action('onExport')}

View file

@ -26,17 +26,12 @@ storiesOf('components/WorkpadHeader/ShareMenu/ShareWebsiteFlyout', module)
},
})
.add('default', () => (
<ShareWebsiteFlyout
onCopy={action('onCopy')}
onDownload={action('onDownload')}
onClose={action('onClose')}
/>
<ShareWebsiteFlyout onClose={action('onClose')} renderedWorkpad={{} as any} />
))
.add('unsupported renderers', () => (
<ShareWebsiteFlyout
onCopy={action('onCopy')}
onDownload={action('onDownload')}
onClose={action('onClose')}
unsupportedRenderers={['rendererOne', 'rendererTwo']}
renderedWorkpad={{} as any}
/>
));

View file

@ -24,13 +24,42 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { arrayBufferFetch } from '../../../../../common/lib/fetch';
import { API_ROUTE_SHAREABLE_ZIP } from '../../../../../common/lib/constants';
import { CanvasRenderedWorkpad } from '../../../../../shareable_runtime/types';
import {
downloadRenderedWorkpad,
downloadRuntime,
downloadZippedRuntime,
} from '../../../../lib/download_workpad';
import { ZIP, CANVAS, HTML } from '../../../../../i18n/constants';
import { OnCloseFn } from '../share_menu.component';
import { WorkpadStep } from './workpad_step';
import { RuntimeStep } from './runtime_step';
import { SnippetsStep } from './snippets_step';
import { useNotifyService, usePlatformService } from '../../../../services';
const strings = {
getCopyShareConfigMessage: () =>
i18n.translate('xpack.canvas.workpadHeaderShareMenu.copyShareConfigMessage', {
defaultMessage: 'Copied share markup to clipboard',
}),
getShareableZipErrorTitle: (workpadName: string) =>
i18n.translate('xpack.canvas.workpadHeaderShareMenu.shareWebsiteErrorTitle', {
defaultMessage:
"Failed to create {ZIP} file for '{workpadName}'. The workpad may be too large. You'll need to download the files separately.",
values: {
ZIP,
workpadName,
},
}),
getUnknownExportErrorMessage: (type: string) =>
i18n.translate('xpack.canvas.workpadHeaderShareMenu.unknownExportErrorMessage', {
defaultMessage: 'Unknown export type: {type}',
values: {
type,
},
}),
getRuntimeStepTitle: () =>
i18n.translate('xpack.canvas.shareWebsiteFlyout.snippetsStep.downloadRuntimeTitle', {
defaultMessage: 'Download runtime',
@ -66,10 +95,9 @@ export type OnDownloadFn = (type: 'share' | 'shareRuntime' | 'shareZip') => void
export type OnCopyFn = () => void;
export interface Props {
onCopy: OnCopyFn;
onDownload: OnDownloadFn;
onClose: OnCloseFn;
unsupportedRenderers?: string[];
renderedWorkpad: CanvasRenderedWorkpad;
}
const steps = (onDownload: OnDownloadFn, onCopy: OnCopyFn) => [
@ -88,11 +116,39 @@ const steps = (onDownload: OnDownloadFn, onCopy: OnCopyFn) => [
];
export const ShareWebsiteFlyout: FC<Props> = ({
onCopy,
onDownload,
onClose,
unsupportedRenderers,
renderedWorkpad,
}) => {
const notifyService = useNotifyService();
const platformService = usePlatformService();
const onCopy = () => {
notifyService.info(strings.getCopyShareConfigMessage());
};
const onDownload = (type: 'share' | 'shareRuntime' | 'shareZip') => {
switch (type) {
case 'share':
downloadRenderedWorkpad(renderedWorkpad);
return;
case 'shareRuntime':
downloadRuntime(platformService.getBasePath());
case 'shareZip':
const basePath = platformService.getBasePath();
arrayBufferFetch
.post(`${basePath}${API_ROUTE_SHAREABLE_ZIP}`, JSON.stringify(renderedWorkpad))
.then((blob) => downloadZippedRuntime(blob.data))
.catch((err: Error) => {
notifyService.error(err, {
title: strings.getShareableZipErrorTitle(renderedWorkpad.name),
});
});
return;
default:
throw new Error(strings.getUnknownExportErrorMessage(type));
}
};
const link = (
<EuiLink
style={{ textDecoration: 'underline' }}

View file

@ -7,56 +7,22 @@
import { connect } from 'react-redux';
import { compose, withProps } from 'recompose';
import { i18n } from '@kbn/i18n';
import {
getWorkpad,
getRenderedWorkpad,
getRenderedWorkpadExpressions,
} from '../../../../state/selectors/workpad';
import {
downloadRenderedWorkpad,
downloadRuntime,
downloadZippedRuntime,
} from '../../../../lib/download_workpad';
import { ShareWebsiteFlyout as Component, Props as ComponentProps } from './flyout.component';
import { State, CanvasWorkpad } from '../../../../../types';
import { CanvasRenderedWorkpad } from '../../../../../shareable_runtime/types';
import { arrayBufferFetch } from '../../../../../common/lib/fetch';
import { API_ROUTE_SHAREABLE_ZIP } from '../../../../../common/lib/constants';
import { renderFunctionNames } from '../../../../../shareable_runtime/supported_renderers';
import { withKibana } from '../../../../../../../../src/plugins/kibana_react/public/';
import { OnCloseFn } from '../share_menu.component';
import { ZIP } from '../../../../../i18n/constants';
import { WithKibanaProps } from '../../../../index';
import { pluginServices } from '../../../../services';
export { OnDownloadFn, OnCopyFn } from './flyout.component';
const strings = {
getCopyShareConfigMessage: () =>
i18n.translate('xpack.canvas.workpadHeaderShareMenu.copyShareConfigMessage', {
defaultMessage: 'Copied share markup to clipboard',
}),
getShareableZipErrorTitle: (workpadName: string) =>
i18n.translate('xpack.canvas.workpadHeaderShareMenu.shareWebsiteErrorTitle', {
defaultMessage:
"Failed to create {ZIP} file for '{workpadName}'. The workpad may be too large. You'll need to download the files separately.",
values: {
ZIP,
workpadName,
},
}),
getUnknownExportErrorMessage: (type: string) =>
i18n.translate('xpack.canvas.workpadHeaderShareMenu.unknownExportErrorMessage', {
defaultMessage: 'Unknown export type: {type}',
values: {
type,
},
}),
};
const getUnsupportedRenderers = (state: State) => {
const renderers: string[] = [];
const expressions = getRenderedWorkpadExpressions(state);
@ -86,41 +52,10 @@ export const ShareWebsiteFlyout = compose<ComponentProps, Pick<Props, 'onClose'>
connect(mapStateToProps),
withKibana,
withProps(
({
unsupportedRenderers,
({ unsupportedRenderers, renderedWorkpad, onClose, workpad }: Props): ComponentProps => ({
renderedWorkpad,
onClose,
workpad,
kibana,
}: Props & WithKibanaProps): ComponentProps => ({
unsupportedRenderers,
onClose,
onCopy: () => {
pluginServices.getServices().notify.info(strings.getCopyShareConfigMessage());
},
onDownload: (type) => {
switch (type) {
case 'share':
downloadRenderedWorkpad(renderedWorkpad);
return;
case 'shareRuntime':
downloadRuntime(kibana.services.http.basePath.get());
return;
case 'shareZip':
const basePath = kibana.services.http.basePath.get();
arrayBufferFetch
.post(`${basePath}${API_ROUTE_SHAREABLE_ZIP}`, JSON.stringify(renderedWorkpad))
.then((blob) => downloadZippedRuntime(blob.data))
.catch((err: Error) => {
pluginServices.getServices().notify.error(err, {
title: strings.getShareableZipErrorTitle(workpad.name),
});
});
return;
default:
throw new Error(strings.getUnknownExportErrorMessage(type));
}
},
})
)
)(Component);

View file

@ -9,11 +9,11 @@ import React, { FunctionComponent, useState } from 'react';
import PropTypes from 'prop-types';
import { EuiButtonEmpty, EuiContextMenu, EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { IBasePath } from 'kibana/public';
import { ReportingStart } from '../../../../../reporting/public';
import { PDF, JSON } from '../../../../i18n/constants';
import { flattenPanelTree } from '../../../lib/flatten_panel_tree';
import { usePlatformService } from '../../../services';
import { ClosePopoverFn, Popover } from '../../popover';
import { ShareWebsiteFlyout } from './flyout';
import { CanvasWorkpadSharingData, getPdfJobParams } from './utils';
@ -59,8 +59,6 @@ export interface Props {
/** Canvas workpad to export as PDF **/
sharingData: CanvasWorkpadSharingData;
sharingServices: {
/** BasePath dependency **/
basePath: IBasePath;
/** Reporting dependency **/
reporting?: ReportingStart;
};
@ -76,6 +74,7 @@ export const ShareMenu: FunctionComponent<Props> = ({
sharingServices: services,
onExport,
}) => {
const platformService = usePlatformService();
const [showFlyout, setShowFlyout] = useState(false);
const onClose = () => {
@ -102,7 +101,9 @@ export const ShareMenu: FunctionComponent<Props> = ({
title: strings.getShareDownloadPDFTitle(),
content: (
<services.reporting.components.ReportingPanelPDF
getJobParams={() => getPdfJobParams(sharingData, services.basePath)}
getJobParams={() =>
getPdfJobParams(sharingData, platformService.getBasePathInterface())
}
layoutOption="canvas"
onClose={closePopover}
/>

View file

@ -41,12 +41,11 @@ export const ShareMenu = compose<ComponentProps, {}>(
withProps(
({ workpad, pageCount, services }: Props & WithServicesProps): ComponentProps => {
const {
platform,
reporting: { start: reporting },
} = services;
return {
sharingServices: { basePath: platform.getBasePathInterface(), reporting },
sharingServices: { reporting },
sharingData: { workpad, pageCount },
onExport: (type) => {
switch (type) {

View file

@ -9,10 +9,10 @@ import { AxiosPromise } from 'axios';
import { API_ROUTE_CUSTOM_ELEMENT } from '../../common/lib/constants';
import { fetch } from '../../common/lib/fetch';
import { CustomElement } from '../../types';
import { platformService } from '../services';
import { pluginServices } from '../services';
const getApiPath = function () {
const basePath = platformService.getService().getBasePath();
const basePath = pluginServices.getServices().platform.getBasePath();
return `${basePath}${API_ROUTE_CUSTOM_ELEMENT}`;
};

View file

@ -6,28 +6,29 @@
*/
// TODO - clint: convert to service abstraction
import { IndexPatternAttributes } from 'src/plugins/data/public';
import { API_ROUTE } from '../../common/lib/constants';
import { fetch } from '../../common/lib/fetch';
import { ErrorStrings } from '../../i18n';
import { pluginServices } from '../services';
import { platformService } from '../services';
const { esService: strings } = ErrorStrings;
const getApiPath = function () {
const basePath = platformService.getService().getBasePath();
const platformService = pluginServices.getServices().platform;
const basePath = platformService.getBasePath();
return basePath + API_ROUTE;
};
const getSavedObjectsClient = function () {
return platformService.getService().getSavedObjectsClient();
const platformService = pluginServices.getServices().platform;
return platformService.getSavedObjectsClient();
};
const getAdvancedSettings = function () {
return platformService.getService().getUISettings();
const platformService = pluginServices.getServices().platform;
return platformService.getUISettings();
};
export const getFields = (index = '_all') => {

View file

@ -5,21 +5,22 @@
* 2.0.
*/
import { platformService } from '../services';
import { pluginServices } from '../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.getService().setFullscreen(false);
platformService.setFullscreen(false);
bodyClassList.add(fullscreenClass);
} else if (!enabled && isFullscreen) {
bodyClassList.remove(fullscreenClass);
platformService.getService().setFullscreen(true);
platformService.setFullscreen(true);
}
}

View file

@ -5,13 +5,16 @@
* 2.0.
*/
// TODO - clint: convert to service abstraction
import { API_ROUTE_TEMPLATES } from '../../common/lib/constants';
import { fetch } from '../../common/lib/fetch';
import { platformService } from '../services';
import { pluginServices } from '../services';
import { CanvasTemplate } from '../../types';
const getApiPath = function () {
const basePath = platformService.getService().getBasePath();
const platformService = pluginServices.getServices().platform;
const basePath = platformService.getBasePath();
return `${basePath}${API_ROUTE_TEMPLATES}`;
};
@ -21,6 +24,5 @@ interface ListResponse {
export async function list() {
const templateResponse = await fetch.get<ListResponse>(`${getApiPath()}`);
return templateResponse.data.templates;
}

View file

@ -5,6 +5,7 @@
* 2.0.
*/
// TODO: clint - move to workpad service.
import {
API_ROUTE_WORKPAD,
API_ROUTE_WORKPAD_ASSETS,
@ -12,7 +13,7 @@ import {
DEFAULT_WORKPAD_CSS,
} from '../../common/lib/constants';
import { fetch } from '../../common/lib/fetch';
import { platformService } from '../services';
import { pluginServices } from '../services';
/*
Remove any top level keys from the workpad which will be rejected by validation
@ -46,17 +47,20 @@ const sanitizeWorkpad = function (workpad) {
};
const getApiPath = function () {
const basePath = platformService.getService().getBasePath();
const platformService = pluginServices.getServices().platform;
const basePath = platformService.getBasePath();
return `${basePath}${API_ROUTE_WORKPAD}`;
};
const getApiPathStructures = function () {
const basePath = platformService.getService().getBasePath();
const platformService = pluginServices.getServices().platform;
const basePath = platformService.getBasePath();
return `${basePath}${API_ROUTE_WORKPAD_STRUCTURES}`;
};
const getApiPathAssets = function () {
const basePath = platformService.getService().getBasePath();
const platformService = pluginServices.getServices().platform;
const basePath = platformService.getBasePath();
return `${basePath}${API_ROUTE_WORKPAD_ASSETS}`;
};

View file

@ -5,15 +5,14 @@
* 2.0.
*/
import { useContext, useEffect } from 'react';
import { useServices } from '../../../services';
import { usePlatformService } from '../../../services';
import { WorkpadRoutingContext } from '..';
const fullscreenClass = 'canvas-isFullscreen';
export const useFullscreenPresentationHelper = () => {
const { isFullscreen } = useContext(WorkpadRoutingContext);
const services = useServices();
const { setFullscreen } = services.platform;
const { setFullscreen } = usePlatformService();
useEffect(() => {
const body = document.querySelector('body');

View file

@ -14,21 +14,21 @@ 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 { useServices } from '../../services';
import { usePlatformService } from '../../services';
export const WorkpadPresentationHelper: FC = ({ children }) => {
const services = useServices();
const platformService = usePlatformService();
const workpad = useSelector(getWorkpad);
useFullscreenPresentationHelper();
useAutoplayHelper();
useRefreshHelper();
useEffect(() => {
services.platform.setBreadcrumbs([
platformService.setBreadcrumbs([
getBaseBreadcrumb(),
getWorkpadBreadcrumb({ name: workpad.name }),
]);
}, [workpad.name, workpad.id, services.platform]);
}, [workpad.name, workpad.id, platformService]);
useEffect(() => {
setDocTitle(workpad.name);

View file

@ -10,13 +10,16 @@ export * from './legacy';
import { PluginServices } from '../../../../../src/plugins/presentation_util/public';
import { CanvasWorkpadService } from './workpad';
import { CanvasNotifyService } from './notify';
import { CanvasPlatformService } from './platform';
export interface CanvasPluginServices {
workpad: CanvasWorkpadService;
notify: CanvasNotifyService;
platform: CanvasPlatformService;
}
export const pluginServices = new PluginServices<CanvasPluginServices>();
export const useWorkpadService = () => (() => pluginServices.getHooks().workpad.useService())();
export const useNotifyService = () => (() => pluginServices.getHooks().notify.useService())();
export const usePlatformService = () => (() => pluginServices.getHooks().platform.useService())();

View file

@ -14,11 +14,13 @@ import {
import { workpadServiceFactory } from './workpad';
import { notifyServiceFactory } from './notify';
import { platformServiceFactory } from './platform';
import { CanvasPluginServices } from '..';
import { CanvasStartDeps } from '../../plugin';
export { workpadServiceFactory } from './workpad';
export { notifyServiceFactory } from './notify';
export { platformServiceFactory } from './platform';
export const pluginServiceProviders: PluginServiceProviders<
CanvasPluginServices,
@ -26,6 +28,7 @@ export const pluginServiceProviders: PluginServiceProviders<
> = {
workpad: new PluginServiceProvider(workpadServiceFactory),
notify: new PluginServiceProvider(notifyServiceFactory),
platform: new PluginServiceProvider(platformServiceFactory),
};
export const pluginServiceRegistry = new PluginServiceRegistry<

View file

@ -5,38 +5,17 @@
* 2.0.
*/
import {
SavedObjectsStart,
SavedObjectsClientContract,
IUiSettingsClient,
ChromeBreadcrumb,
IBasePath,
ChromeStart,
} from '../../../../../../src/core/public';
import { CanvasServiceFactory } from '.';
import { KibanaPluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
export interface PlatformService {
getBasePath: () => string;
getBasePathInterface: () => IBasePath;
getDocLinkVersion: () => string;
getElasticWebsiteUrl: () => string;
getHasWriteAccess: () => boolean;
getUISetting: (key: string, defaultValue?: any) => any;
setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void;
setRecentlyAccessed: (link: string, label: string, id: string) => void;
setFullscreen: ChromeStart['setIsVisible'];
import { CanvasStartDeps } from '../../plugin';
import { CanvasPlatformService } from '../platform';
// TODO: these should go away. We want thin accessors, not entire objects.
// Entire objects are hard to mock, and hide our dependency on the external service.
getSavedObjects: () => SavedObjectsStart;
getSavedObjectsClient: () => SavedObjectsClientContract;
getUISettings: () => IUiSettingsClient;
}
export type CanvaPlatformServiceFactory = KibanaPluginServiceFactory<
CanvasPlatformService,
CanvasStartDeps
>;
export const platformServiceFactory: CanvasServiceFactory<PlatformService> = (
_coreSetup,
coreStart
) => {
export const platformServiceFactory: CanvaPlatformServiceFactory = ({ coreStart }) => {
return {
getBasePath: coreStart.http.basePath.get,
getBasePathInterface: () => coreStart.http.basePath,

View file

@ -22,7 +22,6 @@ export interface WithServicesProps {
const defaultContextValue = {
embeddables: {},
expressions: {},
platform: {},
navLink: {},
search: {},
};
@ -30,7 +29,6 @@ const defaultContextValue = {
const context = createContext<CanvasServices>(defaultContextValue as CanvasServices);
export const useServices = () => useContext(context);
export const usePlatformService = () => useServices().platform;
export const useEmbeddablesService = () => useServices().embeddables;
export const useExpressionsService = () => useServices().expressions;
export const useNavLinkService = () => useServices().navLink;
@ -50,7 +48,6 @@ export const LegacyServicesProvider: FC<{
const value = {
embeddables: specifiedProviders.embeddables.getService(),
expressions: specifiedProviders.expressions.getService(),
platform: specifiedProviders.platform.getService(),
navLink: specifiedProviders.navLink.getService(),
search: specifiedProviders.search.getService(),
reporting: specifiedProviders.reporting.getService(),

View file

@ -8,7 +8,6 @@
import { BehaviorSubject } from 'rxjs';
import { CoreSetup, CoreStart, AppUpdater } from '../../../../../../src/core/public';
import { CanvasSetupDeps, CanvasStartDeps } from '../../plugin';
import { platformServiceFactory } from './platform';
import { navLinkServiceFactory } from './nav_link';
import { embeddablesServiceFactory } from './embeddables';
import { expressionsServiceFactory } from './expressions';
@ -17,7 +16,6 @@ import { labsServiceFactory } from './labs';
import { reportingServiceFactory } from './reporting';
export { SearchService } from './search';
export { PlatformService } from './platform';
export { NavLinkService } from './nav_link';
export { EmbeddablesService } from './embeddables';
export { ExpressionsService } from '../../../../../../src/plugins/expressions/common';
@ -77,7 +75,6 @@ export type ServiceFromProvider<P> = P extends CanvasServiceProvider<infer T> ?
export const services = {
embeddables: new CanvasServiceProvider(embeddablesServiceFactory),
expressions: new CanvasServiceProvider(expressionsServiceFactory),
platform: new CanvasServiceProvider(platformServiceFactory),
navLink: new CanvasServiceProvider(navLinkServiceFactory),
search: new CanvasServiceProvider(searchServiceFactory),
reporting: new CanvasServiceProvider(reportingServiceFactory),
@ -89,7 +86,6 @@ export type CanvasServiceProviders = typeof services;
export interface CanvasServices {
embeddables: ServiceFromProvider<typeof services.embeddables>;
expressions: ServiceFromProvider<typeof services.expressions>;
platform: ServiceFromProvider<typeof services.platform>;
navLink: ServiceFromProvider<typeof services.navLink>;
search: ServiceFromProvider<typeof services.search>;
reporting: ServiceFromProvider<typeof services.reporting>;
@ -116,7 +112,6 @@ export const stopServices = () => {
export const {
embeddables: embeddableService,
platform: platformService,
navLink: navLinkService,
expressions: expressionsService,
search: searchService,

View file

@ -11,7 +11,6 @@ import { expressionsService } from './expressions';
import { reportingService } from './reporting';
import { navLinkService } from './nav_link';
import { labsService } from './labs';
import { platformService } from './platform';
import { searchService } from './search';
export const stubs: CanvasServices = {
@ -19,7 +18,6 @@ export const stubs: CanvasServices = {
expressions: expressionsService,
reporting: reportingService,
navLink: navLinkService,
platform: platformService,
search: searchService,
labs: labsService,
};

View file

@ -0,0 +1,33 @@
/*
* 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 {
SavedObjectsStart,
SavedObjectsClientContract,
IUiSettingsClient,
ChromeBreadcrumb,
IBasePath,
ChromeStart,
} from '../../../../../src/core/public';
export interface CanvasPlatformService {
getBasePath: () => string;
getBasePathInterface: () => IBasePath;
getDocLinkVersion: () => string;
getElasticWebsiteUrl: () => string;
getHasWriteAccess: () => boolean;
getUISetting: (key: string, defaultValue?: any) => any;
setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => void;
setRecentlyAccessed: (link: string, label: string, id: string) => void;
setFullscreen: ChromeStart['setIsVisible'];
// TODO: these should go away. We want thin accessors, not entire objects.
// Entire objects are hard to mock, and hide our dependency on the external service.
getSavedObjects: () => SavedObjectsStart;
getSavedObjectsClient: () => SavedObjectsClientContract;
getUISettings: () => IUiSettingsClient;
}

View file

@ -16,13 +16,16 @@ import {
import { CanvasPluginServices } from '..';
import { workpadServiceFactory } from './workpad';
import { notifyServiceFactory } from './notify';
import { platformServiceFactory } from './platform';
export { workpadServiceFactory } from './workpad';
export { notifyServiceFactory } from './notify';
export { platformServiceFactory } from './platform';
export const pluginServiceProviders: PluginServiceProviders<CanvasPluginServices> = {
workpad: new PluginServiceProvider(workpadServiceFactory),
notify: new PluginServiceProvider(notifyServiceFactory),
platform: new PluginServiceProvider(platformServiceFactory),
};
export const pluginServiceRegistry = new PluginServiceRegistry<CanvasPluginServices>(

View file

@ -5,7 +5,11 @@
* 2.0.
*/
import { PlatformService } from '../platform';
import { PluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
import { CanvasPlatformService } from '../platform';
type CanvasPlatformServiceFactory = PluginServiceFactory<CanvasPlatformService>;
const noop = (..._args: any[]): any => {};
@ -15,7 +19,7 @@ const uiSettings: Record<string, any> = {
const getUISetting = (setting: string) => uiSettings[setting];
export const platformService: PlatformService = {
export const platformServiceFactory: CanvasPlatformServiceFactory = () => ({
getBasePath: () => '/base/path',
getBasePathInterface: noop,
getDocLinkVersion: () => 'dockLinkVersion',
@ -28,4 +32,4 @@ export const platformService: PlatformService = {
getSavedObjectsClient: noop,
getUISettings: noop,
setFullscreen: noop,
};
});

View file

@ -6,11 +6,12 @@
*/
import { get } from 'lodash';
import { platformService } from '../services';
import { pluginServices } from '../services';
import { getDefaultWorkpad } from './defaults';
export const getInitialState = (path) => {
const { getHasWriteAccess } = platformService.getService();
const platformService = pluginServices.getServices().platform;
const { getHasWriteAccess } = platformService;
const state = {
app: {}, // Kibana stuff in here

View file

@ -6,7 +6,7 @@
*/
import { handleActions } from 'redux-actions';
import { platformService } from '../../services';
import { pluginServices } from '../../services';
import { getDefaultWorkpad } from '../defaults';
import {
setWorkpad,
@ -24,9 +24,13 @@ import { APP_ROUTE_WORKPAD } from '../../../common/lib/constants';
export const workpadReducer = handleActions(
{
[setWorkpad]: (workpadState, { payload }) => {
platformService
.getService()
.setRecentlyAccessed(`${APP_ROUTE_WORKPAD}/${payload.id}`, payload.name, payload.id);
pluginServices
.getServices()
.platform.setRecentlyAccessed(
`${APP_ROUTE_WORKPAD}/${payload.id}`,
payload.name,
payload.id
);
return payload;
},
@ -39,9 +43,13 @@ export const workpadReducer = handleActions(
},
[setName]: (workpadState, { payload }) => {
platformService
.getService()
.setRecentlyAccessed(`${APP_ROUTE_WORKPAD}/${workpadState.id}`, payload, workpadState.id);
pluginServices
.getServices()
.platform.setRecentlyAccessed(
`${APP_ROUTE_WORKPAD}/${workpadState.id}`,
payload,
workpadState.id
);
return { ...workpadState, name: payload };
},