mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[canvas] Create Custom Elements Service (#107356)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
f3e094c836
commit
44014c78b6
12 changed files with 247 additions and 243 deletions
|
@ -17,13 +17,11 @@ storiesOf('components/SavedElementsModal', module)
|
|||
.add('no custom elements', () => (
|
||||
<SavedElementsModal
|
||||
customElements={[] as CustomElement[]}
|
||||
search=""
|
||||
setSearch={action('setSearch')}
|
||||
onAddCustomElement={action('onAddCustomElement')}
|
||||
onSearch={action('onSearch')}
|
||||
onUpdateCustomElement={action('onUpdateCustomElement')}
|
||||
onRemoveCustomElement={action('onRemoveCustomElement')}
|
||||
onClose={action('onClose')}
|
||||
addCustomElement={action('addCustomElement')}
|
||||
findCustomElements={action('findCustomElements')}
|
||||
updateCustomElement={action('updateCustomElement')}
|
||||
removeCustomElement={action('removeCustomElement')}
|
||||
/>
|
||||
))
|
||||
.add(
|
||||
|
@ -31,13 +29,11 @@ storiesOf('components/SavedElementsModal', module)
|
|||
(_, props) => (
|
||||
<SavedElementsModal
|
||||
customElements={props?.testCustomElements}
|
||||
search=""
|
||||
setSearch={action('setSearch')}
|
||||
onAddCustomElement={action('onAddCustomElement')}
|
||||
onSearch={action('onSearch')}
|
||||
onUpdateCustomElement={action('onUpdateCustomElement')}
|
||||
onRemoveCustomElement={action('onRemoveCustomElement')}
|
||||
onClose={action('onClose')}
|
||||
addCustomElement={action('addCustomElement')}
|
||||
findCustomElements={action('findCustomElements')}
|
||||
updateCustomElement={action('updateCustomElement')}
|
||||
removeCustomElement={action('removeCustomElement')}
|
||||
/>
|
||||
),
|
||||
{ decorators: [waitFor(getTestCustomElements())] }
|
||||
|
@ -47,13 +43,12 @@ storiesOf('components/SavedElementsModal', module)
|
|||
(_, props) => (
|
||||
<SavedElementsModal
|
||||
customElements={props?.testCustomElements}
|
||||
search="Element 2"
|
||||
initialSearch="Element 2"
|
||||
onAddCustomElement={action('onAddCustomElement')}
|
||||
onSearch={action('onSearch')}
|
||||
onUpdateCustomElement={action('onUpdateCustomElement')}
|
||||
onRemoveCustomElement={action('onRemoveCustomElement')}
|
||||
onClose={action('onClose')}
|
||||
setSearch={action('setSearch')}
|
||||
addCustomElement={action('addCustomElement')}
|
||||
findCustomElements={action('findCustomElements')}
|
||||
updateCustomElement={action('updateCustomElement')}
|
||||
removeCustomElement={action('removeCustomElement')}
|
||||
/>
|
||||
),
|
||||
{ decorators: [waitFor(getTestCustomElements())] }
|
||||
|
|
|
@ -13,7 +13,6 @@ import React, {
|
|||
useEffect,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
EuiModal,
|
||||
EuiModalBody,
|
||||
|
@ -81,66 +80,62 @@ const strings = {
|
|||
|
||||
export interface Props {
|
||||
/**
|
||||
* Adds the custom element to the workpad
|
||||
* Element add handler
|
||||
*/
|
||||
addCustomElement: (customElement: CustomElement) => void;
|
||||
/**
|
||||
* Queries ES for custom element saved objects
|
||||
*/
|
||||
findCustomElements: () => void;
|
||||
onAddCustomElement: (customElement: CustomElement) => void;
|
||||
/**
|
||||
* Handler invoked when the modal closes
|
||||
*/
|
||||
onClose: () => void;
|
||||
/**
|
||||
* Deletes the custom element
|
||||
* Element delete handler
|
||||
*/
|
||||
removeCustomElement: (id: string) => void;
|
||||
onRemoveCustomElement: (id: string) => void;
|
||||
/**
|
||||
* Saved edits to the custom element
|
||||
* Element update handler
|
||||
*/
|
||||
updateCustomElement: (id: string, name: string, description: string, image: string) => void;
|
||||
onUpdateCustomElement: (id: string, name: string, description: string, image: string) => void;
|
||||
/**
|
||||
* Array of custom elements to display
|
||||
*/
|
||||
customElements: CustomElement[];
|
||||
/**
|
||||
* Text used to filter custom elements list
|
||||
* Element search handler
|
||||
*/
|
||||
search: string;
|
||||
onSearch: (search: string) => void;
|
||||
/**
|
||||
* Setter for search text
|
||||
* Initial search term
|
||||
*/
|
||||
setSearch: (search: string) => void;
|
||||
initialSearch?: string;
|
||||
}
|
||||
|
||||
export const SavedElementsModal: FunctionComponent<Props> = ({
|
||||
search,
|
||||
setSearch,
|
||||
customElements,
|
||||
addCustomElement,
|
||||
findCustomElements,
|
||||
onAddCustomElement,
|
||||
onClose,
|
||||
removeCustomElement,
|
||||
updateCustomElement,
|
||||
onRemoveCustomElement,
|
||||
onUpdateCustomElement,
|
||||
onSearch,
|
||||
initialSearch = '',
|
||||
}) => {
|
||||
const hasLoadedElements = useRef<boolean>(false);
|
||||
const [elementToDelete, setElementToDelete] = useState<CustomElement | null>(null);
|
||||
const [elementToEdit, setElementToEdit] = useState<CustomElement | null>(null);
|
||||
const [search, setSearch] = useState<string>(initialSearch);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasLoadedElements.current) {
|
||||
hasLoadedElements.current = true;
|
||||
findCustomElements();
|
||||
onSearch('');
|
||||
}
|
||||
}, [findCustomElements, hasLoadedElements]);
|
||||
}, [onSearch, hasLoadedElements]);
|
||||
|
||||
const showEditModal = (element: CustomElement) => setElementToEdit(element);
|
||||
const hideEditModal = () => setElementToEdit(null);
|
||||
|
||||
const handleEdit = async (name: string, description: string, image: string) => {
|
||||
if (elementToEdit) {
|
||||
updateCustomElement(elementToEdit.id, name, description, image);
|
||||
onUpdateCustomElement(elementToEdit.id, name, description, image);
|
||||
}
|
||||
hideEditModal();
|
||||
};
|
||||
|
@ -150,7 +145,7 @@ export const SavedElementsModal: FunctionComponent<Props> = ({
|
|||
|
||||
const handleDelete = async () => {
|
||||
if (elementToDelete) {
|
||||
removeCustomElement(elementToDelete.id);
|
||||
onRemoveCustomElement(elementToDelete.id);
|
||||
}
|
||||
hideDeleteModal();
|
||||
};
|
||||
|
@ -193,7 +188,7 @@ export const SavedElementsModal: FunctionComponent<Props> = ({
|
|||
const sortElements = (elements: CustomElement[]): CustomElement[] =>
|
||||
sortBy(elements, 'displayName');
|
||||
|
||||
const onSearch = (e: ChangeEvent<HTMLInputElement>) => setSearch(e.target.value);
|
||||
const onFieldSearch = (e: ChangeEvent<HTMLInputElement>) => setSearch(e.target.value);
|
||||
|
||||
let customElementContent = (
|
||||
<EuiEmptyPrompt
|
||||
|
@ -209,7 +204,7 @@ export const SavedElementsModal: FunctionComponent<Props> = ({
|
|||
<ElementGrid
|
||||
elements={sortElements(customElements)}
|
||||
filterText={search}
|
||||
onClick={addCustomElement}
|
||||
onClick={onAddCustomElement}
|
||||
onEdit={showEditModal}
|
||||
onDelete={showDeleteModal}
|
||||
/>
|
||||
|
@ -235,7 +230,7 @@ export const SavedElementsModal: FunctionComponent<Props> = ({
|
|||
fullWidth
|
||||
value={search}
|
||||
placeholder={strings.getFindElementPlaceholder()}
|
||||
onChange={onSearch}
|
||||
onChange={onFieldSearch}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
{customElementContent}
|
||||
|
@ -252,11 +247,3 @@ export const SavedElementsModal: FunctionComponent<Props> = ({
|
|||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
SavedElementsModal.propTypes = {
|
||||
addCustomElement: PropTypes.func.isRequired,
|
||||
findCustomElements: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
removeCustomElement: PropTypes.func.isRequired,
|
||||
updateCustomElement: PropTypes.func.isRequired,
|
||||
};
|
||||
|
|
|
@ -1,138 +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 { connect } from 'react-redux';
|
||||
import { Dispatch } from 'redux';
|
||||
import { compose, withState } from 'recompose';
|
||||
import { camelCase } from 'lodash';
|
||||
import { cloneSubgraphs } from '../../lib/clone_subgraphs';
|
||||
import * as customElementService from '../../lib/custom_element_service';
|
||||
import { withServices, WithServicesProps, pluginServices } from '../../services';
|
||||
// @ts-expect-error untyped local
|
||||
import { selectToplevelNodes } from '../../state/actions/transient';
|
||||
// @ts-expect-error untyped local
|
||||
import { insertNodes } from '../../state/actions/elements';
|
||||
import { getSelectedPage } from '../../state/selectors/workpad';
|
||||
import { trackCanvasUiMetric, METRIC_TYPE } from '../../lib/ui_metric';
|
||||
import {
|
||||
SavedElementsModal as Component,
|
||||
Props as ComponentProps,
|
||||
} from './saved_elements_modal.component';
|
||||
import { State, PositionedElement, CustomElement } from '../../../types';
|
||||
|
||||
const customElementAdded = 'elements-custom-added';
|
||||
|
||||
interface OwnProps {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
interface OwnPropsWithState extends OwnProps {
|
||||
customElements: CustomElement[];
|
||||
setCustomElements: (customElements: CustomElement[]) => void;
|
||||
search: string;
|
||||
setSearch: (search: string) => void;
|
||||
}
|
||||
|
||||
interface DispatchProps {
|
||||
selectToplevelNodes: (nodes: PositionedElement[]) => void;
|
||||
insertNodes: (selectedNodes: PositionedElement[], pageId: string) => void;
|
||||
}
|
||||
|
||||
interface StateProps {
|
||||
pageId: string;
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: State): StateProps => ({
|
||||
pageId: getSelectedPage(state),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
|
||||
selectToplevelNodes: (nodes: PositionedElement[]) =>
|
||||
dispatch(
|
||||
selectToplevelNodes(
|
||||
nodes
|
||||
.filter((e: PositionedElement): boolean => !e.position.parent)
|
||||
.map((e: PositionedElement): string => e.id)
|
||||
)
|
||||
),
|
||||
insertNodes: (selectedNodes: PositionedElement[], pageId: string) =>
|
||||
dispatch(insertNodes(selectedNodes, pageId)),
|
||||
});
|
||||
|
||||
const mergeProps = (
|
||||
stateProps: StateProps,
|
||||
dispatchProps: DispatchProps,
|
||||
ownProps: OwnPropsWithState & WithServicesProps
|
||||
): ComponentProps => {
|
||||
const notifyService = pluginServices.getServices().notify;
|
||||
const { pageId } = stateProps;
|
||||
const { onClose, search, setCustomElements } = ownProps;
|
||||
|
||||
const findCustomElements = async () => {
|
||||
const { customElements } = await customElementService.find(search);
|
||||
setCustomElements(customElements);
|
||||
};
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
// add custom element to the page
|
||||
addCustomElement: (customElement: CustomElement) => {
|
||||
const { selectedNodes = [] } = JSON.parse(customElement.content) || {};
|
||||
const clonedNodes = selectedNodes && cloneSubgraphs(selectedNodes);
|
||||
if (clonedNodes) {
|
||||
dispatchProps.insertNodes(clonedNodes, pageId); // first clone and persist the new node(s)
|
||||
dispatchProps.selectToplevelNodes(clonedNodes); // then select the cloned node(s)
|
||||
}
|
||||
onClose();
|
||||
trackCanvasUiMetric(METRIC_TYPE.LOADED, customElementAdded);
|
||||
},
|
||||
// custom element search
|
||||
findCustomElements: async (text?: string) => {
|
||||
try {
|
||||
await findCustomElements();
|
||||
} catch (err) {
|
||||
notifyService.error(err, {
|
||||
title: `Couldn't find custom elements`,
|
||||
});
|
||||
}
|
||||
},
|
||||
// remove custom element
|
||||
removeCustomElement: async (id: string) => {
|
||||
try {
|
||||
await customElementService.remove(id);
|
||||
await findCustomElements();
|
||||
} catch (err) {
|
||||
notifyService.error(err, {
|
||||
title: `Couldn't delete custom elements`,
|
||||
});
|
||||
}
|
||||
},
|
||||
// update custom element
|
||||
updateCustomElement: async (id: string, name: string, description: string, image: string) => {
|
||||
try {
|
||||
await customElementService.update(id, {
|
||||
name: camelCase(name),
|
||||
displayName: name,
|
||||
image,
|
||||
help: description,
|
||||
});
|
||||
await findCustomElements();
|
||||
} catch (err) {
|
||||
notifyService.error(err, {
|
||||
title: `Couldn't update custom elements`,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const SavedElementsModal = compose<ComponentProps, OwnProps>(
|
||||
withServices,
|
||||
withState('search', 'setSearch', ''),
|
||||
withState('customElements', 'setCustomElements', []),
|
||||
connect(mapStateToProps, mapDispatchToProps, mergeProps)
|
||||
)(Component);
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { camelCase } from 'lodash';
|
||||
import { cloneSubgraphs } from '../../lib/clone_subgraphs';
|
||||
import { useNotifyService, useCustomElementService } from '../../services';
|
||||
// @ts-expect-error untyped local
|
||||
import { selectToplevelNodes } from '../../state/actions/transient';
|
||||
// @ts-expect-error untyped local
|
||||
import { insertNodes } from '../../state/actions/elements';
|
||||
import { getSelectedPage } from '../../state/selectors/workpad';
|
||||
import { trackCanvasUiMetric, METRIC_TYPE } from '../../lib/ui_metric';
|
||||
import {
|
||||
SavedElementsModal as Component,
|
||||
Props as ComponentProps,
|
||||
} from './saved_elements_modal.component';
|
||||
import { PositionedElement, CustomElement } from '../../../types';
|
||||
|
||||
const customElementAdded = 'elements-custom-added';
|
||||
|
||||
export type Props = Pick<ComponentProps, 'onClose'>;
|
||||
|
||||
export const SavedElementsModal = ({ onClose }: Props) => {
|
||||
const notifyService = useNotifyService();
|
||||
const customElementService = useCustomElementService();
|
||||
const dispatch = useDispatch();
|
||||
const pageId = useSelector(getSelectedPage);
|
||||
const [customElements, setCustomElements] = useState<CustomElement[]>([]);
|
||||
|
||||
const onSearch = async (search = '') => {
|
||||
try {
|
||||
const { customElements: foundElements } = await customElementService.find(search);
|
||||
setCustomElements(foundElements);
|
||||
} catch (err) {
|
||||
notifyService.error(err, {
|
||||
title: `Couldn't find custom elements`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const onAddCustomElement = (customElement: CustomElement) => {
|
||||
const { selectedNodes = [] } = JSON.parse(customElement.content) || {};
|
||||
const clonedNodes = selectedNodes && cloneSubgraphs(selectedNodes);
|
||||
|
||||
if (clonedNodes) {
|
||||
dispatch(insertNodes(clonedNodes, pageId)); // first clone and persist the new node(s)
|
||||
dispatch(
|
||||
selectToplevelNodes(
|
||||
clonedNodes
|
||||
.filter((e: PositionedElement): boolean => !e.position.parent)
|
||||
.map((e: PositionedElement): string => e.id)
|
||||
)
|
||||
); // then select the cloned node(s)
|
||||
}
|
||||
|
||||
onClose();
|
||||
trackCanvasUiMetric(METRIC_TYPE.LOADED, customElementAdded);
|
||||
};
|
||||
|
||||
const onRemoveCustomElement = async (id: string) => {
|
||||
try {
|
||||
await customElementService.remove(id);
|
||||
await onSearch();
|
||||
} catch (err) {
|
||||
notifyService.error(err, {
|
||||
title: `Couldn't delete custom elements`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const onUpdateCustomElement = async (
|
||||
id: string,
|
||||
name: string,
|
||||
description: string,
|
||||
image: string
|
||||
) => {
|
||||
try {
|
||||
await customElementService.update(id, {
|
||||
name: camelCase(name),
|
||||
displayName: name,
|
||||
image,
|
||||
help: description,
|
||||
});
|
||||
await onSearch();
|
||||
} catch (err) {
|
||||
notifyService.error(err, {
|
||||
title: `Couldn't update custom elements`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Component
|
||||
{...{
|
||||
onAddCustomElement,
|
||||
onClose,
|
||||
onRemoveCustomElement,
|
||||
onSearch,
|
||||
onUpdateCustomElement,
|
||||
customElements,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { API_ROUTE_CUSTOM_ELEMENT } from '../../common/lib/constants';
|
||||
import { fetch } from '../../common/lib/fetch';
|
||||
import { CustomElement } from '../../types';
|
||||
import { pluginServices } from '../services';
|
||||
|
||||
const getApiPath = function () {
|
||||
const basePath = pluginServices.getServices().platform.getBasePath();
|
||||
return `${basePath}${API_ROUTE_CUSTOM_ELEMENT}`;
|
||||
};
|
||||
|
||||
export const create = (customElement: CustomElement): AxiosPromise =>
|
||||
fetch.post(getApiPath(), customElement);
|
||||
|
||||
export const get = (customElementId: string): Promise<CustomElement> =>
|
||||
fetch
|
||||
.get(`${getApiPath()}/${customElementId}`)
|
||||
.then(({ data: element }: { data: CustomElement }) => element);
|
||||
|
||||
export const update = (id: string, element: Partial<CustomElement>): AxiosPromise =>
|
||||
fetch.put(`${getApiPath()}/${id}`, element);
|
||||
|
||||
export const remove = (id: string): AxiosPromise => fetch.delete(`${getApiPath()}/${id}`);
|
||||
|
||||
export const find = async (
|
||||
searchTerm: string
|
||||
): Promise<{ total: number; customElements: CustomElement[] }> => {
|
||||
const validSearchTerm = typeof searchTerm === 'string' && searchTerm.length > 0;
|
||||
|
||||
return fetch
|
||||
.get(`${getApiPath()}/find?name=${validSearchTerm ? searchTerm : ''}&perPage=10000`)
|
||||
.then(
|
||||
({ data: customElements }: { data: { total: number; customElements: CustomElement[] } }) =>
|
||||
customElements
|
||||
);
|
||||
};
|
|
@ -9,7 +9,6 @@ import { camelCase } from 'lodash';
|
|||
import { getClipboardData, setClipboardData } from './clipboard';
|
||||
import { cloneSubgraphs } from './clone_subgraphs';
|
||||
import { pluginServices } from '../services';
|
||||
import * as customElementService from './custom_element_service';
|
||||
import { getId } from './get_id';
|
||||
import { PositionedElement } from '../../types';
|
||||
import { ELEMENT_NUDGE_OFFSET, ELEMENT_SHIFT_OFFSET } from '../../common/lib/constants';
|
||||
|
@ -71,6 +70,7 @@ export const basicHandlerCreators = {
|
|||
image = ''
|
||||
): void => {
|
||||
const notifyService = pluginServices.getServices().notify;
|
||||
const customElementService = pluginServices.getServices().customElement;
|
||||
|
||||
if (selectedNodes.length) {
|
||||
const content = JSON.stringify({ selectedNodes });
|
||||
|
|
21
x-pack/plugins/canvas/public/services/custom_element.ts
Normal file
21
x-pack/plugins/canvas/public/services/custom_element.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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>;
|
||||
}
|
|
@ -8,18 +8,20 @@
|
|||
export * from './legacy';
|
||||
|
||||
import { PluginServices } from '../../../../../src/plugins/presentation_util/public';
|
||||
import { CanvasExpressionsService } from './expressions';
|
||||
import { CanvasNavLinkService } from './nav_link';
|
||||
import { CanvasEmbeddablesService } from './embeddables';
|
||||
import { CanvasExpressionsService } from './expressions';
|
||||
import { CanvasCustomElementService } from './custom_element';
|
||||
import { CanvasNavLinkService } from './nav_link';
|
||||
import { CanvasNotifyService } from './notify';
|
||||
import { CanvasPlatformService } from './platform';
|
||||
import { CanvasReportingService } from './reporting';
|
||||
import { CanvasWorkpadService } from './workpad';
|
||||
|
||||
export interface CanvasPluginServices {
|
||||
customElement: CanvasCustomElementService;
|
||||
embeddables: CanvasEmbeddablesService;
|
||||
expressions: CanvasExpressionsService;
|
||||
navLink: CanvasNavLinkService;
|
||||
embeddables: CanvasEmbeddablesService;
|
||||
notify: CanvasNotifyService;
|
||||
platform: CanvasPlatformService;
|
||||
reporting: CanvasReportingService;
|
||||
|
@ -28,11 +30,13 @@ export interface CanvasPluginServices {
|
|||
|
||||
export const pluginServices = new PluginServices<CanvasPluginServices>();
|
||||
|
||||
export const useEmbeddablesService = () =>
|
||||
(() => pluginServices.getHooks().embeddables.useService())();
|
||||
export const useCustomElementService = () =>
|
||||
(() => pluginServices.getHooks().customElement.useService())();
|
||||
export const useExpressionsService = () =>
|
||||
(() => pluginServices.getHooks().expressions.useService())();
|
||||
export const useNavLinkService = () => (() => pluginServices.getHooks().navLink.useService())();
|
||||
export const useEmbeddablesService = () =>
|
||||
(() => pluginServices.getHooks().embeddables.useService())();
|
||||
export const useNotifyService = () => (() => pluginServices.getHooks().notify.useService())();
|
||||
export const usePlatformService = () => (() => pluginServices.getHooks().platform.useService())();
|
||||
export const useReportingService = () => (() => pluginServices.getHooks().reporting.useService())();
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 '../../../../../../src/plugins/presentation_util/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) }),
|
||||
get: (customElementId) =>
|
||||
http
|
||||
.get(`${apiPath}/${customElementId}`)
|
||||
.then(({ data: element }: { data: CustomElement }) => element),
|
||||
update: (id, element) => http.put(`${apiPath}/${id}`, { body: JSON.stringify(element) }),
|
||||
remove: (id) => http.delete(`${apiPath}/${id}`),
|
||||
find: async (name) => {
|
||||
return http.get(`${apiPath}/find`, {
|
||||
query: {
|
||||
name,
|
||||
perPage: 10000,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
|
@ -14,6 +14,7 @@ import {
|
|||
|
||||
import { CanvasPluginServices } from '..';
|
||||
import { CanvasStartDeps } from '../../plugin';
|
||||
import { customElementServiceFactory } from './custom_element';
|
||||
import { embeddablesServiceFactory } from './embeddables';
|
||||
import { expressionsServiceFactory } from './expressions';
|
||||
import { navLinkServiceFactory } from './nav_link';
|
||||
|
@ -22,8 +23,9 @@ import { platformServiceFactory } from './platform';
|
|||
import { reportingServiceFactory } from './reporting';
|
||||
import { workpadServiceFactory } from './workpad';
|
||||
|
||||
export { expressionsServiceFactory } from './expressions';
|
||||
export { customElementServiceFactory } from './custom_element';
|
||||
export { embeddablesServiceFactory } from './embeddables';
|
||||
export { expressionsServiceFactory } from './expressions';
|
||||
export { notifyServiceFactory } from './notify';
|
||||
export { platformServiceFactory } from './platform';
|
||||
export { reportingServiceFactory } from './reporting';
|
||||
|
@ -33,9 +35,10 @@ export const pluginServiceProviders: PluginServiceProviders<
|
|||
CanvasPluginServices,
|
||||
KibanaPluginServiceParams<CanvasStartDeps>
|
||||
> = {
|
||||
customElement: new PluginServiceProvider(customElementServiceFactory),
|
||||
embeddables: new PluginServiceProvider(embeddablesServiceFactory),
|
||||
expressions: new PluginServiceProvider(expressionsServiceFactory),
|
||||
navLink: new PluginServiceProvider(navLinkServiceFactory),
|
||||
embeddables: new PluginServiceProvider(embeddablesServiceFactory),
|
||||
notify: new PluginServiceProvider(notifyServiceFactory),
|
||||
platform: new PluginServiceProvider(platformServiceFactory),
|
||||
reporting: new PluginServiceProvider(reportingServiceFactory),
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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 '../../../../../../src/plugins/presentation_util/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,
|
||||
});
|
|
@ -14,6 +14,7 @@ import {
|
|||
} from '../../../../../../src/plugins/presentation_util/public';
|
||||
|
||||
import { CanvasPluginServices } from '..';
|
||||
import { customElementServiceFactory } from './custom_element';
|
||||
import { embeddablesServiceFactory } from './embeddables';
|
||||
import { expressionsServiceFactory } from './expressions';
|
||||
import { navLinkServiceFactory } from './nav_link';
|
||||
|
@ -22,6 +23,7 @@ import { platformServiceFactory } from './platform';
|
|||
import { reportingServiceFactory } from './reporting';
|
||||
import { workpadServiceFactory } from './workpad';
|
||||
|
||||
export { customElementServiceFactory } from './custom_element';
|
||||
export { expressionsServiceFactory } from './expressions';
|
||||
export { navLinkServiceFactory } from './nav_link';
|
||||
export { notifyServiceFactory } from './notify';
|
||||
|
@ -30,6 +32,7 @@ export { reportingServiceFactory } from './reporting';
|
|||
export { workpadServiceFactory } from './workpad';
|
||||
|
||||
export const pluginServiceProviders: PluginServiceProviders<CanvasPluginServices> = {
|
||||
customElement: new PluginServiceProvider(customElementServiceFactory),
|
||||
embeddables: new PluginServiceProvider(embeddablesServiceFactory),
|
||||
expressions: new PluginServiceProvider(expressionsServiceFactory),
|
||||
navLink: new PluginServiceProvider(navLinkServiceFactory),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue