mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Embeddable API cleanup (#60207)
* wip * Remove test in legacy functional plugin
This commit is contained in:
parent
6cbfa274cf
commit
dccfa593dc
92 changed files with 451 additions and 647 deletions
|
@ -33,7 +33,7 @@ export class HelloWorldEmbeddableFactory extends EmbeddableFactory {
|
|||
* embeddables should check the UI Capabilities service to be sure of
|
||||
* the right permissions.
|
||||
*/
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import ReactDOM from 'react-dom';
|
|||
import {
|
||||
Container,
|
||||
ContainerInput,
|
||||
GetEmbeddableFactory,
|
||||
EmbeddableStart,
|
||||
} from '../../../../src/plugins/embeddable/public';
|
||||
import { ListContainerComponent } from './list_container_component';
|
||||
|
||||
|
@ -31,7 +31,10 @@ export class ListContainer extends Container<{}, ContainerInput> {
|
|||
public readonly type = LIST_CONTAINER;
|
||||
private node?: HTMLElement;
|
||||
|
||||
constructor(input: ContainerInput, getEmbeddableFactory: GetEmbeddableFactory) {
|
||||
constructor(
|
||||
input: ContainerInput,
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']
|
||||
) {
|
||||
super(input, { embeddableLoaded: {} }, getEmbeddableFactory);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,25 +20,30 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EmbeddableFactory,
|
||||
GetEmbeddableFactory,
|
||||
ContainerInput,
|
||||
EmbeddableStart,
|
||||
} from '../../../../src/plugins/embeddable/public';
|
||||
import { LIST_CONTAINER, ListContainer } from './list_container';
|
||||
|
||||
interface StartServices {
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
}
|
||||
|
||||
export class ListContainerFactory extends EmbeddableFactory {
|
||||
public readonly type = LIST_CONTAINER;
|
||||
public readonly isContainerType = true;
|
||||
|
||||
constructor(private getEmbeddableFactory: GetEmbeddableFactory) {
|
||||
constructor(private getStartServices: () => Promise<StartServices>) {
|
||||
super();
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public async create(initialInput: ContainerInput) {
|
||||
return new ListContainer(initialInput, this.getEmbeddableFactory);
|
||||
const { getEmbeddableFactory } = await this.getStartServices();
|
||||
return new ListContainer(initialInput, getEmbeddableFactory);
|
||||
}
|
||||
|
||||
public getDisplayName() {
|
||||
|
|
|
@ -32,7 +32,7 @@ export class MultiTaskTodoEmbeddableFactory extends EmbeddableFactory<
|
|||
> {
|
||||
public readonly type = MULTI_TASK_TODO_EMBEDDABLE;
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,20 +17,11 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
IEmbeddableSetup,
|
||||
IEmbeddableStart,
|
||||
EmbeddableFactory,
|
||||
} from '../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableSetup, EmbeddableStart } from '../../../src/plugins/embeddable/public';
|
||||
import { Plugin, CoreSetup, CoreStart } from '../../../src/core/public';
|
||||
import { HelloWorldEmbeddableFactory, HELLO_WORLD_EMBEDDABLE } from './hello_world';
|
||||
import { TODO_EMBEDDABLE, TodoEmbeddableFactory, TodoInput, TodoOutput } from './todo';
|
||||
import {
|
||||
MULTI_TASK_TODO_EMBEDDABLE,
|
||||
MultiTaskTodoEmbeddableFactory,
|
||||
MultiTaskTodoOutput,
|
||||
MultiTaskTodoInput,
|
||||
} from './multi_task_todo';
|
||||
import { MULTI_TASK_TODO_EMBEDDABLE, MultiTaskTodoEmbeddableFactory } from './multi_task_todo';
|
||||
import {
|
||||
SEARCHABLE_LIST_CONTAINER,
|
||||
SearchableListContainerFactory,
|
||||
|
@ -38,46 +29,56 @@ import {
|
|||
import { LIST_CONTAINER, ListContainerFactory } from './list_container';
|
||||
|
||||
interface EmbeddableExamplesSetupDependencies {
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
}
|
||||
|
||||
interface EmbeddableExamplesStartDependencies {
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
}
|
||||
|
||||
export class EmbeddableExamplesPlugin
|
||||
implements
|
||||
Plugin<void, void, EmbeddableExamplesSetupDependencies, EmbeddableExamplesStartDependencies> {
|
||||
public setup(core: CoreSetup, deps: EmbeddableExamplesSetupDependencies) {
|
||||
public setup(
|
||||
core: CoreSetup<EmbeddableExamplesStartDependencies>,
|
||||
deps: EmbeddableExamplesSetupDependencies
|
||||
) {
|
||||
deps.embeddable.registerEmbeddableFactory(
|
||||
HELLO_WORLD_EMBEDDABLE,
|
||||
new HelloWorldEmbeddableFactory()
|
||||
);
|
||||
|
||||
deps.embeddable.registerEmbeddableFactory<
|
||||
EmbeddableFactory<MultiTaskTodoInput, MultiTaskTodoOutput>
|
||||
>(MULTI_TASK_TODO_EMBEDDABLE, new MultiTaskTodoEmbeddableFactory());
|
||||
}
|
||||
deps.embeddable.registerEmbeddableFactory(
|
||||
MULTI_TASK_TODO_EMBEDDABLE,
|
||||
new MultiTaskTodoEmbeddableFactory()
|
||||
);
|
||||
|
||||
public start(core: CoreStart, deps: EmbeddableExamplesStartDependencies) {
|
||||
// These are registered in the start method because `getEmbeddableFactory `
|
||||
// is only available in start. We could reconsider this I think and make it
|
||||
// available in both.
|
||||
deps.embeddable.registerEmbeddableFactory(
|
||||
SEARCHABLE_LIST_CONTAINER,
|
||||
new SearchableListContainerFactory(deps.embeddable.getEmbeddableFactory)
|
||||
new SearchableListContainerFactory(async () => ({
|
||||
getEmbeddableFactory: (await core.getStartServices())[1].embeddable.getEmbeddableFactory,
|
||||
}))
|
||||
);
|
||||
|
||||
deps.embeddable.registerEmbeddableFactory(
|
||||
LIST_CONTAINER,
|
||||
new ListContainerFactory(deps.embeddable.getEmbeddableFactory)
|
||||
new ListContainerFactory(async () => ({
|
||||
getEmbeddableFactory: (await core.getStartServices())[1].embeddable.getEmbeddableFactory,
|
||||
}))
|
||||
);
|
||||
|
||||
deps.embeddable.registerEmbeddableFactory<EmbeddableFactory<TodoInput, TodoOutput>>(
|
||||
deps.embeddable.registerEmbeddableFactory<TodoInput, TodoOutput>(
|
||||
TODO_EMBEDDABLE,
|
||||
new TodoEmbeddableFactory(core.overlays.openModal)
|
||||
new TodoEmbeddableFactory(async () => ({
|
||||
openModal: (await core.getStartServices())[0].overlays.openModal,
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
public start(core: CoreStart, deps: EmbeddableExamplesStartDependencies) {}
|
||||
|
||||
public stop() {}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import ReactDOM from 'react-dom';
|
|||
import {
|
||||
Container,
|
||||
ContainerInput,
|
||||
GetEmbeddableFactory,
|
||||
EmbeddableStart,
|
||||
EmbeddableInput,
|
||||
} from '../../../../src/plugins/embeddable/public';
|
||||
import { SearchableListContainerComponent } from './searchable_list_container_component';
|
||||
|
@ -40,7 +40,10 @@ export class SearchableListContainer extends Container<ChildInput, SearchableCon
|
|||
public readonly type = SEARCHABLE_LIST_CONTAINER;
|
||||
private node?: HTMLElement;
|
||||
|
||||
constructor(input: SearchableContainerInput, getEmbeddableFactory: GetEmbeddableFactory) {
|
||||
constructor(
|
||||
input: SearchableContainerInput,
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']
|
||||
) {
|
||||
super(input, { embeddableLoaded: {} }, getEmbeddableFactory);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,27 +18,32 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EmbeddableFactory, GetEmbeddableFactory } from '../../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableFactory, EmbeddableStart } from '../../../../src/plugins/embeddable/public';
|
||||
import {
|
||||
SEARCHABLE_LIST_CONTAINER,
|
||||
SearchableListContainer,
|
||||
SearchableContainerInput,
|
||||
} from './searchable_list_container';
|
||||
|
||||
interface StartServices {
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
}
|
||||
|
||||
export class SearchableListContainerFactory extends EmbeddableFactory {
|
||||
public readonly type = SEARCHABLE_LIST_CONTAINER;
|
||||
public readonly isContainerType = true;
|
||||
|
||||
constructor(private getEmbeddableFactory: GetEmbeddableFactory) {
|
||||
constructor(private getStartServices: () => Promise<StartServices>) {
|
||||
super();
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public async create(initialInput: SearchableContainerInput) {
|
||||
return new SearchableListContainer(initialInput, this.getEmbeddableFactory);
|
||||
const { getEmbeddableFactory } = await this.getStartServices();
|
||||
return new SearchableListContainer(initialInput, getEmbeddableFactory);
|
||||
}
|
||||
|
||||
public getDisplayName() {
|
||||
|
|
|
@ -43,6 +43,10 @@ function TaskInput({ onSave }: { onSave: (task: string) => void }) {
|
|||
);
|
||||
}
|
||||
|
||||
interface StartServices {
|
||||
openModal: OverlayStart['openModal'];
|
||||
}
|
||||
|
||||
export class TodoEmbeddableFactory extends EmbeddableFactory<
|
||||
TodoInput,
|
||||
TodoOutput,
|
||||
|
@ -50,11 +54,11 @@ export class TodoEmbeddableFactory extends EmbeddableFactory<
|
|||
> {
|
||||
public readonly type = TODO_EMBEDDABLE;
|
||||
|
||||
constructor(private openModal: OverlayStart['openModal']) {
|
||||
constructor(private getStartServices: () => Promise<StartServices>) {
|
||||
super();
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -69,9 +73,10 @@ export class TodoEmbeddableFactory extends EmbeddableFactory<
|
|||
* in this case, the task string.
|
||||
*/
|
||||
public async getExplicitInput() {
|
||||
const { openModal } = await this.getStartServices();
|
||||
return new Promise<{ task: string }>(resolve => {
|
||||
const onSave = (task: string) => resolve({ task });
|
||||
const overlay = this.openModal(
|
||||
const overlay = openModal(
|
||||
toMountPoint(
|
||||
<TaskInput
|
||||
onSave={(task: string) => {
|
||||
|
|
|
@ -23,7 +23,7 @@ import { BrowserRouter as Router, Route, withRouter, RouteComponentProps } from
|
|||
|
||||
import { EuiPage, EuiPageSideBar, EuiSideNav } from '@elastic/eui';
|
||||
|
||||
import { IEmbeddableStart } from '../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableStart } from '../../../src/plugins/embeddable/public';
|
||||
import { UiActionsStart } from '../../../src/plugins/ui_actions/public';
|
||||
import { Start as InspectorStartContract } from '../../../src/plugins/inspector/public';
|
||||
import {
|
||||
|
@ -74,7 +74,7 @@ const Nav = withRouter(({ history, navigateToApp, pages }: NavProps) => {
|
|||
interface Props {
|
||||
basename: string;
|
||||
navigateToApp: CoreStart['application']['navigateToApp'];
|
||||
embeddableApi: IEmbeddableStart;
|
||||
embeddableApi: EmbeddableStart;
|
||||
uiActionsApi: UiActionsStart;
|
||||
overlays: OverlayStart;
|
||||
notifications: CoreStart['notifications'];
|
||||
|
|
|
@ -31,9 +31,8 @@ import {
|
|||
import { EuiSpacer } from '@elastic/eui';
|
||||
import { OverlayStart, CoreStart, SavedObjectsStart, IUiSettingsClient } from 'kibana/public';
|
||||
import {
|
||||
GetEmbeddableFactory,
|
||||
EmbeddablePanel,
|
||||
IEmbeddableStart,
|
||||
EmbeddableStart,
|
||||
IEmbeddable,
|
||||
} from '../../../src/plugins/embeddable/public';
|
||||
import {
|
||||
|
@ -47,8 +46,8 @@ import { Start as InspectorStartContract } from '../../../src/plugins/inspector/
|
|||
import { getSavedObjectFinder } from '../../../src/plugins/saved_objects/public';
|
||||
|
||||
interface Props {
|
||||
getAllEmbeddableFactories: IEmbeddableStart['getEmbeddableFactories'];
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
uiActionsApi: UiActionsStart;
|
||||
overlays: OverlayStart;
|
||||
notifications: CoreStart['notifications'];
|
||||
|
|
|
@ -29,14 +29,14 @@ import {
|
|||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import {
|
||||
GetEmbeddableFactory,
|
||||
EmbeddableStart,
|
||||
EmbeddableFactoryRenderer,
|
||||
EmbeddableRoot,
|
||||
} from '../../../src/plugins/embeddable/public';
|
||||
import { HelloWorldEmbeddable, HELLO_WORLD_EMBEDDABLE } from '../../embeddable_examples/public';
|
||||
|
||||
interface Props {
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
}
|
||||
|
||||
export function HelloWorldEmbeddableExample({ getEmbeddableFactory }: Props) {
|
||||
|
|
|
@ -29,10 +29,7 @@ import {
|
|||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
import {
|
||||
GetEmbeddableFactory,
|
||||
EmbeddableFactoryRenderer,
|
||||
} from '../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableFactoryRenderer, EmbeddableStart } from '../../../src/plugins/embeddable/public';
|
||||
import {
|
||||
HELLO_WORLD_EMBEDDABLE,
|
||||
TODO_EMBEDDABLE,
|
||||
|
@ -42,7 +39,7 @@ import {
|
|||
} from '../../embeddable_examples/public';
|
||||
|
||||
interface Props {
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
}
|
||||
|
||||
export function ListContainerExample({ getEmbeddableFactory }: Props) {
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
|
||||
import { Plugin, CoreSetup, AppMountParameters } from 'kibana/public';
|
||||
import { UiActionsService } from '../../../src/plugins/ui_actions/public';
|
||||
import { IEmbeddableStart } from '../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableStart } from '../../../src/plugins/embeddable/public';
|
||||
import { Start as InspectorStart } from '../../../src/plugins/inspector/public';
|
||||
|
||||
interface StartDeps {
|
||||
uiActions: UiActionsService;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
inspector: InspectorStart;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,10 @@ import {
|
|||
TODO_EMBEDDABLE,
|
||||
TodoEmbeddableFactory,
|
||||
} from '../../../examples/embeddable_examples/public/todo';
|
||||
import { GetEmbeddableFactory, EmbeddableRoot } from '../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableStart, EmbeddableRoot } from '../../../src/plugins/embeddable/public';
|
||||
|
||||
interface Props {
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
|
|
@ -39,7 +39,7 @@ import {
|
|||
} from '../legacy_imports';
|
||||
// @ts-ignore
|
||||
import { initDashboardApp } from './legacy_app';
|
||||
import { IEmbeddableStart } from '../../../../../../plugins/embeddable/public';
|
||||
import { EmbeddableStart } from '../../../../../../plugins/embeddable/public';
|
||||
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../../plugins/navigation/public';
|
||||
import { DataPublicPluginStart } from '../../../../../../plugins/data/public';
|
||||
import { SharePluginStart } from '../../../../../../plugins/share/public';
|
||||
|
@ -67,7 +67,7 @@ export interface RenderDeps {
|
|||
chrome: ChromeStart;
|
||||
addBasePath: (path: string) => string;
|
||||
savedQueryService: DataPublicPluginStart['query']['savedQueries'];
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
localStorage: Storage;
|
||||
share: SharePluginStart;
|
||||
config: KibanaLegacyStart['config'];
|
||||
|
|
|
@ -35,7 +35,7 @@ import {
|
|||
DataPublicPluginSetup,
|
||||
esFilters,
|
||||
} from '../../../../../plugins/data/public';
|
||||
import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
|
||||
import { EmbeddableStart } from '../../../../../plugins/embeddable/public';
|
||||
import { Storage } from '../../../../../plugins/kibana_utils/public';
|
||||
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
|
||||
import { DashboardConstants } from './np_ready/dashboard_constants';
|
||||
|
@ -54,7 +54,7 @@ import { createKbnUrlTracker } from '../../../../../plugins/kibana_utils/public'
|
|||
|
||||
export interface DashboardPluginStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
navigation: NavigationStart;
|
||||
share: SharePluginStart;
|
||||
kibanaLegacy: KibanaLegacyStart;
|
||||
|
@ -70,7 +70,7 @@ export class DashboardPlugin implements Plugin {
|
|||
private startDependencies: {
|
||||
data: DataPublicPluginStart;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
navigation: NavigationStart;
|
||||
share: SharePluginStart;
|
||||
dashboardConfig: KibanaLegacyStart['dashboardConfig'];
|
||||
|
|
|
@ -32,6 +32,11 @@ import { SearchEmbeddable } from './search_embeddable';
|
|||
import { SearchInput, SearchOutput } from './types';
|
||||
import { SEARCH_EMBEDDABLE_TYPE } from './constants';
|
||||
|
||||
interface StartServices {
|
||||
executeTriggerActions: UiActionsStart['executeTriggerActions'];
|
||||
isEditable: () => boolean;
|
||||
}
|
||||
|
||||
export class SearchEmbeddableFactory extends EmbeddableFactory<
|
||||
SearchInput,
|
||||
SearchOutput,
|
||||
|
@ -40,12 +45,10 @@ export class SearchEmbeddableFactory extends EmbeddableFactory<
|
|||
public readonly type = SEARCH_EMBEDDABLE_TYPE;
|
||||
private $injector: auto.IInjectorService | null;
|
||||
private getInjector: () => Promise<auto.IInjectorService> | null;
|
||||
public isEditable: () => boolean;
|
||||
|
||||
constructor(
|
||||
private readonly executeTriggerActions: UiActionsStart['executeTriggerActions'],
|
||||
getInjector: () => Promise<auto.IInjectorService>,
|
||||
isEditable: () => boolean
|
||||
private getStartServices: () => Promise<StartServices>,
|
||||
getInjector: () => Promise<auto.IInjectorService>
|
||||
) {
|
||||
super({
|
||||
savedObjectMetaData: {
|
||||
|
@ -58,13 +61,16 @@ export class SearchEmbeddableFactory extends EmbeddableFactory<
|
|||
});
|
||||
this.$injector = null;
|
||||
this.getInjector = getInjector;
|
||||
this.isEditable = isEditable;
|
||||
}
|
||||
|
||||
public canCreateNew() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public async isEditable() {
|
||||
return (await this.getStartServices()).isEditable();
|
||||
}
|
||||
|
||||
public getDisplayName() {
|
||||
return i18n.translate('kbn.embeddable.search.displayName', {
|
||||
defaultMessage: 'search',
|
||||
|
@ -90,6 +96,7 @@ export class SearchEmbeddableFactory extends EmbeddableFactory<
|
|||
try {
|
||||
const savedObject = await getServices().getSavedSearchById(savedObjectId);
|
||||
const indexPattern = savedObject.searchSource.getField('index');
|
||||
const { executeTriggerActions } = await this.getStartServices();
|
||||
return new SearchEmbeddable(
|
||||
{
|
||||
savedSearch: savedObject,
|
||||
|
@ -101,7 +108,7 @@ export class SearchEmbeddableFactory extends EmbeddableFactory<
|
|||
indexPatterns: indexPattern ? [indexPattern] : [],
|
||||
},
|
||||
input,
|
||||
this.executeTriggerActions,
|
||||
executeTriggerActions,
|
||||
parent
|
||||
);
|
||||
} catch (e) {
|
||||
|
|
|
@ -30,7 +30,7 @@ import {
|
|||
} from '../../../../../plugins/data/public';
|
||||
import { registerFeature } from './np_ready/register_feature';
|
||||
import './kibana_services';
|
||||
import { IEmbeddableStart, IEmbeddableSetup } from '../../../../../plugins/embeddable/public';
|
||||
import { EmbeddableStart, EmbeddableSetup } from '../../../../../plugins/embeddable/public';
|
||||
import { getInnerAngularModule, getInnerAngularModuleEmbeddable } from './get_inner_angular';
|
||||
import { setAngularModule, setServices } from './kibana_services';
|
||||
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
|
||||
|
@ -63,7 +63,7 @@ export interface DiscoverSetup {
|
|||
export type DiscoverStart = void;
|
||||
export interface DiscoverSetupPlugins {
|
||||
uiActions: UiActionsSetup;
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
kibanaLegacy: KibanaLegacySetup;
|
||||
home: HomePublicPluginSetup;
|
||||
visualizations: VisualizationsSetup;
|
||||
|
@ -71,7 +71,7 @@ export interface DiscoverSetupPlugins {
|
|||
}
|
||||
export interface DiscoverStartPlugins {
|
||||
uiActions: UiActionsStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
navigation: NavigationStart;
|
||||
charts: ChartsPluginStart;
|
||||
data: DataPublicPluginStart;
|
||||
|
@ -103,7 +103,7 @@ export class DiscoverPlugin implements Plugin<DiscoverSetup, DiscoverStart> {
|
|||
public initializeInnerAngular?: () => void;
|
||||
public initializeServices?: () => Promise<{ core: CoreStart; plugins: DiscoverStartPlugins }>;
|
||||
|
||||
setup(core: CoreSetup, plugins: DiscoverSetupPlugins): DiscoverSetup {
|
||||
setup(core: CoreSetup<DiscoverStartPlugins>, plugins: DiscoverSetupPlugins): DiscoverSetup {
|
||||
const { appMounted, appUnMounted, stop: stopUrlTracker } = createKbnUrlTracker({
|
||||
baseUrl: core.http.basePath.prepend('/app/kibana'),
|
||||
defaultSubUrl: '#/discover',
|
||||
|
@ -173,6 +173,7 @@ export class DiscoverPlugin implements Plugin<DiscoverSetup, DiscoverStart> {
|
|||
});
|
||||
registerFeature(plugins.home);
|
||||
|
||||
this.registerEmbeddable(core, plugins);
|
||||
return {
|
||||
addDocView: this.docViewsRegistry.addDocView.bind(this.docViewsRegistry),
|
||||
};
|
||||
|
@ -203,8 +204,6 @@ export class DiscoverPlugin implements Plugin<DiscoverSetup, DiscoverStart> {
|
|||
|
||||
return { core, plugins };
|
||||
};
|
||||
|
||||
this.registerEmbeddable(core, plugins);
|
||||
}
|
||||
|
||||
stop() {
|
||||
|
@ -216,19 +215,25 @@ export class DiscoverPlugin implements Plugin<DiscoverSetup, DiscoverStart> {
|
|||
/**
|
||||
* register embeddable with a slimmer embeddable version of inner angular
|
||||
*/
|
||||
private async registerEmbeddable(core: CoreStart, plugins: DiscoverStartPlugins) {
|
||||
private async registerEmbeddable(
|
||||
core: CoreSetup<DiscoverStartPlugins>,
|
||||
plugins: DiscoverSetupPlugins
|
||||
) {
|
||||
const { SearchEmbeddableFactory } = await import('./np_ready/embeddable');
|
||||
const isEditable = () => core.application.capabilities.discover.save as boolean;
|
||||
|
||||
if (!this.getEmbeddableInjector) {
|
||||
throw Error('Discover plugin method getEmbeddableInjector is undefined');
|
||||
}
|
||||
|
||||
const factory = new SearchEmbeddableFactory(
|
||||
plugins.uiActions.executeTriggerActions,
|
||||
this.getEmbeddableInjector,
|
||||
isEditable
|
||||
);
|
||||
const getStartServices = async () => {
|
||||
const [coreStart, deps] = await core.getStartServices();
|
||||
return {
|
||||
executeTriggerActions: deps.uiActions.executeTriggerActions,
|
||||
isEditable: () => coreStart.application.capabilities.discover.save as boolean,
|
||||
};
|
||||
};
|
||||
|
||||
const factory = new SearchEmbeddableFactory(getStartServices, this.getEmbeddableInjector);
|
||||
plugins.embeddable.registerEmbeddableFactory(factory.type, factory);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import {
|
|||
|
||||
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
|
||||
import { Storage } from '../../../../../plugins/kibana_utils/public';
|
||||
import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
|
||||
import { EmbeddableStart } from '../../../../../plugins/embeddable/public';
|
||||
import { SharePluginStart } from '../../../../../plugins/share/public';
|
||||
import { DataPublicPluginStart, IndexPatternsContract } from '../../../../../plugins/data/public';
|
||||
import { VisualizationsStart } from '../../../visualizations/public';
|
||||
|
@ -44,7 +44,7 @@ export interface VisualizeKibanaServices {
|
|||
chrome: ChromeStart;
|
||||
core: CoreStart;
|
||||
data: DataPublicPluginStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
getBasePath: () => string;
|
||||
indexPatterns: IndexPatternsContract;
|
||||
localStorage: Storage;
|
||||
|
|
|
@ -24,7 +24,7 @@ import {
|
|||
DataPublicPluginStart,
|
||||
SavedQuery,
|
||||
} from 'src/plugins/data/public';
|
||||
import { IEmbeddableStart } from 'src/plugins/embeddable/public';
|
||||
import { EmbeddableStart } from 'src/plugins/embeddable/public';
|
||||
import { PersistedState } from 'src/plugins/visualizations/public';
|
||||
import { LegacyCoreStart } from 'kibana/public';
|
||||
import { Vis } from 'src/legacy/core_plugins/visualizations/public';
|
||||
|
@ -61,7 +61,7 @@ export interface EditorRenderProps {
|
|||
appState: { save(): void };
|
||||
core: LegacyCoreStart;
|
||||
data: DataPublicPluginStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
filters: Filter[];
|
||||
uiState: PersistedState;
|
||||
timeRange: TimeRange;
|
||||
|
|
|
@ -36,7 +36,7 @@ import {
|
|||
DataPublicPluginSetup,
|
||||
esFilters,
|
||||
} from '../../../../../plugins/data/public';
|
||||
import { IEmbeddableStart } from '../../../../../plugins/embeddable/public';
|
||||
import { EmbeddableStart } from '../../../../../plugins/embeddable/public';
|
||||
import { NavigationPublicPluginStart as NavigationStart } from '../../../../../plugins/navigation/public';
|
||||
import { SharePluginStart } from '../../../../../plugins/share/public';
|
||||
import {
|
||||
|
@ -55,7 +55,7 @@ import { DefaultEditorController } from '../../../vis_default_editor/public';
|
|||
|
||||
export interface VisualizePluginStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
navigation: NavigationStart;
|
||||
share: SharePluginStart;
|
||||
visualizations: VisualizationsStart;
|
||||
|
@ -71,7 +71,7 @@ export interface VisualizePluginSetupDependencies {
|
|||
export class VisualizePlugin implements Plugin {
|
||||
private startDependencies: {
|
||||
data: DataPublicPluginStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
navigation: NavigationStart;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
share: SharePluginStart;
|
||||
|
|
|
@ -83,7 +83,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
|
|||
});
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return getCapabilities().visualize.save as boolean;
|
||||
}
|
||||
|
||||
|
@ -114,13 +114,14 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory<
|
|||
|
||||
const indexPattern = await getIndexPattern(savedObject);
|
||||
const indexPatterns = indexPattern ? [indexPattern] : [];
|
||||
const editable = await this.isEditable();
|
||||
return new VisualizeEmbeddable(
|
||||
getTimeFilter(),
|
||||
{
|
||||
savedVisualization: savedObject,
|
||||
indexPatterns,
|
||||
editUrl,
|
||||
editable: this.isEditable(),
|
||||
editable,
|
||||
appState: input.appState,
|
||||
uiState: input.uiState,
|
||||
},
|
||||
|
|
|
@ -49,7 +49,7 @@ const createInstance = async () => {
|
|||
const setup = plugin.setup(coreMock.createSetup(), {
|
||||
data: dataPluginMock.createSetupContract(),
|
||||
expressions: expressionsPluginMock.createSetupContract(),
|
||||
embeddable: embeddablePluginMock.createStartContract(),
|
||||
embeddable: embeddablePluginMock.createSetupContract(),
|
||||
usageCollection: usageCollectionPluginMock.createSetupContract(),
|
||||
});
|
||||
const doStart = () =>
|
||||
|
|
|
@ -42,7 +42,7 @@ import {
|
|||
} from './services';
|
||||
import { VISUALIZE_EMBEDDABLE_TYPE, VisualizeEmbeddableFactory } from './embeddable';
|
||||
import { ExpressionsSetup, ExpressionsStart } from '../../../../../../plugins/expressions/public';
|
||||
import { IEmbeddableSetup } from '../../../../../../plugins/embeddable/public';
|
||||
import { EmbeddableSetup } from '../../../../../../plugins/embeddable/public';
|
||||
import { visualization as visualizationFunction } from './expressions/visualization_function';
|
||||
import { visualization as visualizationRenderer } from './expressions/visualization_renderer';
|
||||
import {
|
||||
|
@ -73,7 +73,7 @@ export interface VisualizationsStart extends TypesStart {
|
|||
|
||||
export interface VisualizationsSetupDeps {
|
||||
expressions: ExpressionsSetup;
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
usageCollection: UsageCollectionSetup;
|
||||
data: DataPublicPluginSetup;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { IScope } from 'angular';
|
||||
|
||||
import { UiActionsStart, UiActionsSetup } from 'src/plugins/ui_actions/public';
|
||||
import { IEmbeddableStart, IEmbeddableSetup } from 'src/plugins/embeddable/public';
|
||||
import { EmbeddableStart, EmbeddableSetup } from 'src/plugins/embeddable/public';
|
||||
import { createBrowserHistory } from 'history';
|
||||
import {
|
||||
LegacyCoreSetup,
|
||||
|
@ -68,7 +68,7 @@ export interface PluginsSetup {
|
|||
bfetch: BfetchPublicSetup;
|
||||
charts: ChartsPluginSetup;
|
||||
data: ReturnType<DataPlugin['setup']>;
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
expressions: ReturnType<ExpressionsPlugin['setup']>;
|
||||
home: HomePublicPluginSetup;
|
||||
inspector: InspectorSetup;
|
||||
|
@ -88,7 +88,7 @@ export interface PluginsStart {
|
|||
bfetch: BfetchPublicStart;
|
||||
charts: ChartsPluginStart;
|
||||
data: ReturnType<DataPlugin['start']>;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
expressions: ReturnType<ExpressionsPlugin['start']>;
|
||||
inspector: InspectorStart;
|
||||
uiActions: UiActionsStart;
|
||||
|
|
|
@ -28,7 +28,6 @@ import {
|
|||
ContactCardEmbeddableInput,
|
||||
ContactCardEmbeddableOutput,
|
||||
} from '../embeddable_plugin_test_samples';
|
||||
import { DashboardOptions } from '../embeddable/dashboard_container_factory';
|
||||
|
||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||
embeddableFactories.set(
|
||||
|
@ -40,7 +39,7 @@ let container: DashboardContainer;
|
|||
let embeddable: ContactCardEmbeddable;
|
||||
|
||||
beforeEach(async () => {
|
||||
const options: DashboardOptions = {
|
||||
const options = {
|
||||
ExitFullScreenButton: () => null,
|
||||
SavedObjectFinder: () => null,
|
||||
application: {} as any,
|
||||
|
|
|
@ -24,7 +24,7 @@ import {
|
|||
IEmbeddable,
|
||||
EmbeddableInput,
|
||||
EmbeddableOutput,
|
||||
IEmbeddableStart,
|
||||
EmbeddableStart,
|
||||
IContainer,
|
||||
} from '../embeddable_plugin';
|
||||
|
||||
|
@ -34,7 +34,7 @@ export async function openReplacePanelFlyout(options: {
|
|||
savedObjectFinder: React.ComponentType<any>;
|
||||
notifications: CoreStart['notifications'];
|
||||
panelToRemove: IEmbeddable<EmbeddableInput, EmbeddableOutput>;
|
||||
getEmbeddableFactories: IEmbeddableStart['getEmbeddableFactories'];
|
||||
getEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
}) {
|
||||
const {
|
||||
embeddable,
|
||||
|
|
|
@ -27,7 +27,6 @@ import {
|
|||
ContactCardEmbeddableInput,
|
||||
ContactCardEmbeddableOutput,
|
||||
} from '../embeddable_plugin_test_samples';
|
||||
import { DashboardOptions } from '../embeddable/dashboard_container_factory';
|
||||
import { coreMock } from '../../../../core/public/mocks';
|
||||
import { CoreStart } from 'kibana/public';
|
||||
|
||||
|
@ -43,7 +42,7 @@ let embeddable: ContactCardEmbeddable;
|
|||
let coreStart: CoreStart;
|
||||
beforeEach(async () => {
|
||||
coreStart = coreMock.createStart();
|
||||
const options: DashboardOptions = {
|
||||
const options = {
|
||||
ExitFullScreenButton: () => null,
|
||||
SavedObjectFinder: () => null,
|
||||
application: {} as any,
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreStart } from '../../../../core/public';
|
||||
import { IEmbeddable, ViewMode, IEmbeddableStart } from '../embeddable_plugin';
|
||||
import { IEmbeddable, ViewMode, EmbeddableStart } from '../embeddable_plugin';
|
||||
import { DASHBOARD_CONTAINER_TYPE, DashboardContainer } from '../embeddable';
|
||||
import { ActionByType, IncompatibleActionError } from '../ui_actions_plugin';
|
||||
import { openReplacePanelFlyout } from './open_replace_panel_flyout';
|
||||
|
@ -43,7 +43,7 @@ export class ReplacePanelAction implements ActionByType<typeof ACTION_REPLACE_PA
|
|||
private core: CoreStart,
|
||||
private savedobjectfinder: React.ComponentType<any>,
|
||||
private notifications: CoreStart['notifications'],
|
||||
private getEmbeddableFactories: IEmbeddableStart['getEmbeddableFactories']
|
||||
private getEmbeddableFactories: EmbeddableStart['getEmbeddableFactories']
|
||||
) {}
|
||||
|
||||
public getDisplayName({ embeddable }: ReplacePanelActionContext) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui';
|
||||
import { GetEmbeddableFactories } from 'src/plugins/embeddable/public';
|
||||
import { EmbeddableStart } from '../../../../../src/plugins/embeddable/public';
|
||||
import { DashboardPanelState } from '../embeddable';
|
||||
import { NotificationsStart, Toast } from '../../../../core/public';
|
||||
import { IContainer, IEmbeddable, EmbeddableInput, EmbeddableOutput } from '../embeddable_plugin';
|
||||
|
@ -31,7 +31,7 @@ interface Props {
|
|||
onClose: () => void;
|
||||
notifications: NotificationsStart;
|
||||
panelToRemove: IEmbeddable<EmbeddableInput, EmbeddableOutput>;
|
||||
getEmbeddableFactories: GetEmbeddableFactories;
|
||||
getEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
}
|
||||
|
||||
export class ReplacePanelFlyout extends React.Component<Props> {
|
||||
|
|
|
@ -30,7 +30,7 @@ import {
|
|||
ViewMode,
|
||||
EmbeddableFactory,
|
||||
IEmbeddable,
|
||||
IEmbeddableStart,
|
||||
EmbeddableStart,
|
||||
} from '../embeddable_plugin';
|
||||
import { DASHBOARD_CONTAINER_TYPE } from './dashboard_constants';
|
||||
import { createPanelState } from './panel';
|
||||
|
@ -77,7 +77,7 @@ export interface DashboardContainerOptions {
|
|||
application: CoreStart['application'];
|
||||
overlays: CoreStart['overlays'];
|
||||
notifications: CoreStart['notifications'];
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
inspector: InspectorStartContract;
|
||||
SavedObjectFinder: React.ComponentType<any>;
|
||||
ExitFullScreenButton: React.ComponentType<any>;
|
||||
|
|
|
@ -18,24 +18,29 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { SavedObjectMetaData } from '../../../saved_objects/public';
|
||||
import { SavedObjectAttributes } from '../../../../core/public';
|
||||
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
|
||||
import { EmbeddableStart } from '../../../../../src/plugins/embeddable/public';
|
||||
import { CoreStart } from '../../../../core/public';
|
||||
import {
|
||||
ContainerOutput,
|
||||
EmbeddableFactory,
|
||||
ErrorEmbeddable,
|
||||
Container,
|
||||
} from '../embeddable_plugin';
|
||||
import {
|
||||
DashboardContainer,
|
||||
DashboardContainerInput,
|
||||
DashboardContainerOptions,
|
||||
} from './dashboard_container';
|
||||
import { DashboardCapabilities } from '../types';
|
||||
import { DashboardContainer, DashboardContainerInput } from './dashboard_container';
|
||||
import { DASHBOARD_CONTAINER_TYPE } from './dashboard_constants';
|
||||
import { Start as InspectorStartContract } from '../../../inspector/public';
|
||||
|
||||
export interface DashboardOptions extends DashboardContainerOptions {
|
||||
savedObjectMetaData?: SavedObjectMetaData<SavedObjectAttributes>;
|
||||
interface StartServices {
|
||||
capabilities: CoreStart['application']['capabilities'];
|
||||
application: CoreStart['application'];
|
||||
overlays: CoreStart['overlays'];
|
||||
notifications: CoreStart['notifications'];
|
||||
embeddable: EmbeddableStart;
|
||||
inspector: InspectorStartContract;
|
||||
SavedObjectFinder: React.ComponentType<any>;
|
||||
ExitFullScreenButton: React.ComponentType<any>;
|
||||
uiActions: UiActionsStart;
|
||||
}
|
||||
|
||||
export class DashboardContainerFactory extends EmbeddableFactory<
|
||||
|
@ -45,23 +50,13 @@ export class DashboardContainerFactory extends EmbeddableFactory<
|
|||
public readonly isContainerType = true;
|
||||
public readonly type = DASHBOARD_CONTAINER_TYPE;
|
||||
|
||||
private readonly allowEditing: boolean;
|
||||
|
||||
constructor(private readonly options: DashboardOptions) {
|
||||
super({ savedObjectMetaData: options.savedObjectMetaData });
|
||||
|
||||
const capabilities = (options.application.capabilities
|
||||
.dashboard as unknown) as DashboardCapabilities;
|
||||
|
||||
if (!capabilities || typeof capabilities !== 'object') {
|
||||
throw new TypeError('Dashboard capabilities not found.');
|
||||
}
|
||||
|
||||
this.allowEditing = !!capabilities.createNew && !!capabilities.showWriteControls;
|
||||
constructor(private readonly getStartServices: () => Promise<StartServices>) {
|
||||
super();
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
return this.allowEditing;
|
||||
public async isEditable() {
|
||||
const { capabilities } = await this.getStartServices();
|
||||
return !!capabilities.createNew && !!capabilities.showWriteControls;
|
||||
}
|
||||
|
||||
public getDisplayName() {
|
||||
|
@ -82,6 +77,7 @@ export class DashboardContainerFactory extends EmbeddableFactory<
|
|||
initialInput: DashboardContainerInput,
|
||||
parent?: Container
|
||||
): Promise<DashboardContainer | ErrorEmbeddable> {
|
||||
return new DashboardContainer(initialInput, this.options, parent);
|
||||
const services = await this.getStartServices();
|
||||
return new DashboardContainer(initialInput, services, parent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import sizeMe from 'react-sizeme';
|
|||
import React from 'react';
|
||||
import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { skip } from 'rxjs/operators';
|
||||
import { EmbeddableFactory, GetEmbeddableFactory } from '../../embeddable_plugin';
|
||||
import { EmbeddableFactory } from '../../embeddable_plugin';
|
||||
import { DashboardGrid, DashboardGridProps } from './dashboard_grid';
|
||||
import { DashboardContainer, DashboardContainerOptions } from '../dashboard_container';
|
||||
import { getSampleDashboardInput } from '../../test_helpers';
|
||||
|
@ -41,7 +41,7 @@ function prepare(props?: Partial<DashboardGridProps>) {
|
|||
CONTACT_CARD_EMBEDDABLE,
|
||||
new ContactCardEmbeddableFactory({} as any, (() => {}) as any, {} as any)
|
||||
);
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const initialInput = getSampleDashboardInput({
|
||||
panels: {
|
||||
'1': {
|
||||
|
|
|
@ -23,7 +23,7 @@ import * as React from 'react';
|
|||
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public';
|
||||
import { SharePluginSetup } from 'src/plugins/share/public';
|
||||
import { UiActionsSetup, UiActionsStart } from '../../../plugins/ui_actions/public';
|
||||
import { CONTEXT_MENU_TRIGGER, IEmbeddableSetup, IEmbeddableStart } from './embeddable_plugin';
|
||||
import { CONTEXT_MENU_TRIGGER, EmbeddableSetup, EmbeddableStart } from './embeddable_plugin';
|
||||
import { ExpandPanelAction, ReplacePanelAction } from '.';
|
||||
import { DashboardContainerFactory } from './embeddable/dashboard_container_factory';
|
||||
import { Start as InspectorStartContract } from '../../../plugins/inspector/public';
|
||||
|
@ -47,13 +47,13 @@ declare module '../../share/public' {
|
|||
}
|
||||
|
||||
interface SetupDependencies {
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
uiActions: UiActionsSetup;
|
||||
share?: SharePluginSetup;
|
||||
}
|
||||
|
||||
interface StartDependencies {
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
inspector: InspectorStartContract;
|
||||
uiActions: UiActionsStart;
|
||||
}
|
||||
|
@ -72,7 +72,10 @@ export class DashboardEmbeddableContainerPublicPlugin
|
|||
implements Plugin<Setup, Start, SetupDependencies, StartDependencies> {
|
||||
constructor(initializerContext: PluginInitializerContext) {}
|
||||
|
||||
public setup(core: CoreSetup, { share, uiActions }: SetupDependencies): Setup {
|
||||
public setup(
|
||||
core: CoreSetup<StartDependencies>,
|
||||
{ share, uiActions, embeddable }: SetupDependencies
|
||||
): Setup {
|
||||
const expandPanelAction = new ExpandPanelAction();
|
||||
uiActions.registerAction(expandPanelAction);
|
||||
uiActions.attachAction(CONTEXT_MENU_TRIGGER, expandPanelAction);
|
||||
|
@ -86,26 +89,44 @@ export class DashboardEmbeddableContainerPublicPlugin
|
|||
}))
|
||||
);
|
||||
}
|
||||
|
||||
const getStartServices = async () => {
|
||||
const [coreStart, deps] = await core.getStartServices();
|
||||
|
||||
const useHideChrome = () => {
|
||||
React.useEffect(() => {
|
||||
coreStart.chrome.setIsVisible(false);
|
||||
return () => coreStart.chrome.setIsVisible(true);
|
||||
}, []);
|
||||
};
|
||||
|
||||
const ExitFullScreenButton: React.FC<ExitFullScreenButtonProps> = props => {
|
||||
useHideChrome();
|
||||
return <ExitFullScreenButtonUi {...props} />;
|
||||
};
|
||||
return {
|
||||
capabilities: coreStart.application.capabilities,
|
||||
application: coreStart.application,
|
||||
notifications: coreStart.notifications,
|
||||
overlays: coreStart.overlays,
|
||||
embeddable: deps.embeddable,
|
||||
inspector: deps.inspector,
|
||||
SavedObjectFinder: getSavedObjectFinder(coreStart.savedObjects, coreStart.uiSettings),
|
||||
ExitFullScreenButton,
|
||||
uiActions: deps.uiActions,
|
||||
};
|
||||
};
|
||||
|
||||
const factory = new DashboardContainerFactory(getStartServices);
|
||||
embeddable.registerEmbeddableFactory(factory.type, factory);
|
||||
}
|
||||
|
||||
public start(core: CoreStart, plugins: StartDependencies): Start {
|
||||
const { application, notifications, overlays } = core;
|
||||
const { embeddable, inspector, uiActions } = plugins;
|
||||
const { notifications } = core;
|
||||
const { uiActions } = plugins;
|
||||
|
||||
const SavedObjectFinder = getSavedObjectFinder(core.savedObjects, core.uiSettings);
|
||||
|
||||
const useHideChrome = () => {
|
||||
React.useEffect(() => {
|
||||
core.chrome.setIsVisible(false);
|
||||
return () => core.chrome.setIsVisible(true);
|
||||
}, []);
|
||||
};
|
||||
|
||||
const ExitFullScreenButton: React.FC<ExitFullScreenButtonProps> = props => {
|
||||
useHideChrome();
|
||||
return <ExitFullScreenButtonUi {...props} />;
|
||||
};
|
||||
|
||||
const changeViewAction = new ReplacePanelAction(
|
||||
core,
|
||||
SavedObjectFinder,
|
||||
|
@ -114,19 +135,6 @@ export class DashboardEmbeddableContainerPublicPlugin
|
|||
);
|
||||
uiActions.registerAction(changeViewAction);
|
||||
uiActions.attachAction(CONTEXT_MENU_TRIGGER, changeViewAction);
|
||||
|
||||
const factory = new DashboardContainerFactory({
|
||||
application,
|
||||
notifications,
|
||||
overlays,
|
||||
embeddable,
|
||||
inspector,
|
||||
SavedObjectFinder,
|
||||
ExitFullScreenButton,
|
||||
uiActions,
|
||||
});
|
||||
|
||||
embeddable.registerEmbeddableFactory(factory.type, factory);
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { EmbeddableApiPure } from './types';
|
||||
|
||||
export const getEmbeddableFactories: EmbeddableApiPure['getEmbeddableFactories'] = ({
|
||||
embeddableFactories,
|
||||
}) => () => {
|
||||
return embeddableFactories.values();
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { EmbeddableApiPure } from './types';
|
||||
|
||||
export const getEmbeddableFactory: EmbeddableApiPure['getEmbeddableFactory'] = ({
|
||||
embeddableFactories,
|
||||
}) => embeddableFactoryId => {
|
||||
const factory = embeddableFactories.get(embeddableFactoryId);
|
||||
|
||||
if (!factory) {
|
||||
throw new Error(
|
||||
`Embeddable factory [embeddableFactoryId = ${embeddableFactoryId}] does not exist.`
|
||||
);
|
||||
}
|
||||
|
||||
return factory;
|
||||
};
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EmbeddableApiPure,
|
||||
EmbeddableDependencies,
|
||||
EmbeddableApi,
|
||||
EmbeddableDependenciesInternal,
|
||||
} from './types';
|
||||
import { getEmbeddableFactories } from './get_embeddable_factories';
|
||||
import { getEmbeddableFactory } from './get_embeddable_factory';
|
||||
import { registerEmbeddableFactory } from './register_embeddable_factory';
|
||||
|
||||
export * from './types';
|
||||
|
||||
export const pureApi: EmbeddableApiPure = {
|
||||
getEmbeddableFactories,
|
||||
getEmbeddableFactory,
|
||||
registerEmbeddableFactory,
|
||||
};
|
||||
|
||||
export const createApi = (deps: EmbeddableDependencies) => {
|
||||
const partialApi: Partial<EmbeddableApi> = {};
|
||||
const depsInternal: EmbeddableDependenciesInternal = { ...deps, api: partialApi };
|
||||
for (const [key, fn] of Object.entries(pureApi)) {
|
||||
(partialApi as any)[key] = fn(depsInternal);
|
||||
}
|
||||
Object.freeze(partialApi);
|
||||
const api = partialApi as EmbeddableApi;
|
||||
return { api, depsInternal };
|
||||
};
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { EmbeddableApiPure } from './types';
|
||||
|
||||
export const registerEmbeddableFactory: EmbeddableApiPure['registerEmbeddableFactory'] = ({
|
||||
embeddableFactories,
|
||||
}) => (embeddableFactoryId, factory) => {
|
||||
if (embeddableFactories.has(embeddableFactoryId)) {
|
||||
throw new Error(
|
||||
`Embeddable factory [embeddableFactoryId = ${embeddableFactoryId}] already registered in Embeddables API.`
|
||||
);
|
||||
}
|
||||
|
||||
embeddableFactories.set(embeddableFactoryId, factory);
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { EmbeddableDependencies } from '../types';
|
||||
|
||||
export const createDeps = (): EmbeddableDependencies => {
|
||||
const deps: EmbeddableDependencies = {
|
||||
embeddableFactories: new Map<any, any>(),
|
||||
};
|
||||
return deps;
|
||||
};
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { EmbeddableFactoryRegistry } from '../types';
|
||||
import { EmbeddableFactory, GetEmbeddableFactories } from '../lib';
|
||||
|
||||
export interface EmbeddableApi {
|
||||
getEmbeddableFactory: (embeddableFactoryId: string) => EmbeddableFactory;
|
||||
getEmbeddableFactories: GetEmbeddableFactories;
|
||||
// TODO: Make `registerEmbeddableFactory` receive only `factory` argument.
|
||||
registerEmbeddableFactory: <TEmbeddableFactory extends EmbeddableFactory>(
|
||||
id: string,
|
||||
factory: TEmbeddableFactory
|
||||
) => void;
|
||||
}
|
||||
|
||||
export interface EmbeddableDependencies {
|
||||
embeddableFactories: EmbeddableFactoryRegistry;
|
||||
}
|
||||
|
||||
export interface EmbeddableDependenciesInternal extends EmbeddableDependencies {
|
||||
api: Readonly<Partial<EmbeddableApi>>;
|
||||
}
|
||||
|
||||
export type EmbeddableApiPure = {
|
||||
[K in keyof EmbeddableApi]: (deps: EmbeddableDependenciesInternal) => EmbeddableApi[K];
|
||||
};
|
|
@ -48,8 +48,6 @@ export {
|
|||
EmbeddableRoot,
|
||||
EmbeddableVisTriggerContext,
|
||||
ErrorEmbeddable,
|
||||
GetEmbeddableFactories,
|
||||
GetEmbeddableFactory,
|
||||
IContainer,
|
||||
IEmbeddable,
|
||||
isErrorEmbeddable,
|
||||
|
@ -68,4 +66,4 @@ export function plugin(initializerContext: PluginInitializerContext) {
|
|||
return new EmbeddablePublicPlugin(initializerContext);
|
||||
}
|
||||
|
||||
export { IEmbeddableSetup, IEmbeddableStart } from './plugin';
|
||||
export { EmbeddableSetup, EmbeddableStart } from './plugin';
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
|
||||
import { EditPanelAction } from './edit_panel_action';
|
||||
import { EmbeddableFactory, Embeddable, EmbeddableInput } from '../embeddables';
|
||||
import { GetEmbeddableFactory, ViewMode } from '../types';
|
||||
import { ViewMode } from '../types';
|
||||
import { ContactCardEmbeddable } from '../test_samples';
|
||||
import { EmbeddableStart } from '../../plugin';
|
||||
|
||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||
const getFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getFactory = ((id: string) =>
|
||||
embeddableFactories.get(id)) as EmbeddableStart['getEmbeddableFactory'];
|
||||
|
||||
class EditableEmbeddable extends Embeddable {
|
||||
public readonly type = 'EDITABLE_EMBEDDABLE';
|
||||
|
@ -82,7 +84,8 @@ test('is not compatible when edit url is not available', async () => {
|
|||
|
||||
test('is not visible when edit url is available but in view mode', async () => {
|
||||
embeddableFactories.clear();
|
||||
const action = new EditPanelAction(type => embeddableFactories.get(type));
|
||||
const action = new EditPanelAction((type =>
|
||||
embeddableFactories.get(type)) as EmbeddableStart['getEmbeddableFactory']);
|
||||
expect(
|
||||
await action.isCompatible({
|
||||
embeddable: new EditableEmbeddable(
|
||||
|
@ -98,7 +101,8 @@ test('is not visible when edit url is available but in view mode', async () => {
|
|||
|
||||
test('is not compatible when edit url is available, in edit mode, but not editable', async () => {
|
||||
embeddableFactories.clear();
|
||||
const action = new EditPanelAction(type => embeddableFactories.get(type));
|
||||
const action = new EditPanelAction((type =>
|
||||
embeddableFactories.get(type)) as EmbeddableStart['getEmbeddableFactory']);
|
||||
expect(
|
||||
await action.isCompatible({
|
||||
embeddable: new EditableEmbeddable(
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Action } from 'src/plugins/ui_actions/public';
|
||||
import { GetEmbeddableFactory, ViewMode } from '../types';
|
||||
import { ViewMode } from '../types';
|
||||
import { EmbeddableFactoryNotFoundError } from '../errors';
|
||||
import { IEmbeddable } from '../embeddables';
|
||||
import { EmbeddableStart } from '../../plugin';
|
||||
|
||||
export const ACTION_EDIT_PANEL = 'editPanel';
|
||||
|
||||
|
@ -34,7 +35,7 @@ export class EditPanelAction implements Action<ActionContext> {
|
|||
public readonly id = ACTION_EDIT_PANEL;
|
||||
public order = 15;
|
||||
|
||||
constructor(private readonly getEmbeddableFactory: GetEmbeddableFactory) {}
|
||||
constructor(private readonly getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']) {}
|
||||
|
||||
public getDisplayName({ embeddable }: ActionContext) {
|
||||
const factory = this.getEmbeddableFactory(embeddable.type);
|
||||
|
|
|
@ -29,7 +29,7 @@ import {
|
|||
} from '../embeddables';
|
||||
import { IContainer, ContainerInput, ContainerOutput, PanelState } from './i_container';
|
||||
import { PanelNotFoundError, EmbeddableFactoryNotFoundError } from '../errors';
|
||||
import { GetEmbeddableFactory } from '../types';
|
||||
import { EmbeddableStart } from '../../plugin';
|
||||
|
||||
const getKeys = <T extends {}>(o: T): Array<keyof T> => Object.keys(o) as Array<keyof T>;
|
||||
|
||||
|
@ -49,7 +49,7 @@ export abstract class Container<
|
|||
constructor(
|
||||
input: TContainerInput,
|
||||
output: TContainerOutput,
|
||||
protected readonly getFactory: GetEmbeddableFactory,
|
||||
protected readonly getFactory: EmbeddableStart['getEmbeddableFactory'],
|
||||
parent?: Container
|
||||
) {
|
||||
super(input, output, parent);
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
import React from 'react';
|
||||
import { nextTick } from 'test_utils/enzyme_helpers';
|
||||
import { EmbeddableChildPanel } from './embeddable_child_panel';
|
||||
import { GetEmbeddableFactory } from '../types';
|
||||
import { EmbeddableFactory } from '../embeddables';
|
||||
import { CONTACT_CARD_EMBEDDABLE } from '../test_samples/embeddables/contact_card/contact_card_embeddable_factory';
|
||||
import { SlowContactCardEmbeddableFactory } from '../test_samples/embeddables/contact_card/slow_contact_card_embeddable_factory';
|
||||
|
@ -42,7 +41,7 @@ test('EmbeddableChildPanel renders an embeddable when it is done loading', async
|
|||
CONTACT_CARD_EMBEDDABLE,
|
||||
new SlowContactCardEmbeddableFactory({ execAction: (() => null) as any })
|
||||
);
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
|
||||
const container = new HelloWorldContainer({ id: 'hello', panels: {} }, {
|
||||
getEmbeddableFactory,
|
||||
|
@ -88,7 +87,7 @@ test('EmbeddableChildPanel renders an embeddable when it is done loading', async
|
|||
|
||||
test(`EmbeddableChildPanel renders an error message if the factory doesn't exist`, async () => {
|
||||
const inspector = inspectorPluginMock.createStartContract();
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = () => undefined;
|
||||
const getEmbeddableFactory = () => undefined;
|
||||
const container = new HelloWorldContainer(
|
||||
{
|
||||
id: 'hello',
|
||||
|
|
|
@ -29,15 +29,15 @@ import { Start as InspectorStartContract } from 'src/plugins/inspector/public';
|
|||
import { ErrorEmbeddable, IEmbeddable } from '../embeddables';
|
||||
import { EmbeddablePanel } from '../panel';
|
||||
import { IContainer } from './i_container';
|
||||
import { GetEmbeddableFactory, GetEmbeddableFactories } from '../types';
|
||||
import { EmbeddableStart } from '../../plugin';
|
||||
|
||||
export interface EmbeddableChildPanelProps {
|
||||
embeddableId: string;
|
||||
className?: string;
|
||||
container: IContainer;
|
||||
getActions: UiActionsService['getTriggerCompatibleActions'];
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getAllEmbeddableFactories: GetEmbeddableFactories;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
overlays: CoreStart['overlays'];
|
||||
notifications: CoreStart['notifications'];
|
||||
inspector: InspectorStartContract;
|
||||
|
|
|
@ -74,13 +74,11 @@ export abstract class EmbeddableFactory<
|
|||
this.savedObjectMetaData = savedObjectMetaData;
|
||||
}
|
||||
|
||||
// TODO: Can this be a property? If this "...should be based of capabilities service...",
|
||||
// TODO: maybe then it should be *async*?
|
||||
/**
|
||||
* Returns whether the current user should be allowed to edit this type of
|
||||
* embeddable. Most of the time this should be based off the capabilities service.
|
||||
* embeddable. Most of the time this should be based off the capabilities service, hence it's async.
|
||||
*/
|
||||
public abstract isEditable(): boolean;
|
||||
public abstract async isEditable(): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Returns a display name for this type of embeddable. Used in "Create new... " options
|
||||
|
|
|
@ -22,21 +22,21 @@ import {
|
|||
HelloWorldEmbeddableFactory,
|
||||
} from '../../../../../../examples/embeddable_examples/public';
|
||||
import { EmbeddableFactory } from './embeddable_factory';
|
||||
import { GetEmbeddableFactory } from '../types';
|
||||
import { EmbeddableFactoryRenderer } from './embeddable_factory_renderer';
|
||||
import { mount } from 'enzyme';
|
||||
import { nextTick } from 'test_utils/enzyme_helpers';
|
||||
// @ts-ignore
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { EmbeddableStart } from '../../plugin';
|
||||
|
||||
test('EmbeddableFactoryRenderer renders an embeddable', async () => {
|
||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||
embeddableFactories.set(HELLO_WORLD_EMBEDDABLE, new HelloWorldEmbeddableFactory());
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
|
||||
const component = mount(
|
||||
<EmbeddableFactoryRenderer
|
||||
getEmbeddableFactory={getEmbeddableFactory}
|
||||
getEmbeddableFactory={getEmbeddableFactory as EmbeddableStart['getEmbeddableFactory']}
|
||||
type={HELLO_WORLD_EMBEDDABLE}
|
||||
input={{ id: '123' }}
|
||||
/>
|
||||
|
@ -54,7 +54,7 @@ test('EmbeddableFactoryRenderer renders an embeddable', async () => {
|
|||
});
|
||||
|
||||
test('EmbeddableRoot renders an error if the type does not exist', async () => {
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => undefined;
|
||||
const getEmbeddableFactory = (id: string) => undefined;
|
||||
|
||||
const component = mount(
|
||||
<EmbeddableFactoryRenderer
|
||||
|
|
|
@ -21,11 +21,11 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { IEmbeddable, EmbeddableInput } from './i_embeddable';
|
||||
import { EmbeddableRoot } from './embeddable_root';
|
||||
import { GetEmbeddableFactory } from '../types';
|
||||
import { EmbeddableStart } from '../../plugin';
|
||||
|
||||
interface Props {
|
||||
type: string;
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
input: EmbeddableInput;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import { findTestSubject } from '@elastic/eui/lib/test';
|
|||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
import { CONTEXT_MENU_TRIGGER } from '../triggers';
|
||||
import { Action, UiActionsStart, ActionType } from 'src/plugins/ui_actions/public';
|
||||
import { Trigger, GetEmbeddableFactory, ViewMode } from '../types';
|
||||
import { Trigger, ViewMode } from '../types';
|
||||
import { EmbeddableFactory, isErrorEmbeddable } from '../embeddables';
|
||||
import { EmbeddablePanel } from './embeddable_panel';
|
||||
import { createEditModeAction } from '../test_samples/actions';
|
||||
|
@ -47,7 +47,7 @@ import { EuiBadge } from '@elastic/eui';
|
|||
const actionRegistry = new Map<string, Action<object | undefined | string | number>>();
|
||||
const triggerRegistry = new Map<string, Trigger>();
|
||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
|
||||
const editModeAction = createEditModeAction();
|
||||
const trigger: Trigger = {
|
||||
|
|
|
@ -27,7 +27,7 @@ import { toMountPoint } from '../../../../kibana_react/public';
|
|||
import { Start as InspectorStartContract } from '../inspector';
|
||||
import { CONTEXT_MENU_TRIGGER, PANEL_BADGE_TRIGGER, EmbeddableContext } from '../triggers';
|
||||
import { IEmbeddable } from '../embeddables/i_embeddable';
|
||||
import { ViewMode, GetEmbeddableFactory, GetEmbeddableFactories } from '../types';
|
||||
import { ViewMode } from '../types';
|
||||
|
||||
import { RemovePanelAction } from './panel_header/panel_actions';
|
||||
import { AddPanelAction } from './panel_header/panel_actions/add_panel/add_panel_action';
|
||||
|
@ -36,12 +36,13 @@ import { PanelHeader } from './panel_header/panel_header';
|
|||
import { InspectPanelAction } from './panel_header/panel_actions/inspect_panel_action';
|
||||
import { EditPanelAction } from '../actions';
|
||||
import { CustomizePanelModal } from './panel_header/panel_actions/customize_title/customize_panel_modal';
|
||||
import { EmbeddableStart } from '../../plugin';
|
||||
|
||||
interface Props {
|
||||
embeddable: IEmbeddable<any, any>;
|
||||
getActions: UiActionsService['getTriggerCompatibleActions'];
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getAllEmbeddableFactories: GetEmbeddableFactories;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
overlays: CoreStart['overlays'];
|
||||
notifications: CoreStart['notifications'];
|
||||
inspector: InspectorStartContract;
|
||||
|
|
|
@ -27,15 +27,15 @@ import {
|
|||
} from '../../../../test_samples/embeddables/filterable_embeddable';
|
||||
import { FilterableEmbeddableFactory } from '../../../../test_samples/embeddables/filterable_embeddable_factory';
|
||||
import { FilterableContainer } from '../../../../test_samples/embeddables/filterable_container';
|
||||
import { GetEmbeddableFactory } from '../../../../types';
|
||||
// eslint-disable-next-line
|
||||
import { coreMock } from '../../../../../../../../core/public/mocks';
|
||||
import { ContactCardEmbeddable } from '../../../../test_samples';
|
||||
import { esFilters, Filter } from '../../../../../../../../plugins/data/public';
|
||||
import { EmbeddableStart } from 'src/plugins/embeddable/public/plugin';
|
||||
|
||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||
embeddableFactories.set(FILTERABLE_EMBEDDABLE, new FilterableEmbeddableFactory());
|
||||
const getFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getFactory = (id: string) => embeddableFactories.get(id);
|
||||
|
||||
let container: FilterableContainer;
|
||||
let embeddable: FilterableEmbeddable;
|
||||
|
@ -58,7 +58,7 @@ beforeEach(async () => {
|
|||
};
|
||||
container = new FilterableContainer(
|
||||
{ id: 'hello', panels: {}, filters: [derivedFilter] },
|
||||
getFactory
|
||||
getFactory as EmbeddableStart['getEmbeddableFactory']
|
||||
);
|
||||
|
||||
const filterableEmbeddable = await container.addNewEmbeddable<
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { Action } from 'src/plugins/ui_actions/public';
|
||||
import { NotificationsStart, OverlayStart } from 'src/core/public';
|
||||
import { ViewMode, GetEmbeddableFactory, GetEmbeddableFactories } from '../../../../types';
|
||||
import { EmbeddableStart } from 'src/plugins/embeddable/public/plugin';
|
||||
import { ViewMode } from '../../../../types';
|
||||
import { openAddPanelFlyout } from './open_add_panel_flyout';
|
||||
import { IContainer } from '../../../../containers';
|
||||
|
||||
|
@ -34,8 +35,8 @@ export class AddPanelAction implements Action<ActionContext> {
|
|||
public readonly id = ACTION_ADD_PANEL;
|
||||
|
||||
constructor(
|
||||
private readonly getFactory: GetEmbeddableFactory,
|
||||
private readonly getAllFactories: GetEmbeddableFactories,
|
||||
private readonly getFactory: EmbeddableStart['getEmbeddableFactory'],
|
||||
private readonly getAllFactories: EmbeddableStart['getEmbeddableFactories'],
|
||||
private readonly overlays: OverlayStart,
|
||||
private readonly notifications: NotificationsStart,
|
||||
private readonly SavedObjectFinder: React.ComponentType<any>
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
import * as React from 'react';
|
||||
import { AddPanelFlyout } from './add_panel_flyout';
|
||||
import { GetEmbeddableFactory } from '../../../../types';
|
||||
import {
|
||||
ContactCardEmbeddableFactory,
|
||||
CONTACT_CARD_EMBEDDABLE,
|
||||
|
@ -32,6 +31,7 @@ import { ReactWrapper } from 'enzyme';
|
|||
import { coreMock } from '../../../../../../../../core/public/mocks';
|
||||
// @ts-ignore
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { EmbeddableStart } from 'src/plugins/embeddable/public/plugin';
|
||||
|
||||
function DummySavedObjectFinder(props: { children: React.ReactNode }) {
|
||||
return (
|
||||
|
@ -55,7 +55,7 @@ test('createNewEmbeddable() add embeddable to container', async () => {
|
|||
firstName: 'foo',
|
||||
lastName: 'bar',
|
||||
} as any);
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => contactCardEmbeddableFactory;
|
||||
const getEmbeddableFactory = (id: string) => contactCardEmbeddableFactory;
|
||||
const input: ContainerInput<{ firstName: string; lastName: string }> = {
|
||||
id: '1',
|
||||
panels: {},
|
||||
|
@ -66,7 +66,7 @@ test('createNewEmbeddable() add embeddable to container', async () => {
|
|||
<AddPanelFlyout
|
||||
container={container}
|
||||
onClose={onClose}
|
||||
getFactory={getEmbeddableFactory}
|
||||
getFactory={getEmbeddableFactory as EmbeddableStart['getEmbeddableFactory']}
|
||||
getAllFactories={() => new Set<any>([contactCardEmbeddableFactory]).values()}
|
||||
notifications={core.notifications}
|
||||
SavedObjectFinder={() => null}
|
||||
|
@ -100,7 +100,8 @@ test('selecting embeddable in "Create new ..." list calls createNewEmbeddable()'
|
|||
firstName: 'foo',
|
||||
lastName: 'bar',
|
||||
} as any);
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => contactCardEmbeddableFactory;
|
||||
const getEmbeddableFactory = ((id: string) =>
|
||||
contactCardEmbeddableFactory) as EmbeddableStart['getEmbeddableFactory'];
|
||||
const input: ContainerInput<{ firstName: string; lastName: string }> = {
|
||||
id: '1',
|
||||
panels: {},
|
||||
|
|
|
@ -29,16 +29,16 @@ import {
|
|||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { EmbeddableStart } from 'src/plugins/embeddable/public/plugin';
|
||||
import { IContainer } from '../../../../containers';
|
||||
import { EmbeddableFactoryNotFoundError } from '../../../../errors';
|
||||
import { GetEmbeddableFactories, GetEmbeddableFactory } from '../../../../types';
|
||||
import { SavedObjectFinderCreateNew } from './saved_object_finder_create_new';
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
container: IContainer;
|
||||
getFactory: GetEmbeddableFactory;
|
||||
getAllFactories: GetEmbeddableFactories;
|
||||
getFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
getAllFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
notifications: CoreSetup['notifications'];
|
||||
SavedObjectFinder: React.ComponentType<any>;
|
||||
}
|
||||
|
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { NotificationsStart, OverlayStart } from 'src/core/public';
|
||||
import { EmbeddableStart } from '../../../../../plugin';
|
||||
import { toMountPoint } from '../../../../../../../kibana_react/public';
|
||||
import { IContainer } from '../../../../containers';
|
||||
import { AddPanelFlyout } from './add_panel_flyout';
|
||||
import { GetEmbeddableFactory, GetEmbeddableFactories } from '../../../../types';
|
||||
|
||||
export async function openAddPanelFlyout(options: {
|
||||
embeddable: IContainer;
|
||||
getFactory: GetEmbeddableFactory;
|
||||
getAllFactories: GetEmbeddableFactories;
|
||||
getFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
getAllFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
overlays: OverlayStart;
|
||||
notifications: NotificationsStart;
|
||||
SavedObjectFinder: React.ComponentType<any>;
|
||||
|
|
|
@ -32,7 +32,6 @@ import {
|
|||
ContactCardEmbeddableFactory,
|
||||
} from '../../../../test_samples/embeddables/contact_card/contact_card_embeddable_factory';
|
||||
import { HelloWorldContainer } from '../../../../test_samples/embeddables/hello_world_container';
|
||||
import { GetEmbeddableFactory } from '../../../../types';
|
||||
import { EmbeddableFactory } from '../../../../embeddables';
|
||||
|
||||
let container: Container;
|
||||
|
@ -40,7 +39,7 @@ let embeddable: ContactCardEmbeddable;
|
|||
|
||||
function createHelloWorldContainer(input = { id: '123', panels: {} }) {
|
||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||
const getEmbeddableFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
embeddableFactories.set(
|
||||
CONTACT_CARD_EMBEDDABLE,
|
||||
new ContactCardEmbeddableFactory({}, (() => {}) as any, {} as any)
|
||||
|
|
|
@ -34,14 +34,14 @@ import {
|
|||
isErrorEmbeddable,
|
||||
ErrorEmbeddable,
|
||||
} from '../../../embeddables';
|
||||
import { GetEmbeddableFactory } from '../../../types';
|
||||
import { of } from '../../../../tests/helpers';
|
||||
import { esFilters } from '../../../../../../../plugins/data/public';
|
||||
import { EmbeddableStart } from 'src/plugins/embeddable/public/plugin';
|
||||
|
||||
const setup = async () => {
|
||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||
embeddableFactories.set(FILTERABLE_EMBEDDABLE, new FilterableEmbeddableFactory());
|
||||
const getFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getFactory = (id: string) => embeddableFactories.get(id);
|
||||
const container = new FilterableContainer(
|
||||
{
|
||||
id: 'hello',
|
||||
|
@ -54,7 +54,7 @@ const setup = async () => {
|
|||
},
|
||||
],
|
||||
},
|
||||
getFactory
|
||||
getFactory as EmbeddableStart['getEmbeddableFactory']
|
||||
);
|
||||
|
||||
const embeddable: FilterableEmbeddable | ErrorEmbeddable = await container.addNewEmbeddable<
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import { EmbeddableOutput, isErrorEmbeddable } from '../../../';
|
||||
import { RemovePanelAction } from './remove_panel_action';
|
||||
import { EmbeddableFactory } from '../../../embeddables';
|
||||
import { EmbeddableStart } from '../../../../plugin';
|
||||
import {
|
||||
FILTERABLE_EMBEDDABLE,
|
||||
FilterableEmbeddable,
|
||||
|
@ -27,13 +28,13 @@ import {
|
|||
} from '../../../test_samples/embeddables/filterable_embeddable';
|
||||
import { FilterableEmbeddableFactory } from '../../../test_samples/embeddables/filterable_embeddable_factory';
|
||||
import { FilterableContainer } from '../../../test_samples/embeddables/filterable_container';
|
||||
import { GetEmbeddableFactory, ViewMode } from '../../../types';
|
||||
import { ViewMode } from '../../../types';
|
||||
import { ContactCardEmbeddable } from '../../../test_samples/embeddables/contact_card/contact_card_embeddable';
|
||||
import { esFilters, Filter } from '../../../../../../../plugins/data/public';
|
||||
|
||||
const embeddableFactories = new Map<string, EmbeddableFactory>();
|
||||
embeddableFactories.set(FILTERABLE_EMBEDDABLE, new FilterableEmbeddableFactory());
|
||||
const getFactory: GetEmbeddableFactory = (id: string) => embeddableFactories.get(id);
|
||||
const getFactory = (id: string) => embeddableFactories.get(id);
|
||||
|
||||
let container: FilterableContainer;
|
||||
let embeddable: FilterableEmbeddable;
|
||||
|
@ -46,7 +47,7 @@ beforeEach(async () => {
|
|||
};
|
||||
container = new FilterableContainer(
|
||||
{ id: 'hello', panels: {}, filters: [derivedFilter], viewMode: ViewMode.EDIT },
|
||||
getFactory
|
||||
getFactory as EmbeddableStart['getEmbeddableFactory']
|
||||
);
|
||||
|
||||
const filterableEmbeddable = await container.addNewEmbeddable<
|
||||
|
|
|
@ -42,7 +42,7 @@ export class ContactCardEmbeddableFactory extends EmbeddableFactory<ContactCardE
|
|||
super(options);
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ export class SlowContactCardEmbeddableFactory extends EmbeddableFactory<
|
|||
}
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
*/
|
||||
|
||||
import { Container, ContainerInput } from '../../containers';
|
||||
import { GetEmbeddableFactory } from '../../types';
|
||||
import { Filter } from '../../../../../data/public';
|
||||
import { EmbeddableStart } from '../../../plugin';
|
||||
|
||||
export const FILTERABLE_CONTAINER = 'FILTERABLE_CONTAINER';
|
||||
|
||||
|
@ -46,7 +46,7 @@ export class FilterableContainer extends Container<
|
|||
|
||||
constructor(
|
||||
initialInput: FilterableContainerInput,
|
||||
getFactory: GetEmbeddableFactory,
|
||||
getFactory: EmbeddableStart['getEmbeddableFactory'],
|
||||
parent?: Container
|
||||
) {
|
||||
super(initialInput, { embeddableLoaded: {} }, getFactory, parent);
|
||||
|
|
|
@ -24,14 +24,14 @@ import {
|
|||
FilterableContainerInput,
|
||||
FILTERABLE_CONTAINER,
|
||||
} from './filterable_container';
|
||||
import { GetEmbeddableFactory } from '../../types';
|
||||
import { EmbeddableFactoryOptions } from '../../embeddables/embeddable_factory';
|
||||
import { EmbeddableStart } from '../../../plugin';
|
||||
|
||||
export class FilterableContainerFactory extends EmbeddableFactory<FilterableContainerInput> {
|
||||
public readonly type = FILTERABLE_CONTAINER;
|
||||
|
||||
constructor(
|
||||
private readonly getFactory: GetEmbeddableFactory,
|
||||
private readonly getFactory: EmbeddableStart['getEmbeddableFactory'],
|
||||
options: EmbeddableFactoryOptions<any> = {}
|
||||
) {
|
||||
super(options);
|
||||
|
@ -43,7 +43,7 @@ export class FilterableContainerFactory extends EmbeddableFactory<FilterableCont
|
|||
});
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ import { IContainer } from '../../containers';
|
|||
export class FilterableEmbeddableFactory extends EmbeddableFactory<FilterableEmbeddableInput> {
|
||||
public readonly type = FILTERABLE_EMBEDDABLE;
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import { UiActionsService } from 'src/plugins/ui_actions/public';
|
|||
import { Start as InspectorStartContract } from 'src/plugins/inspector/public';
|
||||
import { Container, ViewMode, ContainerInput } from '../..';
|
||||
import { HelloWorldContainerComponent } from './hello_world_container_component';
|
||||
import { GetEmbeddableFactory, GetEmbeddableFactories } from '../../types';
|
||||
import { EmbeddableStart } from '../../../plugin';
|
||||
|
||||
export const HELLO_WORLD_CONTAINER = 'HELLO_WORLD_CONTAINER';
|
||||
|
||||
|
@ -46,8 +46,8 @@ interface HelloWorldContainerInput extends ContainerInput {
|
|||
|
||||
interface HelloWorldContainerOptions {
|
||||
getActions: UiActionsService['getTriggerCompatibleActions'];
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getAllEmbeddableFactories: GetEmbeddableFactories;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
overlays: CoreStart['overlays'];
|
||||
notifications: CoreStart['notifications'];
|
||||
inspector: InspectorStartContract;
|
||||
|
|
|
@ -24,13 +24,13 @@ import { CoreStart } from 'src/core/public';
|
|||
import { UiActionsService } from 'src/plugins/ui_actions/public';
|
||||
import { Start as InspectorStartContract } from 'src/plugins/inspector/public';
|
||||
import { IContainer, PanelState, EmbeddableChildPanel } from '../..';
|
||||
import { GetEmbeddableFactory, GetEmbeddableFactories } from '../../types';
|
||||
import { EmbeddableStart } from '../../../plugin';
|
||||
|
||||
interface Props {
|
||||
container: IContainer;
|
||||
getActions: UiActionsService['getTriggerCompatibleActions'];
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getAllEmbeddableFactories: GetEmbeddableFactories;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
overlays: CoreStart['overlays'];
|
||||
notifications: CoreStart['notifications'];
|
||||
inspector: InspectorStartContract;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
import { Adapters } from './inspector';
|
||||
import { EmbeddableFactory } from './embeddables/embeddable_factory';
|
||||
|
||||
export interface Trigger {
|
||||
id: string;
|
||||
|
@ -40,6 +39,3 @@ export enum ViewMode {
|
|||
}
|
||||
|
||||
export { Adapters };
|
||||
|
||||
export type GetEmbeddableFactory = (id: string) => EmbeddableFactory | undefined;
|
||||
export type GetEmbeddableFactories = () => IterableIterator<EmbeddableFactory>;
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { IEmbeddableStart, IEmbeddableSetup } from '.';
|
||||
import { EmbeddableStart, EmbeddableSetup } from '.';
|
||||
import { EmbeddablePublicPlugin } from './plugin';
|
||||
import { coreMock } from '../../../core/public/mocks';
|
||||
|
||||
// eslint-disable-next-line
|
||||
import { uiActionsPluginMock } from '../../ui_actions/public/mocks';
|
||||
|
||||
export type Setup = jest.Mocked<IEmbeddableSetup>;
|
||||
export type Start = jest.Mocked<IEmbeddableStart>;
|
||||
export type Setup = jest.Mocked<EmbeddableSetup>;
|
||||
export type Start = jest.Mocked<EmbeddableStart>;
|
||||
|
||||
const createSetupContract = (): Setup => {
|
||||
const setupContract: Setup = {
|
||||
|
@ -36,7 +36,6 @@ const createSetupContract = (): Setup => {
|
|||
|
||||
const createStartContract = (): Start => {
|
||||
const startContract: Start = {
|
||||
registerEmbeddableFactory: jest.fn(),
|
||||
getEmbeddableFactories: jest.fn(),
|
||||
getEmbeddableFactory: jest.fn(),
|
||||
};
|
||||
|
|
|
@ -16,18 +16,20 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { createApi } from '..';
|
||||
import { createDeps } from './helpers';
|
||||
import { coreMock } from '../../../core/public/mocks';
|
||||
import { testPlugin } from './tests/test_plugin';
|
||||
|
||||
test('cannot register embeddable factory with the same ID', async () => {
|
||||
const deps = createDeps();
|
||||
const { api } = createApi(deps);
|
||||
const coreSetup = coreMock.createSetup();
|
||||
const coreStart = coreMock.createStart();
|
||||
const { setup } = testPlugin(coreSetup, coreStart);
|
||||
const embeddableFactoryId = 'ID';
|
||||
const embeddableFactory = {} as any;
|
||||
|
||||
api.registerEmbeddableFactory(embeddableFactoryId, embeddableFactory);
|
||||
expect(() => api.registerEmbeddableFactory(embeddableFactoryId, embeddableFactory)).toThrowError(
|
||||
setup.registerEmbeddableFactory(embeddableFactoryId, embeddableFactory);
|
||||
expect(() =>
|
||||
setup.registerEmbeddableFactory(embeddableFactoryId, embeddableFactory)
|
||||
).toThrowError(
|
||||
'Embeddable factory [embeddableFactoryId = ID] already registered in Embeddables API.'
|
||||
);
|
||||
});
|
|
@ -16,45 +16,78 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { UiActionsSetup } from 'src/plugins/ui_actions/public';
|
||||
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../core/public';
|
||||
import { EmbeddableFactoryRegistry } from './types';
|
||||
import { createApi, EmbeddableApi } from './api';
|
||||
import { bootstrap } from './bootstrap';
|
||||
import { EmbeddableFactory, EmbeddableInput, EmbeddableOutput } from './lib';
|
||||
|
||||
export interface IEmbeddableSetupDependencies {
|
||||
export interface EmbeddableSetupDependencies {
|
||||
uiActions: UiActionsSetup;
|
||||
}
|
||||
|
||||
export interface IEmbeddableSetup {
|
||||
registerEmbeddableFactory: EmbeddableApi['registerEmbeddableFactory'];
|
||||
export interface EmbeddableSetup {
|
||||
registerEmbeddableFactory: <I extends EmbeddableInput, O extends EmbeddableOutput>(
|
||||
id: string,
|
||||
factory: EmbeddableFactory<I, O>
|
||||
) => void;
|
||||
}
|
||||
export interface EmbeddableStart {
|
||||
getEmbeddableFactory: <
|
||||
I extends EmbeddableInput = EmbeddableInput,
|
||||
O extends EmbeddableOutput = EmbeddableOutput
|
||||
>(
|
||||
embeddableFactoryId: string
|
||||
) => EmbeddableFactory<I, O> | undefined;
|
||||
getEmbeddableFactories: () => IterableIterator<EmbeddableFactory>;
|
||||
}
|
||||
|
||||
export type IEmbeddableStart = EmbeddableApi;
|
||||
|
||||
export class EmbeddablePublicPlugin implements Plugin<IEmbeddableSetup, IEmbeddableStart> {
|
||||
export class EmbeddablePublicPlugin implements Plugin<EmbeddableSetup, EmbeddableStart> {
|
||||
private readonly embeddableFactories: EmbeddableFactoryRegistry = new Map();
|
||||
private api!: EmbeddableApi;
|
||||
|
||||
constructor(initializerContext: PluginInitializerContext) {}
|
||||
|
||||
public setup(core: CoreSetup, { uiActions }: IEmbeddableSetupDependencies) {
|
||||
({ api: this.api } = createApi({
|
||||
embeddableFactories: this.embeddableFactories,
|
||||
}));
|
||||
public setup(core: CoreSetup, { uiActions }: EmbeddableSetupDependencies) {
|
||||
bootstrap(uiActions);
|
||||
|
||||
const { registerEmbeddableFactory } = this.api;
|
||||
|
||||
return {
|
||||
registerEmbeddableFactory,
|
||||
registerEmbeddableFactory: this.registerEmbeddableFactory,
|
||||
};
|
||||
}
|
||||
|
||||
public start(core: CoreStart) {
|
||||
return this.api;
|
||||
return {
|
||||
getEmbeddableFactory: this.getEmbeddableFactory,
|
||||
getEmbeddableFactories: () => this.embeddableFactories.values(),
|
||||
};
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
|
||||
private registerEmbeddableFactory = (embeddableFactoryId: string, factory: EmbeddableFactory) => {
|
||||
if (this.embeddableFactories.has(embeddableFactoryId)) {
|
||||
throw new Error(
|
||||
`Embeddable factory [embeddableFactoryId = ${embeddableFactoryId}] already registered in Embeddables API.`
|
||||
);
|
||||
}
|
||||
|
||||
this.embeddableFactories.set(embeddableFactoryId, factory);
|
||||
};
|
||||
|
||||
private getEmbeddableFactory = <
|
||||
I extends EmbeddableInput = EmbeddableInput,
|
||||
O extends EmbeddableOutput = EmbeddableOutput
|
||||
>(
|
||||
embeddableFactoryId: string
|
||||
) => {
|
||||
const factory = this.embeddableFactories.get(embeddableFactoryId);
|
||||
|
||||
if (!factory) {
|
||||
throw new Error(
|
||||
`Embeddable factory [embeddableFactoryId = ${embeddableFactoryId}] does not exist.`
|
||||
);
|
||||
}
|
||||
|
||||
return factory as EmbeddableFactory<I, O>;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -35,14 +35,14 @@ import { inspectorPluginMock } from 'src/plugins/inspector/public/mocks';
|
|||
import { esFilters } from '../../../../plugins/data/public';
|
||||
|
||||
test('ApplyFilterAction applies the filter to the root of the container tree', async () => {
|
||||
const { doStart } = testPlugin();
|
||||
const { doStart, setup } = testPlugin();
|
||||
const api = doStart();
|
||||
|
||||
const factory1 = new FilterableContainerFactory(api.getEmbeddableFactory);
|
||||
const factory2 = new FilterableEmbeddableFactory();
|
||||
|
||||
api.registerEmbeddableFactory(factory1.type, factory1);
|
||||
api.registerEmbeddableFactory(factory2.type, factory2);
|
||||
setup.registerEmbeddableFactory(factory1.type, factory1);
|
||||
setup.registerEmbeddableFactory(factory2.type, factory2);
|
||||
|
||||
const applyFilterAction = createFilterAction();
|
||||
|
||||
|
@ -93,7 +93,7 @@ test('ApplyFilterAction applies the filter to the root of the container tree', a
|
|||
});
|
||||
|
||||
test('ApplyFilterAction is incompatible if the root container does not accept a filter as input', async () => {
|
||||
const { doStart, coreStart } = testPlugin();
|
||||
const { doStart, coreStart, setup } = testPlugin();
|
||||
const api = doStart();
|
||||
const inspector = inspectorPluginMock.createStartContract();
|
||||
|
||||
|
@ -112,7 +112,7 @@ test('ApplyFilterAction is incompatible if the root container does not accept a
|
|||
);
|
||||
|
||||
const factory = new FilterableEmbeddableFactory();
|
||||
api.registerEmbeddableFactory(factory.type, factory);
|
||||
setup.registerEmbeddableFactory(factory.type, factory);
|
||||
|
||||
const embeddable = await parent.addNewEmbeddable<
|
||||
FilterableContainerInput,
|
||||
|
@ -129,12 +129,12 @@ test('ApplyFilterAction is incompatible if the root container does not accept a
|
|||
});
|
||||
|
||||
test('trying to execute on incompatible context throws an error ', async () => {
|
||||
const { doStart, coreStart } = testPlugin();
|
||||
const { doStart, coreStart, setup } = testPlugin();
|
||||
const api = doStart();
|
||||
const inspector = inspectorPluginMock.createStartContract();
|
||||
|
||||
const factory = new FilterableEmbeddableFactory();
|
||||
api.registerEmbeddableFactory(factory.type, factory);
|
||||
setup.registerEmbeddableFactory(factory.type, factory);
|
||||
|
||||
const applyFilterAction = createFilterAction();
|
||||
const parent = new HelloWorldContainer(
|
||||
|
|
|
@ -562,7 +562,7 @@ test('Panel added to input state', async () => {
|
|||
test('Container changes made directly after adding a new embeddable are propagated', async done => {
|
||||
const coreSetup = coreMock.createSetup();
|
||||
const coreStart = coreMock.createStart();
|
||||
const { doStart, uiActions } = testPlugin(coreSetup, coreStart);
|
||||
const { setup, doStart, uiActions } = testPlugin(coreSetup, coreStart);
|
||||
const start = doStart();
|
||||
|
||||
const container = new HelloWorldContainer(
|
||||
|
@ -586,7 +586,7 @@ test('Container changes made directly after adding a new embeddable are propagat
|
|||
loadTickCount: 3,
|
||||
execAction: uiActions.executeTriggerActions,
|
||||
});
|
||||
start.registerEmbeddableFactory(factory.type, factory);
|
||||
setup.registerEmbeddableFactory(factory.type, factory);
|
||||
|
||||
const subscription = Rx.merge(container.getOutput$(), container.getInput$())
|
||||
.pipe(skip(2))
|
||||
|
@ -755,7 +755,7 @@ test('untilEmbeddableLoaded() resolves if child is loaded in the container', asy
|
|||
});
|
||||
|
||||
test('untilEmbeddableLoaded resolves with undefined if child is subsequently removed', async done => {
|
||||
const { doStart, coreStart, uiActions } = testPlugin(
|
||||
const { doStart, setup, coreStart, uiActions } = testPlugin(
|
||||
coreMock.createSetup(),
|
||||
coreMock.createStart()
|
||||
);
|
||||
|
@ -764,7 +764,7 @@ test('untilEmbeddableLoaded resolves with undefined if child is subsequently rem
|
|||
loadTickCount: 3,
|
||||
execAction: uiActions.executeTriggerActions,
|
||||
});
|
||||
start.registerEmbeddableFactory(factory.type, factory);
|
||||
setup.registerEmbeddableFactory(factory.type, factory);
|
||||
const container = new HelloWorldContainer(
|
||||
{
|
||||
id: 'hello',
|
||||
|
@ -795,7 +795,7 @@ test('untilEmbeddableLoaded resolves with undefined if child is subsequently rem
|
|||
});
|
||||
|
||||
test('adding a panel then subsequently removing it before its loaded removes the panel', async done => {
|
||||
const { doStart, coreStart, uiActions } = testPlugin(
|
||||
const { doStart, coreStart, uiActions, setup } = testPlugin(
|
||||
coreMock.createSetup(),
|
||||
coreMock.createStart()
|
||||
);
|
||||
|
@ -804,7 +804,7 @@ test('adding a panel then subsequently removing it before its loaded removes the
|
|||
loadTickCount: 1,
|
||||
execAction: uiActions.executeTriggerActions,
|
||||
});
|
||||
start.registerEmbeddableFactory(factory.type, factory);
|
||||
setup.registerEmbeddableFactory(factory.type, factory);
|
||||
const container = new HelloWorldContainer(
|
||||
{
|
||||
id: 'hello',
|
||||
|
|
|
@ -34,16 +34,16 @@ import { HelloWorldContainer } from '../lib/test_samples/embeddables/hello_world
|
|||
// eslint-disable-next-line
|
||||
import { coreMock } from '../../../../core/public/mocks';
|
||||
import { testPlugin } from './test_plugin';
|
||||
import { EmbeddableApi } from '../api';
|
||||
import { CustomizePanelModal } from '../lib/panel/panel_header/panel_actions/customize_title/customize_panel_modal';
|
||||
import { mount } from 'enzyme';
|
||||
import { EmbeddableStart } from '../plugin';
|
||||
|
||||
let api: EmbeddableApi;
|
||||
let api: EmbeddableStart;
|
||||
let container: Container;
|
||||
let embeddable: ContactCardEmbeddable;
|
||||
|
||||
beforeEach(async () => {
|
||||
const { doStart, coreStart, uiActions } = testPlugin(
|
||||
const { doStart, coreStart, uiActions, setup } = testPlugin(
|
||||
coreMock.createSetup(),
|
||||
coreMock.createStart()
|
||||
);
|
||||
|
@ -54,7 +54,7 @@ beforeEach(async () => {
|
|||
uiActions.executeTriggerActions,
|
||||
{} as any
|
||||
);
|
||||
api.registerEmbeddableFactory(contactCardFactory.type, contactCardFactory);
|
||||
setup.registerEmbeddableFactory(contactCardFactory.type, contactCardFactory);
|
||||
|
||||
container = new HelloWorldContainer(
|
||||
{ id: '123', panels: {} },
|
||||
|
|
|
@ -22,14 +22,14 @@ import { CoreSetup, CoreStart } from 'src/core/public';
|
|||
import { uiActionsPluginMock } from 'src/plugins/ui_actions/public/mocks';
|
||||
import { UiActionsStart } from 'src/plugins/ui_actions/public';
|
||||
import { coreMock } from '../../../../core/public/mocks';
|
||||
import { EmbeddablePublicPlugin, IEmbeddableSetup, IEmbeddableStart } from '../plugin';
|
||||
import { EmbeddablePublicPlugin, EmbeddableSetup, EmbeddableStart } from '../plugin';
|
||||
|
||||
export interface TestPluginReturn {
|
||||
plugin: EmbeddablePublicPlugin;
|
||||
coreSetup: CoreSetup;
|
||||
coreStart: CoreStart;
|
||||
setup: IEmbeddableSetup;
|
||||
doStart: (anotherCoreStart?: CoreStart) => IEmbeddableStart;
|
||||
setup: EmbeddableSetup;
|
||||
doStart: (anotherCoreStart?: CoreStart) => EmbeddableStart;
|
||||
uiActions: UiActionsStart;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,18 +19,15 @@
|
|||
import { EuiTab } from '@elastic/eui';
|
||||
import React, { Component } from 'react';
|
||||
import { CoreStart } from 'src/core/public';
|
||||
import {
|
||||
GetEmbeddableFactory,
|
||||
GetEmbeddableFactories,
|
||||
} from 'src/legacy/core_plugins/embeddable_api/public/np_ready/public';
|
||||
import { EmbeddableStart } from 'src/plugins/embeddable/public';
|
||||
import { UiActionsService } from '../../../../../../../../src/plugins/ui_actions/public';
|
||||
import { DashboardContainerExample } from './dashboard_container_example';
|
||||
import { Start as InspectorStartContract } from '../../../../../../../../src/plugins/inspector/public';
|
||||
|
||||
export interface AppProps {
|
||||
getActions: UiActionsService['getTriggerCompatibleActions'];
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getAllEmbeddableFactories: GetEmbeddableFactories;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
overlays: CoreStart['overlays'];
|
||||
notifications: CoreStart['notifications'];
|
||||
inspector: InspectorStartContract;
|
||||
|
|
|
@ -18,18 +18,19 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { EuiButton, EuiLoadingChart } from '@elastic/eui';
|
||||
import { ContainerOutput } from 'src/plugins/embeddable/public';
|
||||
import {
|
||||
ErrorEmbeddable,
|
||||
ViewMode,
|
||||
isErrorEmbeddable,
|
||||
EmbeddablePanel,
|
||||
GetEmbeddableFactory,
|
||||
GetEmbeddableFactories,
|
||||
EmbeddableStart,
|
||||
} from '../embeddable_api';
|
||||
import {
|
||||
DASHBOARD_CONTAINER_TYPE,
|
||||
DashboardContainer,
|
||||
DashboardContainerFactory,
|
||||
DashboardContainerInput,
|
||||
} from '../../../../../../../../src/plugins/dashboard/public';
|
||||
|
||||
import { CoreStart } from '../../../../../../../../src/core/public';
|
||||
|
@ -39,8 +40,8 @@ import { UiActionsService } from '../../../../../../../../src/plugins/ui_actions
|
|||
|
||||
interface Props {
|
||||
getActions: UiActionsService['getTriggerCompatibleActions'];
|
||||
getEmbeddableFactory: GetEmbeddableFactory;
|
||||
getAllEmbeddableFactories: GetEmbeddableFactories;
|
||||
getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'];
|
||||
getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories'];
|
||||
overlays: CoreStart['overlays'];
|
||||
notifications: CoreStart['notifications'];
|
||||
inspector: InspectorStartContract;
|
||||
|
@ -67,9 +68,10 @@ export class DashboardContainerExample extends React.Component<Props, State> {
|
|||
|
||||
public async componentDidMount() {
|
||||
this.mounted = true;
|
||||
const dashboardFactory = this.props.getEmbeddableFactory(
|
||||
DASHBOARD_CONTAINER_TYPE
|
||||
) as DashboardContainerFactory;
|
||||
const dashboardFactory = this.props.getEmbeddableFactory<
|
||||
DashboardContainerInput,
|
||||
ContainerOutput
|
||||
>(DASHBOARD_CONTAINER_TYPE) as DashboardContainerFactory;
|
||||
if (dashboardFactory) {
|
||||
this.container = await dashboardFactory.create(dashboardInput);
|
||||
if (this.mounted) {
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line
|
||||
import { npSetup } from '../../../../../../../../src/legacy/ui/public/new_platform';
|
||||
// eslint-disable-next-line
|
||||
import { HelloWorldEmbeddableFactory, HELLO_WORLD_EMBEDDABLE } from '../../../../../../../../examples/embeddable_examples/public';
|
||||
|
||||
npSetup.plugins.embeddable.registerEmbeddableFactory(
|
||||
HELLO_WORLD_EMBEDDABLE,
|
||||
new HelloWorldEmbeddableFactory()
|
||||
);
|
|
@ -31,21 +31,16 @@ import { CONTEXT_MENU_TRIGGER } from './embeddable_api';
|
|||
|
||||
const REACT_ROOT_ID = 'embeddableExplorerRoot';
|
||||
|
||||
import {
|
||||
SayHelloAction,
|
||||
createSendMessageAction,
|
||||
ContactCardEmbeddableFactory,
|
||||
} from './embeddable_api';
|
||||
import { SayHelloAction, createSendMessageAction } from './embeddable_api';
|
||||
import { App } from './app';
|
||||
import { getSavedObjectFinder } from '../../../../../../../src/plugins/saved_objects/public';
|
||||
import { HelloWorldEmbeddableFactory } from '../../../../../../../examples/embeddable_examples/public';
|
||||
import {
|
||||
IEmbeddableStart,
|
||||
IEmbeddableSetup,
|
||||
EmbeddableStart,
|
||||
EmbeddableSetup,
|
||||
} from '.../../../../../../../src/plugins/embeddable/public';
|
||||
|
||||
export interface SetupDependencies {
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
inspector: InspectorSetupContract;
|
||||
__LEGACY: {
|
||||
ExitFullScreenButton: React.ComponentType<any>;
|
||||
|
@ -53,7 +48,7 @@ export interface SetupDependencies {
|
|||
}
|
||||
|
||||
interface StartDependencies {
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
uiActions: UiActionsStart;
|
||||
inspector: InspectorStartContract;
|
||||
__LEGACY: {
|
||||
|
@ -74,12 +69,6 @@ export class EmbeddableExplorerPublicPlugin
|
|||
const helloWorldAction = createHelloWorldAction(core.overlays);
|
||||
const sayHelloAction = new SayHelloAction(alert);
|
||||
const sendMessageAction = createSendMessageAction(core.overlays);
|
||||
const helloWorldEmbeddableFactory = new HelloWorldEmbeddableFactory();
|
||||
const contactCardEmbeddableFactory = new ContactCardEmbeddableFactory(
|
||||
{},
|
||||
plugins.uiActions.executeTriggerActions,
|
||||
core.overlays
|
||||
);
|
||||
|
||||
plugins.uiActions.registerAction(helloWorldAction);
|
||||
plugins.uiActions.registerAction(sayHelloAction);
|
||||
|
@ -87,15 +76,6 @@ export class EmbeddableExplorerPublicPlugin
|
|||
|
||||
plugins.uiActions.attachAction(CONTEXT_MENU_TRIGGER, helloWorldAction);
|
||||
|
||||
plugins.embeddable.registerEmbeddableFactory(
|
||||
helloWorldEmbeddableFactory.type,
|
||||
helloWorldEmbeddableFactory
|
||||
);
|
||||
plugins.embeddable.registerEmbeddableFactory(
|
||||
contactCardEmbeddableFactory.type,
|
||||
contactCardEmbeddableFactory
|
||||
);
|
||||
|
||||
plugins.__LEGACY.onRenderComplete(() => {
|
||||
const root = document.getElementById(REACT_ROOT_ID);
|
||||
ReactDOM.render(
|
||||
|
|
|
@ -17,11 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
export default function({ getService }) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const retry = getService('retry');
|
||||
const pieChart = getService('pieChart');
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
|
||||
|
@ -30,17 +27,6 @@ export default function({ getService }) {
|
|||
await testSubjects.click('embedExplorerTab-dashboardContainer');
|
||||
});
|
||||
|
||||
it('hello world embeddable renders', async () => {
|
||||
await retry.try(async () => {
|
||||
const text = await testSubjects.getVisibleText('helloWorldEmbeddable');
|
||||
expect(text).to.be('HELLO WORLD!');
|
||||
});
|
||||
});
|
||||
|
||||
it('contact card embeddable renders', async () => {
|
||||
await testSubjects.existOrFail('embeddablePanelHeading-HelloSue');
|
||||
});
|
||||
|
||||
it('pie charts', async () => {
|
||||
await pieChart.expectPieSliceCount(5);
|
||||
});
|
||||
|
|
|
@ -27,17 +27,19 @@ import { Embeddable } from './embeddable';
|
|||
import { SavedObjectIndexStore, DOC_TYPE } from '../../persistence';
|
||||
import { getEditPath } from '../../../../../../plugins/lens/common';
|
||||
|
||||
interface StartServices {
|
||||
timefilter: TimefilterContract;
|
||||
coreHttp: HttpSetup;
|
||||
capabilities: RecursiveReadonly<Capabilities>;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
expressionRenderer: ReactExpressionRendererType;
|
||||
indexPatternService: IndexPatternsContract;
|
||||
}
|
||||
|
||||
export class EmbeddableFactory extends AbstractEmbeddableFactory {
|
||||
type = DOC_TYPE;
|
||||
|
||||
constructor(
|
||||
private timefilter: TimefilterContract,
|
||||
private coreHttp: HttpSetup,
|
||||
private capabilities: RecursiveReadonly<Capabilities>,
|
||||
private savedObjectsClient: SavedObjectsClientContract,
|
||||
private expressionRenderer: ReactExpressionRendererType,
|
||||
private indexPatternService: IndexPatternsContract
|
||||
) {
|
||||
constructor(private getStartServices: () => Promise<StartServices>) {
|
||||
super({
|
||||
savedObjectMetaData: {
|
||||
name: i18n.translate('xpack.lens.lensSavedObjectLabel', {
|
||||
|
@ -49,8 +51,9 @@ export class EmbeddableFactory extends AbstractEmbeddableFactory {
|
|||
});
|
||||
}
|
||||
|
||||
public isEditable() {
|
||||
return this.capabilities.visualize.save as boolean;
|
||||
public async isEditable() {
|
||||
const { capabilities } = await this.getStartServices();
|
||||
return capabilities.visualize.save as boolean;
|
||||
}
|
||||
|
||||
canCreateNew() {
|
||||
|
@ -68,13 +71,20 @@ export class EmbeddableFactory extends AbstractEmbeddableFactory {
|
|||
input: Partial<EmbeddableInput> & { id: string },
|
||||
parent?: IContainer
|
||||
) {
|
||||
const store = new SavedObjectIndexStore(this.savedObjectsClient);
|
||||
const {
|
||||
savedObjectsClient,
|
||||
coreHttp,
|
||||
indexPatternService,
|
||||
timefilter,
|
||||
expressionRenderer,
|
||||
} = await this.getStartServices();
|
||||
const store = new SavedObjectIndexStore(savedObjectsClient);
|
||||
const savedVis = await store.load(savedObjectId);
|
||||
|
||||
const promises = savedVis.state.datasourceMetaData.filterableIndexPatterns.map(
|
||||
async ({ id }) => {
|
||||
try {
|
||||
return await this.indexPatternService.get(id);
|
||||
return await indexPatternService.get(id);
|
||||
} catch (error) {
|
||||
// Unable to load index pattern, ignore error as the index patterns are only used to
|
||||
// configure the filter and query bar - there is still a good chance to get the visualization
|
||||
|
@ -90,12 +100,12 @@ export class EmbeddableFactory extends AbstractEmbeddableFactory {
|
|||
);
|
||||
|
||||
return new Embeddable(
|
||||
this.timefilter,
|
||||
this.expressionRenderer,
|
||||
timefilter,
|
||||
expressionRenderer,
|
||||
{
|
||||
savedVis,
|
||||
editUrl: this.coreHttp.basePath.prepend(getEditPath(savedObjectId)),
|
||||
editable: this.isEditable(),
|
||||
editUrl: coreHttp.basePath.prepend(getEditPath(savedObjectId)),
|
||||
editable: await this.isEditable(),
|
||||
indexPatterns,
|
||||
},
|
||||
input,
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
createMockSetupDependencies,
|
||||
createMockStartDependencies,
|
||||
} from './mocks';
|
||||
import { CoreSetup } from 'kibana/public';
|
||||
|
||||
jest.mock('ui/new_platform');
|
||||
|
||||
|
@ -41,7 +42,10 @@ describe('editor_frame service', () => {
|
|||
it('should create an editor frame instance which mounts and unmounts', async () => {
|
||||
await expect(
|
||||
(async () => {
|
||||
pluginInstance.setup(coreMock.createSetup(), pluginSetupDependencies);
|
||||
pluginInstance.setup(
|
||||
coreMock.createSetup() as CoreSetup<MockedStartDependencies>,
|
||||
pluginSetupDependencies
|
||||
);
|
||||
const publicAPI = pluginInstance.start(coreMock.createStart(), pluginStartDependencies);
|
||||
const instance = await publicAPI.createInstance({});
|
||||
instance.mount(mountpoint, {
|
||||
|
@ -57,7 +61,10 @@ describe('editor_frame service', () => {
|
|||
});
|
||||
|
||||
it('should not have child nodes after unmount', async () => {
|
||||
pluginInstance.setup(coreMock.createSetup(), pluginSetupDependencies);
|
||||
pluginInstance.setup(
|
||||
coreMock.createSetup() as CoreSetup<MockedStartDependencies>,
|
||||
pluginSetupDependencies
|
||||
);
|
||||
const publicAPI = pluginInstance.start(coreMock.createStart(), pluginStartDependencies);
|
||||
const instance = await publicAPI.createInstance({});
|
||||
instance.mount(mountpoint, {
|
||||
|
|
|
@ -12,10 +12,7 @@ import {
|
|||
ExpressionsSetup,
|
||||
ExpressionsStart,
|
||||
} from '../../../../../../src/plugins/expressions/public';
|
||||
import {
|
||||
IEmbeddableSetup,
|
||||
IEmbeddableStart,
|
||||
} from '../../../../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableSetup, EmbeddableStart } from '../../../../../../src/plugins/embeddable/public';
|
||||
import {
|
||||
DataPublicPluginSetup,
|
||||
DataPublicPluginStart,
|
||||
|
@ -35,13 +32,13 @@ import { getActiveDatasourceIdFromDoc } from './editor_frame/state_management';
|
|||
|
||||
export interface EditorFrameSetupPlugins {
|
||||
data: DataPublicPluginSetup;
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
expressions: ExpressionsSetup;
|
||||
}
|
||||
|
||||
export interface EditorFrameStartPlugins {
|
||||
data: DataPublicPluginStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
expressions: ExpressionsStart;
|
||||
}
|
||||
|
||||
|
@ -63,10 +60,27 @@ export class EditorFrameService {
|
|||
private readonly datasources: Array<Datasource | Promise<Datasource>> = [];
|
||||
private readonly visualizations: Array<Visualization | Promise<Visualization>> = [];
|
||||
|
||||
public setup(core: CoreSetup, plugins: EditorFrameSetupPlugins): EditorFrameSetup {
|
||||
public setup(
|
||||
core: CoreSetup<EditorFrameStartPlugins>,
|
||||
plugins: EditorFrameSetupPlugins
|
||||
): EditorFrameSetup {
|
||||
plugins.expressions.registerFunction(() => mergeTables);
|
||||
plugins.expressions.registerFunction(() => formatColumn);
|
||||
|
||||
const getStartServices = async () => {
|
||||
const [coreStart, deps] = await core.getStartServices();
|
||||
return {
|
||||
capabilities: coreStart.application.capabilities,
|
||||
savedObjectsClient: coreStart.savedObjects.client,
|
||||
coreHttp: coreStart.http,
|
||||
timefilter: deps.data.query.timefilter.timefilter,
|
||||
expressionRenderer: deps.expressions.ReactExpressionRenderer,
|
||||
indexPatternService: deps.data.indexPatterns,
|
||||
};
|
||||
};
|
||||
|
||||
plugins.embeddable.registerEmbeddableFactory('lens', new EmbeddableFactory(getStartServices));
|
||||
|
||||
return {
|
||||
registerDatasource: datasource => {
|
||||
this.datasources.push(datasource as Datasource<unknown, unknown>);
|
||||
|
@ -78,18 +92,6 @@ export class EditorFrameService {
|
|||
}
|
||||
|
||||
public start(core: CoreStart, plugins: EditorFrameStartPlugins): EditorFrameStart {
|
||||
plugins.embeddable.registerEmbeddableFactory(
|
||||
'lens',
|
||||
new EmbeddableFactory(
|
||||
plugins.data.query.timefilter.timefilter,
|
||||
core.http,
|
||||
core.application.capabilities,
|
||||
core.savedObjects.client,
|
||||
plugins.expressions.ReactExpressionRenderer,
|
||||
plugins.data.indexPatterns
|
||||
)
|
||||
);
|
||||
|
||||
const createInstance = async (): Promise<EditorFrameInstance> => {
|
||||
let domElement: Element;
|
||||
const [resolvedDatasources, resolvedVisualizations] = await Promise.all([
|
||||
|
|
|
@ -36,7 +36,7 @@ import {
|
|||
getLensUrlFromDashboardAbsoluteUrl,
|
||||
} from '../../../../../src/legacy/core_plugins/kibana/public/dashboard/np_ready/url_helper';
|
||||
import { FormatFactory } from './legacy_imports';
|
||||
import { IEmbeddableSetup, IEmbeddableStart } from '../../../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableSetup, EmbeddableStart } from '../../../../../src/plugins/embeddable/public';
|
||||
import { EditorFrameStart } from './types';
|
||||
import { getLensAliasConfig } from './vis_type_alias';
|
||||
import { VisualizationsSetup } from './legacy_imports';
|
||||
|
@ -45,7 +45,7 @@ export interface LensPluginSetupDependencies {
|
|||
kibanaLegacy: KibanaLegacySetup;
|
||||
expressions: ExpressionsSetup;
|
||||
data: DataPublicPluginSetup;
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
__LEGACY: {
|
||||
formatFactory: FormatFactory;
|
||||
visualizations: VisualizationsSetup;
|
||||
|
@ -54,7 +54,7 @@ export interface LensPluginSetupDependencies {
|
|||
|
||||
export interface LensPluginStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
expressions: ExpressionsStart;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,18 +9,13 @@ import React from 'react';
|
|||
import { OutPortal, PortalNode } from 'react-reverse-portal';
|
||||
import minimatch from 'minimatch';
|
||||
import { ViewMode } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
|
||||
import {
|
||||
IndexPatternMapping,
|
||||
MapEmbeddable,
|
||||
RenderTooltipContentParams,
|
||||
SetQuery,
|
||||
EmbeddableApi,
|
||||
} from './types';
|
||||
import { IndexPatternMapping, MapEmbeddable, RenderTooltipContentParams, SetQuery } from './types';
|
||||
import { getLayerList } from './map_config';
|
||||
// @ts-ignore Missing type defs as maps moves to Typescript
|
||||
import { MAP_SAVED_OBJECT_TYPE } from '../../../../maps/common/constants';
|
||||
import * as i18n from './translations';
|
||||
import { Query, Filter } from '../../../../../../../src/plugins/data/public';
|
||||
import { EmbeddableStart } from '../../../../../../../src/plugins/embeddable/public';
|
||||
import { IndexPatternSavedObject } from '../../hooks/types';
|
||||
|
||||
/**
|
||||
|
@ -45,7 +40,7 @@ export const createEmbeddable = async (
|
|||
endDate: number,
|
||||
setQuery: SetQuery,
|
||||
portalNode: PortalNode,
|
||||
embeddableApi: EmbeddableApi
|
||||
embeddableApi: EmbeddableStart
|
||||
): Promise<MapEmbeddable> => {
|
||||
const factory = embeddableApi.getEmbeddableFactory(MAP_SAVED_OBJECT_TYPE);
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
EmbeddableInput,
|
||||
EmbeddableOutput,
|
||||
IEmbeddable,
|
||||
EmbeddableFactory,
|
||||
} from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';
|
||||
import { inputsModel } from '../../store/inputs';
|
||||
import { Query, Filter } from '../../../../../../../src/plugins/data/public';
|
||||
|
@ -85,8 +84,3 @@ export interface RenderTooltipContentParams {
|
|||
}
|
||||
|
||||
export type MapToolTipProps = Partial<RenderTooltipContentParams>;
|
||||
|
||||
export interface EmbeddableApi {
|
||||
getEmbeddableFactory: (embeddableFactoryId: string) => EmbeddableFactory;
|
||||
registerEmbeddableFactory: (id: string, factory: EmbeddableFactory) => void;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
} from '../../../../../src/core/public';
|
||||
import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public';
|
||||
import { DataPublicPluginStart } from '../../../../../src/plugins/data/public';
|
||||
import { IEmbeddableStart } from '../../../../../src/plugins/embeddable/public';
|
||||
import { EmbeddableStart } from '../../../../../src/plugins/embeddable/public';
|
||||
import { Start as NewsfeedStart } from '../../../../../src/plugins/newsfeed/public';
|
||||
import { Start as InspectorStart } from '../../../../../src/plugins/inspector/public';
|
||||
import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public';
|
||||
|
@ -37,7 +37,7 @@ export interface SetupPlugins {
|
|||
}
|
||||
export interface StartPlugins {
|
||||
data: DataPublicPluginStart;
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
inspector: InspectorStart;
|
||||
newsfeed?: NewsfeedStart;
|
||||
uiActions: UiActionsStart;
|
||||
|
|
|
@ -15,8 +15,8 @@ import { UiActionsStart, UiActionsSetup } from '../../../../src/plugins/ui_actio
|
|||
import {
|
||||
CONTEXT_MENU_TRIGGER,
|
||||
PANEL_BADGE_TRIGGER,
|
||||
IEmbeddableSetup,
|
||||
IEmbeddableStart,
|
||||
EmbeddableSetup,
|
||||
EmbeddableStart,
|
||||
} from '../../../../src/plugins/embeddable/public';
|
||||
import {
|
||||
CustomTimeRangeAction,
|
||||
|
@ -32,12 +32,12 @@ import {
|
|||
import { CommonlyUsedRange } from './types';
|
||||
|
||||
interface SetupDependencies {
|
||||
embeddable: IEmbeddableSetup; // Embeddable are needed because they register basic triggers/actions.
|
||||
embeddable: EmbeddableSetup; // Embeddable are needed because they register basic triggers/actions.
|
||||
uiActions: UiActionsSetup;
|
||||
}
|
||||
|
||||
interface StartDependencies {
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
uiActions: UiActionsStart;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
ContainerInput,
|
||||
Container,
|
||||
ContainerOutput,
|
||||
GetEmbeddableFactory,
|
||||
EmbeddableStart,
|
||||
} from '../../../../../src/plugins/embeddable/public';
|
||||
import { TimeRange } from '../../../../../src/plugins/data/public';
|
||||
|
||||
|
@ -37,7 +37,7 @@ export class TimeRangeContainer extends Container<
|
|||
public readonly type = TIME_RANGE_CONTAINER;
|
||||
constructor(
|
||||
initialInput: ContainerTimeRangeInput,
|
||||
getFactory: GetEmbeddableFactory,
|
||||
getFactory: EmbeddableStart['getEmbeddableFactory'],
|
||||
parent?: Container
|
||||
) {
|
||||
super(initialInput, { embeddableLoaded: {} }, getFactory, parent);
|
||||
|
|
|
@ -19,7 +19,7 @@ interface EmbeddableTimeRangeInput extends EmbeddableInput {
|
|||
export class TimeRangeEmbeddableFactory extends EmbeddableFactory<EmbeddableTimeRangeInput> {
|
||||
public readonly type = TIME_RANGE_EMBEDDABLE;
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import { ResolverEmbeddable } from './embeddable';
|
|||
export class ResolverEmbeddableFactory extends EmbeddableFactory {
|
||||
public readonly type = 'resolver';
|
||||
|
||||
public isEditable() {
|
||||
public async isEditable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { Plugin, CoreSetup, AppMountParameters, CoreStart } from 'kibana/public';
|
||||
import { IEmbeddableSetup } from 'src/plugins/embeddable/public';
|
||||
import { EmbeddableSetup } from 'src/plugins/embeddable/public';
|
||||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ResolverEmbeddableFactory } from './embeddables/resolver';
|
||||
|
@ -13,7 +13,7 @@ import { ResolverEmbeddableFactory } from './embeddables/resolver';
|
|||
export type EndpointPluginStart = void;
|
||||
export type EndpointPluginSetup = void;
|
||||
export interface EndpointPluginSetupDependencies {
|
||||
embeddable: IEmbeddableSetup;
|
||||
embeddable: EmbeddableSetup;
|
||||
data: DataPublicPluginStart;
|
||||
}
|
||||
export interface EndpointPluginStartDependencies {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
import { Plugin, CoreSetup } from 'kibana/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { IEmbeddable, IEmbeddableStart } from '../../../../../../src/plugins/embeddable/public';
|
||||
import { IEmbeddable, EmbeddableStart } from '../../../../../../src/plugins/embeddable/public';
|
||||
|
||||
export type ResolverTestPluginSetup = void;
|
||||
export type ResolverTestPluginStart = void;
|
||||
export interface ResolverTestPluginSetupDependencies {} // eslint-disable-line @typescript-eslint/no-empty-interface
|
||||
export interface ResolverTestPluginStartDependencies {
|
||||
embeddable: IEmbeddableStart;
|
||||
embeddable: EmbeddableStart;
|
||||
}
|
||||
|
||||
export class ResolverTestPlugin
|
||||
|
@ -41,7 +41,9 @@ export class ResolverTestPlugin
|
|||
(async () => {
|
||||
const [, { embeddable }] = await core.getStartServices();
|
||||
const factory = embeddable.getEmbeddableFactory('resolver');
|
||||
resolveEmbeddable!(factory.create({ id: 'test basic render' }));
|
||||
if (factory) {
|
||||
resolveEmbeddable!(factory.create({ id: 'test basic render' }));
|
||||
}
|
||||
})();
|
||||
|
||||
const { renderApp } = await import('./applications/resolver_test');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue