mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
* Typescriptify ui/embeddable folder * Allow ts modules from ui/public folders to be imported * Address review comments from Tim * Address code review from Oleg * remove lodash usage * remove mappng to non public folder
This commit is contained in:
parent
4d7229ba17
commit
d131af8da8
11 changed files with 187 additions and 117 deletions
|
@ -84,6 +84,7 @@
|
|||
"@kbn/pm": "link:packages/kbn-pm",
|
||||
"@kbn/test-subj-selector": "link:packages/kbn-test-subj-selector",
|
||||
"@kbn/ui-framework": "link:packages/kbn-ui-framework",
|
||||
"@types/prop-types": "^15.5.3",
|
||||
"JSONStream": "1.1.1",
|
||||
"accept-language-parser": "1.2.0",
|
||||
"angular": "1.6.9",
|
||||
|
|
|
@ -24,22 +24,19 @@ import * as columnActions from 'ui/doc_table/actions/columns';
|
|||
|
||||
export class SearchEmbeddable extends Embeddable {
|
||||
constructor({ onEmbeddableStateChanged, savedSearch, editUrl, loader, $rootScope, $compile }) {
|
||||
super();
|
||||
super({
|
||||
metadata: {
|
||||
title: savedSearch.title,
|
||||
editUrl,
|
||||
indexPattern: savedSearch.searchSource.get('index')
|
||||
}
|
||||
});
|
||||
this.onEmbeddableStateChanged = onEmbeddableStateChanged;
|
||||
this.savedSearch = savedSearch;
|
||||
this.loader = loader;
|
||||
this.$rootScope = $rootScope;
|
||||
this.$compile = $compile;
|
||||
this.customization = {};
|
||||
|
||||
/**
|
||||
* @type {EmbeddableMetadata}
|
||||
*/
|
||||
this.metadata = {
|
||||
title: savedSearch.title,
|
||||
editUrl,
|
||||
indexPattern: this.savedSearch.searchSource.get('index'),
|
||||
};
|
||||
}
|
||||
|
||||
emitEmbeddableStateChange(embeddableState) {
|
||||
|
|
|
@ -24,7 +24,13 @@ import _ from 'lodash';
|
|||
|
||||
export class VisualizeEmbeddable extends Embeddable {
|
||||
constructor({ onEmbeddableStateChanged, savedVisualization, editUrl, loader }) {
|
||||
super();
|
||||
super({
|
||||
metadata: {
|
||||
title: savedVisualization.title,
|
||||
editUrl,
|
||||
indexPattern: savedVisualization.vis.indexPattern
|
||||
}
|
||||
});
|
||||
this._onEmbeddableStateChanged = onEmbeddableStateChanged;
|
||||
this.savedVisualization = savedVisualization;
|
||||
this.loader = loader;
|
||||
|
@ -33,15 +39,6 @@ export class VisualizeEmbeddable extends Embeddable {
|
|||
this.uiState = new PersistedState(parsedUiState);
|
||||
|
||||
this.uiState.on('change', this._uiStateChangeHandler);
|
||||
|
||||
/**
|
||||
* @type {EmbeddableMetadata}
|
||||
*/
|
||||
this.metadata = {
|
||||
title: savedVisualization.title,
|
||||
editUrl,
|
||||
indexPattern: this.savedVisualization.vis.indexPattern
|
||||
};
|
||||
}
|
||||
|
||||
_uiStateChangeHandler = () => {
|
||||
|
|
|
@ -1,76 +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 { PropTypes } from 'prop-types';
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbeddableMetadata - data that does not change over the course of the embeddables life span.
|
||||
* @property {string} title
|
||||
* @property {string|undefined} editUrl
|
||||
* @property {IndexPattern} indexPattern
|
||||
*/
|
||||
|
||||
export const embeddableShape = PropTypes.shape({
|
||||
metadata: PropTypes.object.isRequired,
|
||||
onContainerStateChanged: PropTypes.func.isRequired,
|
||||
render: PropTypes.func.isRequired,
|
||||
destroy: PropTypes.func.isRequired,
|
||||
});
|
||||
|
||||
export class Embeddable {
|
||||
/**
|
||||
*
|
||||
* @param {Object|undefined} config
|
||||
* @param {EmbeddableMetadata|undefined} config.metadata optional metadata
|
||||
* @param {function|undefined} config.render optional render method
|
||||
* @param {function|undefined} config.destroy optional destroy method
|
||||
* @param {function|undefined} config.onContainerStateChanged optional onContainerStateChanged method
|
||||
*/
|
||||
constructor(config = {}) {
|
||||
/**
|
||||
* @type {EmbeddableMetadata}
|
||||
*/
|
||||
this.metadata = config.metadata || {};
|
||||
|
||||
if (config.render) {
|
||||
this.render = config.render;
|
||||
}
|
||||
|
||||
if (config.destroy) {
|
||||
this.destroy = config.destroy;
|
||||
}
|
||||
|
||||
if (config.onContainerStateChanged) {
|
||||
this.onContainerStateChanged = config.onContainerStateChanged;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ContainerState} containerState
|
||||
*/
|
||||
onContainerStateChanged(/*containerState*/) {}
|
||||
|
||||
/**
|
||||
* @param {Element} domNode - the dom node to mount the rendered embeddable on
|
||||
* @param {ContainerState} containerState
|
||||
*/
|
||||
render(/*domNode, containerState*/) {}
|
||||
|
||||
destroy() {}
|
||||
}
|
95
src/ui/public/embeddable/embeddable.ts
Normal file
95
src/ui/public/embeddable/embeddable.ts
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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 * as PropTypes from 'prop-types';
|
||||
import { ContainerState } from './types';
|
||||
|
||||
// TODO: we'll be able to get rid of this shape once all of dashboard is typescriptified too.
|
||||
export const embeddableShape = PropTypes.shape({
|
||||
destroy: PropTypes.func.isRequired,
|
||||
metadata: PropTypes.object.isRequired,
|
||||
onContainerStateChanged: PropTypes.func.isRequired,
|
||||
render: PropTypes.func.isRequired,
|
||||
});
|
||||
|
||||
interface EmbeddableMetadata {
|
||||
// TODO: change to an array, embeddables should be able to specify multiple index patterns they use. Also
|
||||
// see https://github.com/elastic/kibana/issues/19408 - this needs to be generalized to support embeddables that
|
||||
// use dynamic index patterns (vega, TSVB) instead of saved object index patterns (most other visualizations).
|
||||
/**
|
||||
* Should specify any index pattern the embeddable uses. This will be used by the container to list out
|
||||
* available fields to filter on.
|
||||
*/
|
||||
indexPattern?: object;
|
||||
|
||||
/**
|
||||
* The title, or name, of the embeddable.
|
||||
*/
|
||||
title?: string;
|
||||
|
||||
/**
|
||||
* A url to direct the user for managing the embeddable instance. We may want to eventually make this optional
|
||||
* for non-instanced panels that can only be created and deleted but not edited. We also wish to eventually support
|
||||
* in-place editing on the dashboard itself, so another option could be to supply an element, or fly out panel, to
|
||||
* offer for editing directly on the dashboard.
|
||||
*/
|
||||
editUrl?: string;
|
||||
}
|
||||
|
||||
interface EmbeddableOptions {
|
||||
metadata?: EmbeddableMetadata;
|
||||
render?: (domNode: HTMLElement, containerState: ContainerState) => void;
|
||||
destroy?: () => void;
|
||||
onContainerStateChanged?: (containerState: ContainerState) => void;
|
||||
}
|
||||
|
||||
export abstract class Embeddable {
|
||||
public readonly metadata: EmbeddableMetadata = {};
|
||||
|
||||
// TODO: Make title and editUrl required and move out of options parameter.
|
||||
constructor(options: EmbeddableOptions = {}) {
|
||||
this.metadata = options.metadata || {};
|
||||
|
||||
if (options.render) {
|
||||
this.render = options.render;
|
||||
}
|
||||
|
||||
if (options.destroy) {
|
||||
this.destroy = options.destroy;
|
||||
}
|
||||
|
||||
if (options.onContainerStateChanged) {
|
||||
this.onContainerStateChanged = options.onContainerStateChanged;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract onContainerStateChanged(containerState: ContainerState): void;
|
||||
|
||||
/**
|
||||
* Embeddable should render itself at the given domNode.
|
||||
*/
|
||||
public abstract render(
|
||||
domNode: HTMLElement,
|
||||
containerState: ContainerState
|
||||
): void;
|
||||
|
||||
public destroy(): void {
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -17,13 +17,13 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
// @ts-ignore: implicit any for JS file
|
||||
import { uiRegistry } from '../registry/_registry';
|
||||
|
||||
/**
|
||||
* Registry of functions (EmbeddableFactoryProviders) which return an EmbeddableFactory.
|
||||
*/
|
||||
export const EmbeddableFactoriesRegistryProvider = uiRegistry({
|
||||
index: ['name'],
|
||||
name: 'embeddableFactories',
|
||||
index: ['name']
|
||||
});
|
||||
|
|
@ -17,33 +17,24 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} EmbeddableState
|
||||
* @property {Object} customization - any customization data that should be stored at the panel level. For
|
||||
* example, pie slice colors, or custom per panel sort order or columns.
|
||||
* @property {Object} stagedFilter - a possible filter the embeddable wishes dashboard to apply.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @callback onEmbeddableStateChanged
|
||||
* @param {EmbeddableState} embeddableState
|
||||
*/
|
||||
import { Embeddable } from './embeddable';
|
||||
import { EmbeddableState } from './types';
|
||||
|
||||
/**
|
||||
* The EmbeddableFactory creates and initializes an embeddable instance
|
||||
*/
|
||||
export class EmbeddableFactory {
|
||||
export abstract class EmbeddableFactory {
|
||||
/**
|
||||
*
|
||||
* @param {Object} containerMetadata. Currently just passing in panelState but it's more than we need, so we should
|
||||
* @param {{ id: string }} containerMetadata. Currently just passing in panelState but it's more than we need, so we should
|
||||
* decouple this to only include data given to us from the embeddable when it's added to the dashboard. Generally
|
||||
* will be just the object id, but could be anything depending on the plugin.
|
||||
* @param {onEmbeddableStateChanged} onEmbeddableStateChanged - embeddable should call this function with updated
|
||||
* state whenever something changes that the dashboard should know about.
|
||||
* @return {Promise.<Embeddable>}
|
||||
*/
|
||||
create(/* containerMetadata, onEmbeddableStateChanged*/) {
|
||||
throw new Error('Must implement create.');
|
||||
}
|
||||
public abstract create(
|
||||
containerMetadata: { id: string },
|
||||
onEmbeddableStateChanged: (embeddableStateChanges: EmbeddableState) => void
|
||||
): Promise<Embeddable>;
|
||||
}
|
|
@ -19,4 +19,6 @@
|
|||
|
||||
export { EmbeddableFactory } from './embeddable_factory';
|
||||
export * from './embeddable';
|
||||
export { EmbeddableFactoriesRegistryProvider } from './embeddable_factories_registry';
|
||||
export {
|
||||
EmbeddableFactoriesRegistryProvider,
|
||||
} from './embeddable_factories_registry';
|
57
src/ui/public/embeddable/types.ts
Normal file
57
src/ui/public/embeddable/types.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export interface ContainerState {
|
||||
// 'view' or 'edit'. Should probably be an enum but I'm undecided where to define it, here or in dashboard code.
|
||||
viewMode: string;
|
||||
|
||||
timeRange: {
|
||||
// To and From should be either an absolute time range in utc format or a relative one (e.g. now-15m)
|
||||
to: string;
|
||||
from: string;
|
||||
};
|
||||
|
||||
// The shape will be up to the embeddable type.
|
||||
embeddableCustomization?: object;
|
||||
|
||||
/**
|
||||
* Whether or not panel titles are hidden. It is not the embeddable's responsibility to hide the title (the container
|
||||
* handles that). This information is currently only used to determine the title for reporting (data-sharing-title
|
||||
* attribute). If we move that out of the embeddables and push it to the container (as we probably should), then
|
||||
* we shouldn't need to expose this information.
|
||||
*/
|
||||
hidePanelTitles: boolean;
|
||||
|
||||
/**
|
||||
* Is the current panel in expanded mode
|
||||
*/
|
||||
isPanelExpanded: boolean;
|
||||
}
|
||||
|
||||
export interface EmbeddableState {
|
||||
/**
|
||||
* Any customization data that should be stored at the panel level. For
|
||||
* example, pie slice colors, or custom per panel sort order or columns.
|
||||
*/
|
||||
customization: object;
|
||||
/**
|
||||
* A possible filter the embeddable wishes dashboard to apply.
|
||||
*/
|
||||
stagedFilter: object;
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
|
||||
"paths": {
|
||||
"ui/*": ["src/ui/public/*"]
|
||||
},
|
||||
// Support .tsx files and transform JSX into calls to React.createElement
|
||||
"jsx": "react",
|
||||
|
||||
|
|
|
@ -324,6 +324,10 @@
|
|||
dependencies:
|
||||
"@types/retry" "*"
|
||||
|
||||
"@types/prop-types@^15.5.3":
|
||||
version "15.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.3.tgz#bef071852dca2a2dbb65fecdb7bfb30cedae2de2"
|
||||
|
||||
"@types/react-dom@^16.0.5":
|
||||
version "16.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.5.tgz#a757457662e3819409229e8f86795ff37b371f96"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue