mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[Canvas] Cleanup services (#194634)](https://github.com/elastic/kibana/pull/194634) <!--- Backport version: 8.9.8 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Hannah Mudge","email":"Heenawter@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-10-08T20:34:01Z","message":"[Canvas] Cleanup services (#194634)\n\nCloses https://github.com/elastic/kibana/issues/194050\r\n\r\n## Summary\r\n\r\nThis PR refactors the Canvas services to no longer use the\r\n`PluginServiceProvider` from the `PresentationUtil` plugin. Note that\r\nthe Canvas storybooks are broken on main (and they have been for who\r\nknows how long) and so, while I did make some changes to the storybooks\r\nto make them **compile**, I didn't bother to get them fully functional.\r\n\r\nNote that the Ecommerce workpad is broken - this is not due to this PR,\r\nit is a [bug](https://github.com/elastic/kibana/issues/195297) that is\r\npresent on main.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n\r\n<!--ONMERGE {\"backportTargets\":[\"8.x\"]} ONMERGE-->\r\n\r\n---------\r\n\r\nCo-authored-by: Catherine Liu <catherine.liu@elastic.co>","sha":"91c045d698b2e68afd13f5d4bef9229d8a231abe","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Presentation","loe:medium","technical debt","release_note:skip","impact:high","v9.0.0","backport:prev-minor"],"number":194634,"url":"https://github.com/elastic/kibana/pull/194634","mergeCommit":{"message":"[Canvas] Cleanup services (#194634)\n\nCloses https://github.com/elastic/kibana/issues/194050\r\n\r\n## Summary\r\n\r\nThis PR refactors the Canvas services to no longer use the\r\n`PluginServiceProvider` from the `PresentationUtil` plugin. Note that\r\nthe Canvas storybooks are broken on main (and they have been for who\r\nknows how long) and so, while I did make some changes to the storybooks\r\nto make them **compile**, I didn't bother to get them fully functional.\r\n\r\nNote that the Ecommerce workpad is broken - this is not due to this PR,\r\nit is a [bug](https://github.com/elastic/kibana/issues/195297) that is\r\npresent on main.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n\r\n<!--ONMERGE {\"backportTargets\":[\"8.x\"]} ONMERGE-->\r\n\r\n---------\r\n\r\nCo-authored-by: Catherine Liu <catherine.liu@elastic.co>","sha":"91c045d698b2e68afd13f5d4bef9229d8a231abe"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","labelRegex":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194634","number":194634,"mergeCommit":{"message":"[Canvas] Cleanup services (#194634)\n\nCloses https://github.com/elastic/kibana/issues/194050\r\n\r\n## Summary\r\n\r\nThis PR refactors the Canvas services to no longer use the\r\n`PluginServiceProvider` from the `PresentationUtil` plugin. Note that\r\nthe Canvas storybooks are broken on main (and they have been for who\r\nknows how long) and so, while I did make some changes to the storybooks\r\nto make them **compile**, I didn't bother to get them fully functional.\r\n\r\nNote that the Ecommerce workpad is broken - this is not due to this PR,\r\nit is a [bug](https://github.com/elastic/kibana/issues/195297) that is\r\npresent on main.\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n### For maintainers\r\n\r\n- [ ] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n\r\n<!--ONMERGE {\"backportTargets\":[\"8.x\"]} ONMERGE-->\r\n\r\n---------\r\n\r\nCo-authored-by: Catherine Liu <catherine.liu@elastic.co>","sha":"91c045d698b2e68afd13f5d4bef9229d8a231abe"}}]}] BACKPORT-->
This commit is contained in:
parent
e8992e3749
commit
a177282289
123 changed files with 983 additions and 2012 deletions
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -17,4 +17,5 @@ module.exports = {
|
|||
collectCoverageFrom: [
|
||||
'<rootDir>/x-pack/plugins/canvas/{canvas_plugin_src,common,i18n,public,server,shareable_runtime}/**/*.{js,ts,tsx}',
|
||||
],
|
||||
setupFiles: ['<rootDir>/x-pack/plugins/canvas/jest_setup.ts'],
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export interface CanvasNavLinkService {
|
||||
updatePath: (path: string) => void;
|
||||
}
|
||||
import { setStubKibanaServices } from './public/services/mocks';
|
||||
|
||||
// Start the kibana services with stubs
|
||||
setStubKibanaServices();
|
|
@ -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,29 +50,26 @@ export const renderApp = ({
|
|||
startPlugins,
|
||||
params,
|
||||
canvasStore,
|
||||
pluginServices,
|
||||
appUpdater,
|
||||
}: {
|
||||
coreStart: CoreStart;
|
||||
startPlugins: CanvasStartDeps;
|
||||
params: AppMountParameters;
|
||||
canvasStore: Store;
|
||||
pluginServices: PluginServices<CanvasPluginServices>;
|
||||
appUpdater: BehaviorSubject<AppUpdater>;
|
||||
}) => {
|
||||
const { element } = params;
|
||||
element.classList.add('canvas');
|
||||
element.classList.add('canvasContainerWrapper');
|
||||
const ServicesContextProvider = pluginServices.getContextProvider();
|
||||
|
||||
ReactDOM.render(
|
||||
<KibanaRenderContextProvider {...coreStart}>
|
||||
<KibanaContextProvider services={{ ...startPlugins, ...coreStart }}>
|
||||
<ServicesContextProvider>
|
||||
<LegacyServicesProvider providers={services}>
|
||||
<Provider store={canvasStore}>
|
||||
<App history={params.history} />
|
||||
</Provider>
|
||||
</LegacyServicesProvider>
|
||||
</ServicesContextProvider>
|
||||
<LegacyServicesProvider providers={services}>
|
||||
<Provider store={canvasStore}>
|
||||
<App history={params.history} appUpdater={appUpdater} />
|
||||
</Provider>
|
||||
</LegacyServicesProvider>
|
||||
</KibanaContextProvider>
|
||||
</KibanaRenderContextProvider>,
|
||||
element
|
||||
|
|
|
@ -5,14 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { FC, useEffect } from 'react';
|
||||
import { AppUpdater, ScopedHistory } from '@kbn/core/public';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ScopedHistory } from '@kbn/core/public';
|
||||
import { useNavLinkService } from '../../services';
|
||||
import React, { FC, useEffect } from 'react';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
// @ts-expect-error
|
||||
import { shortcutManager } from '../../lib/shortcut_manager';
|
||||
import { CanvasRouter } from '../../routes';
|
||||
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<React.PropsWithChildren<{}>> {
|
||||
static childContextTypes = {
|
||||
|
@ -28,12 +31,21 @@ class ShortcutManagerContextWrapper extends React.Component<React.PropsWithChild
|
|||
}
|
||||
}
|
||||
|
||||
export const App: FC<{ history: ScopedHistory }> = ({ history }) => {
|
||||
const { updatePath } = useNavLinkService();
|
||||
|
||||
export const App: FC<{ history: ScopedHistory; appUpdater: BehaviorSubject<AppUpdater> }> = ({
|
||||
history,
|
||||
appUpdater,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
return history.listen(({ pathname, search }) => {
|
||||
updatePath(pathname + search);
|
||||
const path = pathname + search;
|
||||
appUpdater.next(() => ({
|
||||
defaultPath: path,
|
||||
}));
|
||||
|
||||
getSessionStorage().set(
|
||||
`${SESSIONSTORAGE_LASTPATH}:${coreServices.http.basePath.get()}`,
|
||||
path
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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 { notify, workpad: workpadService } = pluginServices.getServices();
|
||||
const workpadService = getCanvasWorkpadService();
|
||||
|
||||
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) => {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 <Loading {...props} />;
|
||||
|
|
|
@ -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<ComponentProps, 'renderFunction' | 'backgroundColor'>;
|
||||
|
||||
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 <Component {...{ ...props, renderFunction, backgroundColor }} />;
|
||||
};
|
||||
|
|
|
@ -5,14 +5,18 @@
|
|||
* 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 { 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,
|
||||
coreServices,
|
||||
embeddableService,
|
||||
} from '../../services/kibana_services';
|
||||
|
||||
const strings = {
|
||||
getNoItemsText: () =>
|
||||
|
@ -45,13 +49,8 @@ export const AddEmbeddableFlyout: FC<Props> = ({
|
|||
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 +59,10 @@ export const AddEmbeddableFlyout: FC<Props> = ({
|
|||
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 +73,7 @@ export const AddEmbeddableFlyout: FC<Props> = ({
|
|||
};
|
||||
return acc;
|
||||
}, {} as FactoryMap);
|
||||
}, [getReactEmbeddableSavedObjects]);
|
||||
}, []);
|
||||
|
||||
const metaData = useMemo(
|
||||
() =>
|
||||
|
@ -111,7 +110,7 @@ export const AddEmbeddableFlyout: FC<Props> = ({
|
|||
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 +123,7 @@ export const AddEmbeddableFlyout: FC<Props> = ({
|
|||
|
||||
onSelect(id, foundEmbeddableType, isByValueEnabled);
|
||||
},
|
||||
[isByValueEnabled, getEmbeddableFactories, onSelect, factoriesBySavedObjectType]
|
||||
[isByValueEnabled, onSelect, factoriesBySavedObjectType]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -141,8 +140,8 @@ export const AddEmbeddableFlyout: FC<Props> = ({
|
|||
showFilter={true}
|
||||
noItemsMessage={strings.getNoItemsText()}
|
||||
services={{
|
||||
contentClient: getContentManagement().client,
|
||||
uiSettings: getUISettings(),
|
||||
contentClient: contentManagementService.client,
|
||||
uiSettings: coreServices.uiSettings,
|
||||
}}
|
||||
/>
|
||||
</EuiFlyoutBody>
|
||||
|
|
|
@ -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,8 +67,9 @@ export const AddEmbeddablePanel: React.FunctionComponent<FlyoutProps> = ({
|
|||
availableEmbeddables,
|
||||
...restProps
|
||||
}) => {
|
||||
const labsService = useLabsService();
|
||||
const isByValueEnabled = labsService.isProjectEnabled('labs:canvas:byValueEmbeddable');
|
||||
const isByValueEnabled = presentationUtilService.labsService.isProjectEnabled(
|
||||
'labs:canvas:byValueEmbeddable'
|
||||
);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const pageId = useSelector<State, string>((state) => getSelectedPage(state));
|
||||
|
|
|
@ -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<DataView, 'id' | 'name' | 'title'>;
|
||||
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<HTMLDivElement> | undefined;
|
||||
onFocus: FocusEventHandler<HTMLDivElement> | undefined;
|
||||
|
@ -31,7 +29,7 @@ export const ESDataViewSelect: React.FunctionComponent<ESDataViewSelectProps> =
|
|||
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 }
|
||||
|
|
|
@ -5,25 +5,24 @@
|
|||
* 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';
|
||||
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<Props, 'indices' | 'loading'>;
|
||||
|
||||
export const ESDataViewSelect: FC<ESDataViewSelectProps> = (props) => {
|
||||
const { value, onChange } = props;
|
||||
|
||||
const [dataViews, setDataViews] = useState<Array<Pick<DataView, 'id' | 'name' | 'title'>>>([]);
|
||||
const [dataViews, setDataViews] = useState<DataViewListItem[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const mounted = useRef(true);
|
||||
const { getDataViews } = useDataViewsService();
|
||||
|
||||
useEffectOnce(() => {
|
||||
getDataViews().then((newDataViews) => {
|
||||
|
|
|
@ -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<Props, 'fields'>;
|
||||
|
||||
|
@ -15,17 +15,16 @@ export const ESFieldSelect: React.FunctionComponent<ESFieldSelectProps> = (props
|
|||
const { index, value, onChange } = props;
|
||||
const [fields, setFields] = useState<string[]>([]);
|
||||
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)) {
|
||||
|
|
|
@ -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<Props, 'fields'> & { index: string };
|
||||
|
||||
|
@ -21,11 +21,10 @@ export const ESFieldsSelect: React.FunctionComponent<ESFieldsSelectProps> = (pro
|
|||
const [fields, setFields] = useState<string[]>([]);
|
||||
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;
|
||||
}
|
||||
|
@ -37,7 +36,7 @@ export const ESFieldsSelect: React.FunctionComponent<ESFieldsSelectProps> = (pro
|
|||
}
|
||||
});
|
||||
}
|
||||
}, [fields, index, onChange, prevIndex, selected, getFields]);
|
||||
}, [fields, index, onChange, prevIndex, selected]);
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
|
|
|
@ -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<ExpressionProps> = ({ done }) => {
|
|||
};
|
||||
|
||||
const ExpressionContainer: FC<ExpressionContainerProps> = ({ done, element, pageId }) => {
|
||||
const expressions = useExpressionsService();
|
||||
const dispatch = useDispatch();
|
||||
const [isCompact, setCompact] = useState<boolean>(true);
|
||||
const toggleCompactView = useCallback(() => {
|
||||
|
@ -111,8 +110,8 @@ const ExpressionContainer: FC<ExpressionContainerProps> = ({ done, element, page
|
|||
}, [element, setFormState, formState]);
|
||||
|
||||
const functionDefinitions = useMemo(
|
||||
() => Object.values(expressions.getFunctions()),
|
||||
[expressions]
|
||||
() => Object.values(getCanvasExpressionService().getFunctions()),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -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 { useNotifyService, useWorkpadService } from '../../services';
|
||||
import { createAsset, notifyError } from '../../lib/assets';
|
||||
import { getCanvasWorkpadService } from '../../services/canvas_workpad_service';
|
||||
|
||||
interface FunctionFormProps {
|
||||
name: string;
|
||||
|
@ -54,8 +54,6 @@ interface FunctionFormProps {
|
|||
export const FunctionForm: React.FunctionComponent<FunctionFormProps> = (props) => {
|
||||
const { expressionIndex, ...restProps } = props;
|
||||
const { nextArgType, path, parentPath, argType } = restProps;
|
||||
const service = useWorkpadService();
|
||||
const notifyService = useNotifyService();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const context = useSelector<State, ExpressionContext>(
|
||||
|
@ -113,16 +111,16 @@ export const FunctionForm: React.FunctionComponent<FunctionFormProps> = (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));
|
||||
// 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, workpad.assets, workpad.id]
|
||||
);
|
||||
|
||||
const onAssetAdd = useCallback(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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]
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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]
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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]
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -8,51 +8,48 @@
|
|||
import { useCallback } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { useNotifyService, useWorkpadService } from '../../../services';
|
||||
import { getCanvasNotifyService } from '../../../services/canvas_notify_service';
|
||||
import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service';
|
||||
|
||||
export const useDeleteWorkpads = () => {
|
||||
const workpadService = useWorkpadService();
|
||||
const notifyService = useNotifyService();
|
||||
return useCallback(async (workpadIds: string[]) => {
|
||||
const workpadService = getCanvasWorkpadService();
|
||||
|
||||
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 };
|
||||
}
|
||||
});
|
||||
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 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];
|
||||
},
|
||||
[[], []]
|
||||
);
|
||||
return [passesArr, errorsArr];
|
||||
},
|
||||
[[], []]
|
||||
);
|
||||
|
||||
const removedIds = workpadIds.filter((id) => passes.includes(id));
|
||||
const removedIds = workpadIds.filter((id) => passes.includes(id));
|
||||
|
||||
if (errored.length > 0) {
|
||||
notifyService.error(errors.getDeleteFailureErrorMessage());
|
||||
}
|
||||
if (errored.length > 0) {
|
||||
getCanvasNotifyService().error(errors.getDeleteFailureErrorMessage());
|
||||
}
|
||||
|
||||
return {
|
||||
removedIds,
|
||||
errored,
|
||||
};
|
||||
});
|
||||
},
|
||||
[workpadService, notifyService]
|
||||
);
|
||||
return {
|
||||
removedIds,
|
||||
errored,
|
||||
};
|
||||
});
|
||||
}, []);
|
||||
};
|
||||
|
||||
const errors = {
|
||||
|
|
|
@ -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(), []);
|
||||
};
|
||||
|
|
|
@ -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]
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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]
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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 <Component {...{ workpads, dateFormat, canUserWrite, onCloneWorkpad, onExportWorkpad }} />;
|
||||
};
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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 <Component onLoad={onLoad} />;
|
||||
};
|
||||
|
|
|
@ -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]
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<ComponentProps, 'onClose'>;
|
|||
|
||||
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<CustomElement[]>([]);
|
||||
|
|
|
@ -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<Props, 'registerLayout' | 'unregisterLayout'>;
|
||||
|
||||
|
@ -40,9 +40,7 @@ export const Workpad: FC<ContainerProps> = (props) => {
|
|||
const { isFullscreen, setFullscreen, undo, redo, autoplayInterval, nextPage, previousPage } =
|
||||
useContext(WorkpadRoutingContext);
|
||||
|
||||
const platformService = usePlatformService();
|
||||
|
||||
const hasHeaderBanner = useObservable(platformService.hasHeaderBanner$());
|
||||
const hasHeaderBanner = useObservable<boolean>(coreServices.chrome.hasHeaderBanner$());
|
||||
|
||||
const propsFromState = useSelector((state: State) => {
|
||||
const { width, height, id: workpadId, css: workpadCss } = getWorkpad(state);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Props> = ({ 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<Array<Action<object>>>([]);
|
||||
|
||||
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<Props> = ({ 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<Props> = ({ addElement }) => {
|
|||
return () => {
|
||||
mounted = false;
|
||||
};
|
||||
}, [uiActions, canvasApi]);
|
||||
}, [canvasApi]);
|
||||
|
||||
const createNewVisType = useCallback(
|
||||
(visType?: BaseVisType | VisTypeAlias) => () => {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -5,14 +5,16 @@
|
|||
* 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 } from '../../../../../services';
|
||||
import { coreServices } from '../../../../../services/kibana_services';
|
||||
import { getCanvasWorkpadService } from '../../../../../services/canvas_workpad_service';
|
||||
|
||||
const strings = {
|
||||
getDownloadRuntimeFailureErrorMessage: () =>
|
||||
|
@ -35,28 +37,28 @@ 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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -9,11 +9,11 @@ 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 { getPages, getWorkpad } from '../../../state/selectors/workpad';
|
||||
import { useDownloadWorkpad } from '../../hooks';
|
||||
import { ShareMenu as ShareMenuComponent } from './share_menu.component';
|
||||
import { getPdfJobParams } from './utils';
|
||||
import { kibanaVersion, reportingService } from '../../../services/kibana_services';
|
||||
|
||||
const strings = {
|
||||
getUnknownExportErrorMessage: (type: string) =>
|
||||
|
@ -27,32 +27,30 @@ const strings = {
|
|||
|
||||
export const ShareMenu = () => {
|
||||
const downloadWorkpad = useDownloadWorkpad();
|
||||
const reportingService = useReportingService();
|
||||
const platformService = usePlatformService();
|
||||
|
||||
const { workpad, pageCount } = useSelector((state: State) => ({
|
||||
workpad: getWorkpad(state),
|
||||
pageCount: getPages(state).length,
|
||||
}));
|
||||
|
||||
const ReportingPanelPDFComponent = reportingService.getReportingPanelPDFComponent();
|
||||
|
||||
const sharingData = {
|
||||
workpad,
|
||||
pageCount,
|
||||
};
|
||||
|
||||
const ReportingComponent =
|
||||
ReportingPanelPDFComponent !== null
|
||||
? ({ onClose }: { onClose: () => void }) => (
|
||||
<ReportingPanelPDFComponent
|
||||
getJobParams={() => getPdfJobParams(sharingData, platformService.getKibanaVersion())}
|
||||
const ReportingComponent = reportingService
|
||||
? ({ onClose }: { onClose: () => void }) => {
|
||||
const ReportingPanelPDFV2 = reportingService!.components.ReportingPanelPDFV2;
|
||||
return (
|
||||
<ReportingPanelPDFV2
|
||||
getJobParams={() => getPdfJobParams(sharingData, kibanaVersion)}
|
||||
layoutOption="canvas"
|
||||
onClose={onClose}
|
||||
objectId={workpad.id}
|
||||
/>
|
||||
)
|
||||
: null;
|
||||
);
|
||||
}
|
||||
: null;
|
||||
|
||||
const onExport = useCallback(
|
||||
(type: string) => {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -12,8 +12,10 @@ 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';
|
||||
// @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...?
|
||||
|
@ -80,7 +82,7 @@ export const createDispatchedHandlerFactory = (
|
|||
oldElement = element;
|
||||
}
|
||||
|
||||
const { filters } = pluginServices.getServices();
|
||||
const filters = getCanvasFiltersService();
|
||||
|
||||
const handlers: RendererHandlers & {
|
||||
event: IInterpreterRenderHandlers['event'];
|
||||
|
@ -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);
|
||||
|
|
26
x-pack/plugins/canvas/public/lib/data_view_helpers.ts
Normal file
26
x-pack/plugins/canvas/public/lib/data_view_helpers.ts
Normal file
|
@ -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);
|
||||
};
|
|
@ -8,10 +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;
|
||||
|
||||
|
@ -71,8 +72,8 @@ export const basicHandlerCreators = {
|
|||
createCustomElement:
|
||||
({ selectedNodes }: Props) =>
|
||||
(name = '', description = '', image = ''): void => {
|
||||
const notifyService = pluginServices.getServices().notify;
|
||||
const customElementService = pluginServices.getServices().customElement;
|
||||
const notifyService = getCanvasNotifyService();
|
||||
const customElementService = getCustomElementService();
|
||||
|
||||
if (selectedNodes.length) {
|
||||
const content = JSON.stringify({ selectedNodes });
|
||||
|
@ -145,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 });
|
||||
|
@ -156,7 +157,7 @@ export const clipboardHandlerCreators = {
|
|||
copyNodes:
|
||||
({ selectedNodes }: Props) =>
|
||||
(): void => {
|
||||
const notifyService = pluginServices.getServices().notify;
|
||||
const notifyService = getCanvasNotifyService();
|
||||
|
||||
if (selectedNodes.length) {
|
||||
setClipboardData({ selectedNodes });
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}`;
|
||||
};
|
||||
|
||||
|
|
|
@ -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, untilPluginStartServicesReady } from './services/kibana_services';
|
||||
|
||||
export type { CoreStart, CoreSetup };
|
||||
|
||||
|
@ -121,22 +122,13 @@ 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);
|
||||
|
||||
const { pluginServices } = await import('./services');
|
||||
const { pluginServiceRegistry } = await import('./services/kibana');
|
||||
|
||||
pluginServices.setRegistry(
|
||||
pluginServiceRegistry.start({
|
||||
coreStart,
|
||||
startPlugins,
|
||||
appUpdater: this.appUpdater,
|
||||
initContext: this.initContext,
|
||||
})
|
||||
);
|
||||
|
||||
const { expressions, presentationUtil } = startPlugins;
|
||||
await presentationUtil.registerExpressionsLanguage(
|
||||
Object.values(expressions.getFunctions())
|
||||
|
@ -154,7 +146,13 @@ export class CanvasPlugin
|
|||
this.appUpdater
|
||||
);
|
||||
|
||||
const unmount = renderApp({ coreStart, startPlugins, params, canvasStore, pluginServices });
|
||||
const unmount = renderApp({
|
||||
coreStart,
|
||||
startPlugins,
|
||||
params,
|
||||
canvasStore,
|
||||
appUpdater: this.appUpdater,
|
||||
});
|
||||
|
||||
return () => {
|
||||
unmount();
|
||||
|
@ -190,6 +188,7 @@ export class CanvasPlugin
|
|||
}
|
||||
|
||||
public start(coreStart: CoreStart, startPlugins: CanvasStartDeps) {
|
||||
setKibanaServices(coreStart, startPlugins, this.initContext);
|
||||
initLoadingIndicator(coreStart.http.addLoadingCountSource);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,32 +6,30 @@
|
|||
*/
|
||||
import { 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();
|
||||
|
||||
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);
|
||||
}
|
||||
}, [isFullscreen, setFullscreen]);
|
||||
}, [isFullscreen]);
|
||||
|
||||
// Remove fullscreen when component unmounts
|
||||
useEffectOnce(() => () => {
|
||||
setFullscreen(true);
|
||||
coreServices.chrome.setIsVisible(true);
|
||||
document.querySelector('body')?.classList.remove(fullscreenClass);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useWorkpadService, usePlatformService } from '../../../services';
|
||||
import { getWorkpad } from '../../../state/selectors/workpad';
|
||||
import { setWorkpad } from '../../../state/actions/workpad';
|
||||
// @ts-expect-error
|
||||
|
@ -16,7 +15,11 @@ 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,
|
||||
getCanvasWorkpadService,
|
||||
} from '../../../services/canvas_workpad_service';
|
||||
import { spacesService } from '../../../services/kibana_services';
|
||||
|
||||
const getWorkpadLabel = () =>
|
||||
i18n.translate('xpack.canvas.workpadResolve.redirectLabel', {
|
||||
|
@ -32,9 +35,6 @@ export const useWorkpad = (
|
|||
loadPages: boolean = true,
|
||||
getRedirectPath: (workpadId: string) => string
|
||||
): [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<string | Error | undefined>(undefined);
|
||||
|
@ -47,14 +47,12 @@ export const useWorkpad = (
|
|||
const {
|
||||
workpad: { assets, ...workpad },
|
||||
...resolveProps
|
||||
} = await workpadResolve(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));
|
||||
|
@ -63,7 +61,7 @@ export const useWorkpad = (
|
|||
setError(e as Error | string);
|
||||
}
|
||||
})();
|
||||
}, [workpadId, dispatch, setError, loadPages, workpadResolve, storedWorkpad.id]);
|
||||
}, [workpadId, dispatch, setError, loadPages, storedWorkpad.id]);
|
||||
|
||||
useEffect(() => {
|
||||
// If the resolved info is not for the current workpad id, bail out
|
||||
|
@ -75,16 +73,16 @@ 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(),
|
||||
});
|
||||
}
|
||||
})();
|
||||
}, [workpadId, resolveInfo, getRedirectPath, platformService]);
|
||||
}, [workpadId, resolveInfo, getRedirectPath]);
|
||||
|
||||
return [storedWorkpad.id === workpadId ? storedWorkpad : undefined, error];
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
}),
|
||||
|
|
|
@ -10,13 +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, useNotifyService } from '../../../services';
|
||||
import { notifyError } from '../../../lib/assets';
|
||||
import { getCanvasWorkpadService } from '../../../services/canvas_workpad_service';
|
||||
|
||||
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) => [
|
||||
getWorkpad(state),
|
||||
|
@ -30,10 +27,12 @@ export const useWorkpadPersist = () => {
|
|||
useEffect(() => {
|
||||
if (canWrite) {
|
||||
if (workpadChanged) {
|
||||
service.updateWorkpad(workpad.id, workpad).catch((err) => {
|
||||
notifyError(err, notifyService.error);
|
||||
});
|
||||
getCanvasWorkpadService()
|
||||
.updateWorkpad(workpad.id, workpad)
|
||||
.catch((err) => {
|
||||
notifyError(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [service, workpad, workpadChanged, canWrite, notifyService.error]);
|
||||
}, [workpad, workpadChanged, canWrite]);
|
||||
};
|
||||
|
|
|
@ -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<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
const platformService = usePlatformService();
|
||||
const workpad = useSelector(getWorkpad);
|
||||
useFullscreenPresentationHelper();
|
||||
useAutoplayHelper();
|
||||
|
@ -30,18 +29,18 @@ export const WorkpadPresentationHelper: FC<PropsWithChildren<unknown>> = ({ 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,
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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 { API_ROUTE_CUSTOM_ELEMENT } from '../../common/lib';
|
||||
import { CustomElement } from '../../types';
|
||||
import { coreServices } from './kibana_services';
|
||||
|
||||
export interface CustomElementFindResponse {
|
||||
total: number;
|
||||
customElements: CustomElement[];
|
||||
}
|
||||
|
||||
class CanvasCustomElementService {
|
||||
public apiPath = `${API_ROUTE_CUSTOM_ELEMENT}`;
|
||||
|
||||
public async create(customElement: CustomElement) {
|
||||
await coreServices.http.post(this.apiPath, {
|
||||
body: JSON.stringify(customElement),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async get(customElementId: string): Promise<CustomElement> {
|
||||
return await coreServices.http
|
||||
.get<{ data: CustomElement }>(`${this.apiPath}/${customElementId}`, { version: '1' })
|
||||
.then(({ data: element }) => element);
|
||||
}
|
||||
|
||||
public async update(id: string, element: Partial<CustomElement>) {
|
||||
await coreServices.http.put(`${this.apiPath}/${id}`, {
|
||||
body: JSON.stringify(element),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async remove(id: string) {
|
||||
await coreServices.http.delete(`${this.apiPath}/${id}`, { version: '1' });
|
||||
}
|
||||
|
||||
public async find(searchTerm: string): Promise<CustomElementFindResponse> {
|
||||
return await coreServices.http.get(`${this.apiPath}/find`, {
|
||||
query: {
|
||||
name: searchTerm,
|
||||
perPage: 10000,
|
||||
},
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let canvasCustomElementService: CanvasCustomElementService;
|
||||
|
||||
export const getCustomElementService = () => {
|
||||
if (!canvasCustomElementService) {
|
||||
canvasCustomElementService = new CanvasCustomElementService();
|
||||
}
|
||||
return canvasCustomElementService;
|
||||
};
|
|
@ -4,34 +4,29 @@
|
|||
* 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';
|
||||
import { getCanvasNotifyService } from './canvas_notify_service';
|
||||
import { getCanvasFiltersService } from './canvas_filters_service';
|
||||
|
||||
interface Options {
|
||||
castToRender?: boolean;
|
||||
}
|
||||
|
||||
export class ExpressionsService {
|
||||
private filters: CanvasFiltersService;
|
||||
private notify: CanvasNotifyService;
|
||||
class ExpressionsService {
|
||||
private notifyService;
|
||||
private filtersService;
|
||||
|
||||
constructor(
|
||||
private readonly expressions: ExpressionsServiceStart,
|
||||
{ filters, notify }: CanvasExpressionsServiceRequiredServices
|
||||
) {
|
||||
this.filters = filters;
|
||||
this.notify = notify;
|
||||
constructor() {
|
||||
this.notifyService = getCanvasNotifyService();
|
||||
this.filtersService = getCanvasFiltersService();
|
||||
}
|
||||
|
||||
async interpretAst(
|
||||
|
@ -51,7 +46,7 @@ export class ExpressionsService {
|
|||
input: ExpressionValue = null,
|
||||
context?: ExpressionExecutionParams
|
||||
): Promise<ExpressionValue> {
|
||||
return await this.expressions
|
||||
return await expressionsService
|
||||
.execute(ast, input, { ...context, namespace: 'canvas' })
|
||||
.getData()
|
||||
.pipe(pluck('result'))
|
||||
|
@ -92,22 +87,22 @@ export 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;
|
||||
}
|
||||
}
|
||||
|
||||
getRenderer(name: string) {
|
||||
return this.expressions.getRenderer(name);
|
||||
return expressionsService.getRenderer(name);
|
||||
}
|
||||
|
||||
getFunctions() {
|
||||
return this.expressions.getFunctions();
|
||||
return expressionsService.getFunctions();
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -122,19 +117,11 @@ export class ExpressionsService {
|
|||
}
|
||||
}
|
||||
|
||||
export type CanvasExpressionsService = ExpressionsService;
|
||||
export interface CanvasExpressionsServiceRequiredServices {
|
||||
notify: CanvasNotifyService;
|
||||
filters: CanvasFiltersService;
|
||||
}
|
||||
let canvasExpressionsService: ExpressionsService;
|
||||
|
||||
export type CanvasExpressionsServiceFactory = KibanaPluginServiceFactory<
|
||||
CanvasExpressionsService,
|
||||
CanvasStartDeps,
|
||||
CanvasExpressionsServiceRequiredServices
|
||||
>;
|
||||
|
||||
export const expressionsServiceFactory: CanvasExpressionsServiceFactory = (
|
||||
{ startPlugins },
|
||||
requiredServices
|
||||
) => new ExpressionsService(startPlugins.expressions, requiredServices);
|
||||
export const getCanvasExpressionService = () => {
|
||||
if (!canvasExpressionsService) {
|
||||
canvasExpressionsService = new ExpressionsService();
|
||||
}
|
||||
return canvasExpressionsService;
|
||||
};
|
|
@ -5,25 +5,21 @@
|
|||
* 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';
|
||||
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';
|
||||
|
||||
export class FiltersService {
|
||||
constructor() {}
|
||||
import { setFilter } from '../state/actions/filters';
|
||||
|
||||
class FiltersService {
|
||||
getFilters(state: State = getState()) {
|
||||
return getGlobalFilters(state);
|
||||
}
|
||||
|
||||
updateFilter(filterId: string, filterExpression: string) {
|
||||
const { dispatch } = getStore();
|
||||
dispatch(setFilter(filterExpression, filterId, true));
|
||||
dispatch(setFilter(filterExpression, filterId));
|
||||
}
|
||||
|
||||
getFiltersContext(state: State = getState()) {
|
||||
|
@ -32,11 +28,11 @@ export class FiltersService {
|
|||
}
|
||||
}
|
||||
|
||||
export type CanvasFiltersService = FiltersService;
|
||||
let canvasFiltersService: FiltersService;
|
||||
|
||||
export type CanvasFiltersServiceFactory = KibanaPluginServiceFactory<
|
||||
CanvasFiltersService,
|
||||
CanvasStartDeps
|
||||
>;
|
||||
|
||||
export const filtersServiceFactory: CanvasFiltersServiceFactory = () => new FiltersService();
|
||||
export const getCanvasFiltersService = () => {
|
||||
if (!canvasFiltersService) {
|
||||
canvasFiltersService = new FiltersService();
|
||||
}
|
||||
return canvasFiltersService;
|
||||
};
|
|
@ -6,17 +6,10 @@
|
|||
*/
|
||||
|
||||
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';
|
||||
|
||||
export type CanvasNotifyServiceFactory = KibanaPluginServiceFactory<
|
||||
CanvasNotifyService,
|
||||
CanvasStartDeps
|
||||
>;
|
||||
import { formatMsg } from '../lib/format_msg';
|
||||
import { coreServices } from './kibana_services';
|
||||
|
||||
const getToast = (err: Error | string, opts: ToastInputFields = {}) => {
|
||||
const errData = (get(err, 'response') || err) as Error | string;
|
||||
|
@ -36,8 +29,15 @@ const getToast = (err: Error | string, opts: ToastInputFields = {}) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const notifyServiceFactory: CanvasNotifyServiceFactory = ({ coreStart }) => {
|
||||
const toasts = coreStart.notifications.toasts;
|
||||
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;
|
||||
|
||||
return {
|
||||
/*
|
200
x-pack/plugins/canvas/public/services/canvas_workpad_service.ts
Normal file
200
x-pack/plugins/canvas/public/services/canvas_workpad_service.ts
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* 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, SavedObject } from '@kbn/core/public';
|
||||
import {
|
||||
API_ROUTE_SHAREABLE_ZIP,
|
||||
API_ROUTE_TEMPLATES,
|
||||
API_ROUTE_WORKPAD,
|
||||
API_ROUTE_WORKPAD_ASSETS,
|
||||
API_ROUTE_WORKPAD_STRUCTURES,
|
||||
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<Pick<CanvasWorkpad, 'name' | 'id' | '@timestamp' | '@created'>>;
|
||||
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'];
|
||||
}
|
||||
|
||||
/*
|
||||
Remove any top level keys from the workpad which will be rejected by validation
|
||||
*/
|
||||
const validKeys = [
|
||||
'@created',
|
||||
'@timestamp',
|
||||
'assets',
|
||||
'colors',
|
||||
'css',
|
||||
'variables',
|
||||
'height',
|
||||
'id',
|
||||
'isWriteable',
|
||||
'name',
|
||||
'page',
|
||||
'pages',
|
||||
'width',
|
||||
];
|
||||
|
||||
const sanitizeWorkpad = function (workpad: CanvasWorkpad) {
|
||||
const workpadKeys = Object.keys(workpad);
|
||||
|
||||
for (const key of workpadKeys) {
|
||||
if (!validKeys.includes(key)) {
|
||||
delete (workpad as { [key: string]: any })[key];
|
||||
}
|
||||
}
|
||||
|
||||
return workpad;
|
||||
};
|
||||
|
||||
class CanvasWorkpadService {
|
||||
private apiPath = `${API_ROUTE_WORKPAD}`;
|
||||
|
||||
public async get(id: string): Promise<CanvasWorkpad> {
|
||||
const workpad = await coreServices.http.get<any>(`${this.apiPath}/${id}`, { version: '1' });
|
||||
|
||||
return { css: DEFAULT_WORKPAD_CSS, variables: [], ...workpad };
|
||||
}
|
||||
|
||||
public async export(id: string) {
|
||||
const workpad = await coreServices.http.get<SavedObject<CanvasWorkpad>>(
|
||||
`${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<ResolveWorkpadResponse> {
|
||||
const { workpad, ...resolveProps } = await coreServices.http.get<ResolveWorkpadResponse>(
|
||||
`${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,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public async create(workpad: CanvasWorkpad): Promise<CanvasWorkpad> {
|
||||
return coreServices.http.post(this.apiPath, {
|
||||
body: JSON.stringify({
|
||||
...sanitizeWorkpad({ ...workpad }),
|
||||
assets: workpad.assets || {},
|
||||
variables: workpad.variables || [],
|
||||
}),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async import(workpad: CanvasWorkpad): Promise<CanvasWorkpad> {
|
||||
return coreServices.http.post(`${this.apiPath}/import`, {
|
||||
body: JSON.stringify({
|
||||
...sanitizeWorkpad({ ...workpad }),
|
||||
assets: workpad.assets || {},
|
||||
variables: workpad.variables || [],
|
||||
}),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async createFromTemplate(templateId: string): Promise<CanvasWorkpad> {
|
||||
return coreServices.http.post(this.apiPath, {
|
||||
body: JSON.stringify({ templateId }),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async findTemplates(): Promise<TemplateFindResponse> {
|
||||
return coreServices.http.get(API_ROUTE_TEMPLATES, { version: '1' });
|
||||
}
|
||||
|
||||
public async find(searchTerm: string): Promise<WorkpadFindResponse> {
|
||||
// TODO: this shouldn't be necessary. Check for usage.
|
||||
const validSearchTerm = typeof searchTerm === 'string' && searchTerm.length > 0;
|
||||
|
||||
return coreServices.http.get(`${this.apiPath}/find`, {
|
||||
query: {
|
||||
perPage: 10000,
|
||||
name: validSearchTerm ? searchTerm : '',
|
||||
},
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async remove(id: string) {
|
||||
coreServices.http.delete(`${this.apiPath}/${id}`, { version: '1' });
|
||||
}
|
||||
|
||||
public async update(id: string, workpad: CanvasWorkpad) {
|
||||
coreServices.http.put(`${this.apiPath}/${id}`, {
|
||||
body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async updateWorkpad(id: string, workpad: CanvasWorkpad) {
|
||||
coreServices.http.put(`${API_ROUTE_WORKPAD_STRUCTURES}/${id}`, {
|
||||
body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async updateAssets(id: string, assets: CanvasWorkpad['assets']) {
|
||||
coreServices.http.put(`${API_ROUTE_WORKPAD_ASSETS}/${id}`, {
|
||||
body: JSON.stringify(assets),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
|
||||
public async getRuntimeZip(workpad: CanvasRenderedWorkpad): Promise<Blob> {
|
||||
return coreServices.http.post<Blob>(API_ROUTE_SHAREABLE_ZIP, {
|
||||
body: JSON.stringify(workpad),
|
||||
version: '1',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let canvasWorkpadService: CanvasWorkpadService;
|
||||
|
||||
export const getCanvasWorkpadService: () => CanvasWorkpadService = () => {
|
||||
if (!canvasWorkpadService) {
|
||||
canvasWorkpadService = new CanvasWorkpadService();
|
||||
}
|
||||
return canvasWorkpadService;
|
||||
};
|
|
@ -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<void>;
|
||||
get: (customElementId: string) => Promise<CustomElement>;
|
||||
update: (id: string, element: Partial<CustomElement>) => Promise<void>;
|
||||
remove: (id: string) => Promise<void>;
|
||||
find: (searchTerm: string) => Promise<CustomElementFindResponse>;
|
||||
}
|
|
@ -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<string[]>;
|
||||
getDataViews: () => Promise<Array<Pick<DataView, 'id' | 'name' | 'title'>>>;
|
||||
getDefaultDataView: () => Promise<Pick<DataView, 'id' | 'name' | 'title'> | undefined>;
|
||||
}
|
|
@ -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<TSavedObjectAttributes>]>;
|
||||
getEmbeddableFactories: () => IterableIterator<EmbeddableFactory>;
|
||||
getStateTransfer: () => EmbeddableStateTransfer;
|
||||
}
|
|
@ -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';
|
|
@ -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';
|
|
@ -6,55 +6,11 @@
|
|||
*/
|
||||
|
||||
export * from './legacy';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { PluginServices } from '@kbn/presentation-util-plugin/public';
|
||||
import { getCanvasNotifyService } from './canvas_notify_service';
|
||||
|
||||
import { CanvasCustomElementService } from './custom_element';
|
||||
import { CanvasDataViewsService } from './data_views';
|
||||
import { CanvasEmbeddablesService } from './embeddables';
|
||||
import { CanvasExpressionsService } from './expressions';
|
||||
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';
|
||||
|
||||
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<CanvasPluginServices>();
|
||||
|
||||
export const useCustomElementService = () =>
|
||||
(() => pluginServices.getHooks().customElement.useService())();
|
||||
export const useDataViewsService = () => (() => pluginServices.getHooks().dataViews.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 useNotifyService = () => (() => pluginServices.getHooks().notify.useService())();
|
||||
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())();
|
||||
export const useNotifyService = () => {
|
||||
const canvasNotifyService = useMemo(() => getCanvasNotifyService(), []);
|
||||
return canvasNotifyService;
|
||||
};
|
||||
|
|
|
@ -1,44 +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 { API_ROUTE_CUSTOM_ELEMENT } from '../../../common/lib/constants';
|
||||
import { CustomElement } from '../../../types';
|
||||
import { CanvasStartDeps } from '../../plugin';
|
||||
import { CanvasCustomElementService } from '../custom_element';
|
||||
|
||||
export type CanvasCustomElementServiceFactory = KibanaPluginServiceFactory<
|
||||
CanvasCustomElementService,
|
||||
CanvasStartDeps
|
||||
>;
|
||||
|
||||
export const customElementServiceFactory: CanvasCustomElementServiceFactory = ({ coreStart }) => {
|
||||
const { http } = coreStart;
|
||||
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',
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
|
@ -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;
|
||||
},
|
||||
});
|
|
@ -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,
|
||||
});
|
|
@ -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<CanvasStartDeps>
|
||||
> = {
|
||||
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<CanvasStartDeps>
|
||||
>(pluginServiceProviders);
|
|
@ -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,
|
||||
});
|
|
@ -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);
|
||||
},
|
||||
});
|
|
@ -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,
|
||||
};
|
||||
};
|
|
@ -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();
|
||||
};
|
|
@ -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,
|
||||
});
|
|
@ -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,
|
||||
});
|
|
@ -1,170 +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 { SavedObject } from '@kbn/core/public';
|
||||
import { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public';
|
||||
|
||||
import { CanvasStartDeps } from '../../plugin';
|
||||
import { CanvasWorkpadService, ResolveWorkpadResponse } from '../workpad';
|
||||
|
||||
import {
|
||||
API_ROUTE_WORKPAD,
|
||||
DEFAULT_WORKPAD_CSS,
|
||||
API_ROUTE_TEMPLATES,
|
||||
API_ROUTE_WORKPAD_ASSETS,
|
||||
API_ROUTE_WORKPAD_STRUCTURES,
|
||||
API_ROUTE_SHAREABLE_ZIP,
|
||||
} from '../../../common/lib/constants';
|
||||
import { CanvasWorkpad } from '../../../types';
|
||||
|
||||
export type CanvasWorkpadServiceFactory = KibanaPluginServiceFactory<
|
||||
CanvasWorkpadService,
|
||||
CanvasStartDeps
|
||||
>;
|
||||
|
||||
/*
|
||||
Remove any top level keys from the workpad which will be rejected by validation
|
||||
*/
|
||||
const validKeys = [
|
||||
'@created',
|
||||
'@timestamp',
|
||||
'assets',
|
||||
'colors',
|
||||
'css',
|
||||
'variables',
|
||||
'height',
|
||||
'id',
|
||||
'isWriteable',
|
||||
'name',
|
||||
'page',
|
||||
'pages',
|
||||
'width',
|
||||
];
|
||||
|
||||
const sanitizeWorkpad = function (workpad: CanvasWorkpad) {
|
||||
const workpadKeys = Object.keys(workpad);
|
||||
|
||||
for (const key of workpadKeys) {
|
||||
if (!validKeys.includes(key)) {
|
||||
delete (workpad as { [key: string]: any })[key];
|
||||
}
|
||||
}
|
||||
|
||||
return workpad;
|
||||
};
|
||||
|
||||
export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart, startPlugins }) => {
|
||||
const getApiPath = function () {
|
||||
return `${API_ROUTE_WORKPAD}`;
|
||||
};
|
||||
|
||||
return {
|
||||
get: async (id: string) => {
|
||||
const workpad = await coreStart.http.get<any>(`${getApiPath()}/${id}`, { version: '1' });
|
||||
|
||||
return { css: DEFAULT_WORKPAD_CSS, variables: [], ...workpad };
|
||||
},
|
||||
export: async (id: string) => {
|
||||
const workpad = await coreStart.http.get<SavedObject<CanvasWorkpad>>(
|
||||
`${getApiPath()}/export/${id}`,
|
||||
{ version: '1' }
|
||||
);
|
||||
const { attributes } = workpad;
|
||||
|
||||
return {
|
||||
...workpad,
|
||||
attributes: {
|
||||
...attributes,
|
||||
css: attributes.css ?? DEFAULT_WORKPAD_CSS,
|
||||
variables: attributes.variables ?? [],
|
||||
},
|
||||
};
|
||||
},
|
||||
resolve: async (id: string) => {
|
||||
const { workpad, ...resolveProps } = await coreStart.http.get<ResolveWorkpadResponse>(
|
||||
`${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 coreStart.http.post(getApiPath(), {
|
||||
body: JSON.stringify({
|
||||
...sanitizeWorkpad({ ...workpad }),
|
||||
assets: workpad.assets || {},
|
||||
variables: workpad.variables || [],
|
||||
}),
|
||||
version: '1',
|
||||
});
|
||||
},
|
||||
import: (workpad: CanvasWorkpad) =>
|
||||
coreStart.http.post(`${getApiPath()}/import`, {
|
||||
body: JSON.stringify({
|
||||
...sanitizeWorkpad({ ...workpad }),
|
||||
assets: workpad.assets || {},
|
||||
variables: workpad.variables || [],
|
||||
}),
|
||||
version: '1',
|
||||
}),
|
||||
createFromTemplate: (templateId: string) => {
|
||||
return coreStart.http.post(getApiPath(), {
|
||||
body: JSON.stringify({ templateId }),
|
||||
version: '1',
|
||||
});
|
||||
},
|
||||
findTemplates: async () => coreStart.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`, {
|
||||
query: {
|
||||
perPage: 10000,
|
||||
name: validSearchTerm ? searchTerm : '',
|
||||
},
|
||||
version: '1',
|
||||
});
|
||||
},
|
||||
remove: (id: string) => {
|
||||
return coreStart.http.delete(`${getApiPath()}/${id}`, { version: '1' });
|
||||
},
|
||||
update: (id, workpad) => {
|
||||
return coreStart.http.put(`${getApiPath()}/${id}`, {
|
||||
body: JSON.stringify({ ...sanitizeWorkpad({ ...workpad }) }),
|
||||
version: '1',
|
||||
});
|
||||
},
|
||||
updateWorkpad: (id, workpad) => {
|
||||
return coreStart.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}`, {
|
||||
body: JSON.stringify(assets),
|
||||
version: '1',
|
||||
});
|
||||
},
|
||||
getRuntimeZip: (workpad) => {
|
||||
return coreStart.http.post<Blob>(API_ROUTE_SHAREABLE_ZIP, {
|
||||
body: JSON.stringify(workpad),
|
||||
version: '1',
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
76
x-pack/plugins/canvas/public/services/kibana_services.ts
Normal file
76
x-pack/plugins/canvas/public/services/kibana_services.ts
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 { 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 { CanvasStartDeps } from '../plugin';
|
||||
|
||||
export let kibanaVersion: string;
|
||||
|
||||
export let coreServices: CoreStart;
|
||||
export let contentManagementService: ContentManagementPublicStart;
|
||||
export let dataService: DataPublicPluginStart;
|
||||
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;
|
||||
export let uiActionsService: UiActionsPublicStart;
|
||||
export let visualizationsService: VisualizationsStart;
|
||||
|
||||
const servicesReady$ = new BehaviorSubject(false);
|
||||
|
||||
export const setKibanaServices = (
|
||||
kibanaCore: CoreStart,
|
||||
deps: CanvasStartDeps,
|
||||
initContext: PluginInitializerContext
|
||||
) => {
|
||||
kibanaVersion = initContext.env.packageInfo.version;
|
||||
|
||||
coreServices = kibanaCore;
|
||||
contentManagementService = deps.contentManagement;
|
||||
dataService = deps.data;
|
||||
dataViewsService = deps.dataViews;
|
||||
embeddableService = deps.embeddable;
|
||||
expressionsService = deps.expressions;
|
||||
presentationUtilService = deps.presentationUtil;
|
||||
reportingService = Boolean(
|
||||
deps.reporting?.usesUiCapabilities() && !kibanaCore.application.capabilities.canvas?.generatePdf
|
||||
)
|
||||
? undefined
|
||||
: deps.reporting;
|
||||
spacesService = deps.spaces;
|
||||
uiActionsService = deps.uiActions;
|
||||
visualizationsService = deps.visualizations;
|
||||
|
||||
servicesReady$.next(true);
|
||||
};
|
||||
|
||||
export const untilPluginStartServicesReady = () => {
|
||||
if (servicesReady$.value) return Promise.resolve();
|
||||
return new Promise<void>((resolve) => {
|
||||
const subscription = servicesReady$.subscribe((isInitialized) => {
|
||||
if (isInitialized) {
|
||||
subscription.unsubscribe();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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<ReportingService> = (
|
||||
_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();
|
||||
};
|
125
x-pack/plugins/canvas/public/services/mocks.ts
Normal file
125
x-pack/plugins/canvas/public/services/mocks.ts
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* 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 { chartPluginMock } from '@kbn/charts-plugin/public/mocks';
|
||||
import { contentManagementMock } from '@kbn/content-management-plugin/public/mocks';
|
||||
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';
|
||||
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(),
|
||||
reporting: reportingPluginMock.createStartContract(),
|
||||
spaces: spacesPluginMock.createStartContract(),
|
||||
uiActions: uiActionsPluginMock.createStartContract(),
|
||||
visualizations: visualizationsPluginMock.createStartContract(),
|
||||
},
|
||||
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();
|
|
@ -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;
|
||||
}
|
|
@ -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<boolean>;
|
||||
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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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<CanvasPluginServices, StorybookParams> =
|
||||
{
|
||||
...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',
|
||||
},
|
||||
},
|
||||
};
|
|
@ -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<CanvasNotifyService, StorybookParams>;
|
||||
|
||||
export const notifyServiceFactory: CanvasNotifyServiceFactory = () => ({
|
||||
success: (message) => action(`success: ${message}`)(),
|
||||
error: (message) => action(`error: ${message}`)(),
|
||||
info: (message) => action(`info: ${message}`)(),
|
||||
warning: (message) => action(`warning: ${message}`)(),
|
||||
});
|
|
@ -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<CanvasWorkpadService, StorybookParams>;
|
||||
|
||||
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' })),
|
||||
});
|
|
@ -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<CanvasCustomElementService>;
|
||||
|
||||
const noop = (..._args: any[]): any => {};
|
||||
|
||||
export const customElementServiceFactory: CanvasCustomElementServiceFactory = () => ({
|
||||
create: noop,
|
||||
find: noop,
|
||||
get: noop,
|
||||
remove: noop,
|
||||
update: noop,
|
||||
});
|
|
@ -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<CanvasDataViewsService>;
|
||||
|
||||
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',
|
||||
}),
|
||||
});
|
|
@ -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<CanvasEmbeddablesService>;
|
||||
|
||||
const noop = (..._args: any[]): any => {};
|
||||
|
||||
export const embeddablesServiceFactory: EmbeddablesServiceFactory = () => ({
|
||||
reactEmbeddableRegistryHasKey: noop,
|
||||
getReactEmbeddableSavedObjects: noop,
|
||||
getEmbeddableFactories: noop,
|
||||
getStateTransfer: noop,
|
||||
});
|
|
@ -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);
|
||||
};
|
|
@ -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<CanvasFiltersService, {}>;
|
||||
|
||||
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: {} }),
|
||||
});
|
|
@ -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<CanvasPluginServices> = {
|
||||
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<CanvasPluginServices>(
|
||||
pluginServiceProviders
|
||||
);
|
|
@ -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<CanvasLabsService>;
|
||||
|
||||
const noop = (..._args: any[]): any => {};
|
||||
|
||||
export const labsServiceFactory: CanvasLabsServiceFactory = () => ({
|
||||
getProject: noop,
|
||||
getProjects: noop,
|
||||
getProjectIDs: () => projectIDs,
|
||||
isProjectEnabled: () => false,
|
||||
isLabsEnabled: () => true,
|
||||
projectIDs,
|
||||
reset: noop,
|
||||
setProjectStatus: noop,
|
||||
});
|
|
@ -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<CanvasNavLinkService>;
|
||||
|
||||
const noop = (..._args: any[]): any => {};
|
||||
|
||||
export const navLinkServiceFactory: CanvasNavLinkServiceFactory = () => ({
|
||||
updatePath: noop,
|
||||
});
|
|
@ -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<CanvasNotifyService>;
|
||||
|
||||
const noop = (..._args: any[]): any => {};
|
||||
|
||||
export const notifyServiceFactory: CanvasNotifyServiceFactory = () => ({
|
||||
error: noop,
|
||||
info: noop,
|
||||
success: noop,
|
||||
warning: noop,
|
||||
});
|
|
@ -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<CanvasPlatformService>;
|
||||
|
||||
const noop = (..._args: any[]): any => {};
|
||||
|
||||
const uiSettings: Record<string, any> = {
|
||||
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,
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue