mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Discover] Remove Angular from doc viewer (#109368)
* Remove angular from doc viewer * Remove types * Remove plugin_functional for angular doc_view, since testing angular is no longer necessary
This commit is contained in:
parent
e733b6ae0d
commit
42527e4188
10 changed files with 4 additions and 220 deletions
|
@ -1052,8 +1052,7 @@
|
|||
"description": [],
|
||||
"signature": [
|
||||
"{ addDocView(docViewRaw: ComponentDocViewInput | ",
|
||||
"RenderDocViewInput",
|
||||
" | DirectiveDocViewInput | ",
|
||||
"RenderDocViewInput |",
|
||||
"DocViewInputFn",
|
||||
"): void; }"
|
||||
],
|
||||
|
@ -1391,4 +1390,4 @@
|
|||
],
|
||||
"objects": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { auto, IController } from 'angular';
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import angular, { ICompileService } from 'angular';
|
||||
import { DocViewRenderProps, AngularScope, AngularDirective } from './doc_views_types';
|
||||
import { DocViewerError } from '../components/doc_viewer/doc_viewer_render_error';
|
||||
|
||||
/**
|
||||
* Compiles and injects the give angular template into the given dom node
|
||||
* returns a function to cleanup the injected angular element
|
||||
*/
|
||||
export async function injectAngularElement(
|
||||
domNode: Element,
|
||||
template: string,
|
||||
scopeProps: DocViewRenderProps,
|
||||
Controller: IController,
|
||||
getInjector: () => Promise<auto.IInjectorService>
|
||||
): Promise<() => void> {
|
||||
const $injector = await getInjector();
|
||||
const rootScope: AngularScope = $injector.get('$rootScope');
|
||||
const $compile: ICompileService = $injector.get('$compile');
|
||||
const newScope = Object.assign(rootScope.$new(), scopeProps);
|
||||
|
||||
if (typeof Controller === 'function') {
|
||||
// when a controller is defined, expose the value it produces to the view as `$ctrl`
|
||||
// see: https://docs.angularjs.org/api/ng/provider/$compileProvider#component
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(newScope as any).$ctrl = $injector.instantiate(Controller, {
|
||||
$scope: newScope,
|
||||
});
|
||||
}
|
||||
|
||||
const $target = angular.element(domNode);
|
||||
const $element = angular.element(template);
|
||||
|
||||
newScope.$apply(() => {
|
||||
const linkFn = $compile($element);
|
||||
$target.empty().append($element);
|
||||
linkFn(newScope);
|
||||
});
|
||||
|
||||
return () => {
|
||||
newScope.$destroy();
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Converts a given legacy angular directive to a render function
|
||||
* for usage in a react component. Note that the rendering is async
|
||||
*/
|
||||
export function convertDirectiveToRenderFn(
|
||||
directive: AngularDirective,
|
||||
getInjector: () => Promise<auto.IInjectorService>
|
||||
) {
|
||||
return (domNode: Element, props: DocViewRenderProps) => {
|
||||
let rejected = false;
|
||||
|
||||
const cleanupFnPromise = injectAngularElement(
|
||||
domNode,
|
||||
directive.template,
|
||||
props,
|
||||
directive.controller,
|
||||
getInjector
|
||||
);
|
||||
cleanupFnPromise.catch((e) => {
|
||||
rejected = true;
|
||||
render(<DocViewerError error={e} />, domNode);
|
||||
});
|
||||
|
||||
return () => {
|
||||
if (!rejected) {
|
||||
// for cleanup
|
||||
// http://roubenmeschian.com/rubo/?p=51
|
||||
cleanupFnPromise.then((cleanup) => cleanup());
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
|
@ -6,33 +6,16 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { auto } from 'angular';
|
||||
import { convertDirectiveToRenderFn } from './doc_views_helpers';
|
||||
import { DocView, DocViewInput, ElasticSearchHit, DocViewInputFn } from './doc_views_types';
|
||||
|
||||
export class DocViewsRegistry {
|
||||
private docViews: DocView[] = [];
|
||||
private angularInjectorGetter: (() => Promise<auto.IInjectorService>) | null = null;
|
||||
|
||||
setAngularInjectorGetter = (injectorGetter: () => Promise<auto.IInjectorService>) => {
|
||||
this.angularInjectorGetter = injectorGetter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extends and adds the given doc view to the registry array
|
||||
*/
|
||||
addDocView(docViewRaw: DocViewInput | DocViewInputFn) {
|
||||
const docView = typeof docViewRaw === 'function' ? docViewRaw() : docViewRaw;
|
||||
if (docView.directive) {
|
||||
// convert angular directive to render function for backwards compatibility
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(docView.render as any) = convertDirectiveToRenderFn(docView.directive as any, () => {
|
||||
if (!this.angularInjectorGetter) {
|
||||
throw new Error('Angular was not initialized');
|
||||
}
|
||||
return this.angularInjectorGetter();
|
||||
});
|
||||
}
|
||||
if (typeof docView.shouldShow !== 'function') {
|
||||
docView.shouldShow = () => true;
|
||||
}
|
||||
|
|
|
@ -7,17 +7,10 @@
|
|||
*/
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import { IScope } from 'angular';
|
||||
|
||||
import type { estypes } from '@elastic/elasticsearch';
|
||||
import { IndexPattern } from '../../../../data/public';
|
||||
|
||||
export interface AngularDirective {
|
||||
controller: (...injectedServices: unknown[]) => void;
|
||||
template: string;
|
||||
}
|
||||
|
||||
export type AngularScope = IScope;
|
||||
|
||||
export type ElasticSearchHit<T = unknown> = estypes.SearchHit<T>;
|
||||
|
||||
export interface FieldMapping {
|
||||
|
@ -67,13 +60,7 @@ interface ComponentDocViewInput extends BaseDocViewInput {
|
|||
directive?: undefined;
|
||||
}
|
||||
|
||||
interface DirectiveDocViewInput extends BaseDocViewInput {
|
||||
component?: undefined;
|
||||
render?: undefined;
|
||||
directive: ng.IDirective;
|
||||
}
|
||||
|
||||
export type DocViewInput = ComponentDocViewInput | RenderDocViewInput | DirectiveDocViewInput;
|
||||
export type DocViewInput = ComponentDocViewInput | RenderDocViewInput;
|
||||
|
||||
export type DocView = DocViewInput & {
|
||||
shouldShow: NonNullable<DocViewInput['shouldShow']>;
|
||||
|
|
|
@ -317,7 +317,6 @@ export class DiscoverPlugin
|
|||
stopUrlTracker();
|
||||
};
|
||||
|
||||
this.docViewsRegistry.setAngularInjectorGetter(this.getEmbeddableInjector);
|
||||
core.application.register({
|
||||
id: 'discover',
|
||||
title: 'Discover',
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"id": "docViewPlugin",
|
||||
"version": "0.0.1",
|
||||
"kibanaVersion": "kibana",
|
||||
"server": false,
|
||||
"ui": true,
|
||||
"requiredPlugins": ["discover"]
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"name": "docViewPlugin",
|
||||
"version": "1.0.0",
|
||||
"main": "target/test/plugin_functional/plugins/doc_views_plugin",
|
||||
"kibana": {
|
||||
"version": "kibana",
|
||||
"templateVersion": "1.0.0"
|
||||
},
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0",
|
||||
"scripts": {
|
||||
"kbn": "node ../../../../scripts/kbn.js",
|
||||
"build": "rm -rf './target' && ../../../../node_modules/.bin/tsc"
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { DocViewsPlugin } from './plugin';
|
||||
|
||||
export const plugin = () => new DocViewsPlugin();
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import angular from 'angular';
|
||||
import React from 'react';
|
||||
import { Plugin, CoreSetup } from 'kibana/public';
|
||||
import { DiscoverSetup } from '../../../../../src/plugins/discover/public';
|
||||
|
||||
angular.module('myDocView', []).directive('myHit', () => ({
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
hit: '=hit',
|
||||
},
|
||||
template: '<h1 data-test-subj="angular-docview">{{hit._index}}</h1>',
|
||||
}));
|
||||
|
||||
function MyHit(props: { index: string }) {
|
||||
return <h1 data-test-subj="react-docview">{props.index}</h1>;
|
||||
}
|
||||
|
||||
export class DocViewsPlugin implements Plugin<void, void> {
|
||||
public setup(core: CoreSetup, { discover }: { discover: DiscoverSetup }) {
|
||||
discover.docViews.addDocView({
|
||||
directive: {
|
||||
controller: function MyController($injector: any) {
|
||||
$injector.loadNewModules(['myDocView']);
|
||||
},
|
||||
template: `<my-hit hit="hit"></my-hit>`,
|
||||
},
|
||||
order: 1,
|
||||
title: 'Angular doc view',
|
||||
});
|
||||
|
||||
discover.docViews.addDocView({
|
||||
component: (props) => {
|
||||
return <MyHit index={props.hit._index as string} />;
|
||||
},
|
||||
order: 2,
|
||||
title: 'React doc view',
|
||||
});
|
||||
}
|
||||
|
||||
public start() {}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./target/types"
|
||||
},
|
||||
"include": [
|
||||
"index.ts",
|
||||
"public/**/*.ts",
|
||||
"public/**/*.tsx",
|
||||
"../../../../typings/**/*"
|
||||
],
|
||||
"exclude": [],
|
||||
"references": [
|
||||
{ "path": "../../../../src/core/tsconfig.json" },
|
||||
{ "path": "../../../../src/plugins/discover/tsconfig.json" },
|
||||
]
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue