Migrate vis_type_table to kibana/new platform (#63105)

* Move vis_type_table to Kibana Platform

* Adapt mocha tests
* Adapt CODEOWNERS

* Adapt SCSS
This commit is contained in:
Matthias Wilhelm 2020-04-21 09:49:48 +02:00 committed by GitHub
parent 46f6f8779e
commit 2f363ba144
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 354 additions and 323 deletions

1
.github/CODEOWNERS vendored
View file

@ -13,6 +13,7 @@
/src/legacy/core_plugins/kibana/public/dev_tools/ @elastic/kibana-app
/src/legacy/core_plugins/vis_type_vislib/ @elastic/kibana-app
/src/plugins/vis_type_xy/ @elastic/kibana-app
/src/plugins/vis_type_table/ @elastic/kibana-app
/src/plugins/kibana_legacy/ @elastic/kibana-app
/src/plugins/vis_type_timelion/ @elastic/kibana-app
/src/plugins/dashboard/ @elastic/kibana-app

View file

@ -48,7 +48,7 @@
"visDefaultEditor": "src/plugins/vis_default_editor",
"visTypeMarkdown": "src/plugins/vis_type_markdown",
"visTypeMetric": "src/plugins/vis_type_metric",
"visTypeTable": "src/legacy/core_plugins/vis_type_table",
"visTypeTable": "src/plugins/vis_type_table",
"visTypeTagCloud": "src/legacy/core_plugins/vis_type_tagcloud",
"visTypeTimeseries": ["src/legacy/core_plugins/vis_type_timeseries", "src/plugins/vis_type_timeseries"],
"visTypeVega": "src/legacy/core_plugins/vis_type_vega",

View file

@ -22,11 +22,18 @@ import moment from 'moment';
import ngMock from 'ng_mock';
import expect from '@kbn/expect';
import sinon from 'sinon';
import { npStart } from '../../legacy_imports';
import './legacy';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { npStart } from 'ui/new_platform';
import { round } from 'lodash';
import { getAngularModule } from '../../get_inner_angular';
import { initTableVisLegacyModule } from '../../table_vis_legacy_module';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { getInnerAngular } from '../../../../../../plugins/vis_type_table/public/get_inner_angular';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { initTableVisLegacyModule } from '../../../../../../plugins/vis_type_table/public/table_vis_legacy_module';
import { tabifiedData } from './tabified_data';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { configureAppAngularModule } from '../../../../../../plugins/kibana_legacy/public/angular';
describe('Table Vis - AggTable Directive', function() {
let $rootScope;
@ -34,7 +41,8 @@ describe('Table Vis - AggTable Directive', function() {
let settings;
const initLocalAngular = () => {
const tableVisModule = getAngularModule('kibana/table_vis', npStart.core);
const tableVisModule = getInnerAngular('kibana/table_vis', npStart.core);
configureAppAngularModule(tableVisModule, npStart.core, true);
initTableVisLegacyModule(tableVisModule);
};

View file

@ -20,17 +20,24 @@
import $ from 'jquery';
import ngMock from 'ng_mock';
import expect from '@kbn/expect';
import { npStart } from '../../legacy_imports';
import { getAngularModule } from '../../get_inner_angular';
import { initTableVisLegacyModule } from '../../table_vis_legacy_module';
import './legacy';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { getInnerAngular } from '../../../../../../plugins/vis_type_table/public/get_inner_angular';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { initTableVisLegacyModule } from '../../../../../../plugins/vis_type_table/public/table_vis_legacy_module';
import { tabifiedData } from './tabified_data';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { npStart } from 'ui/new_platform';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { configureAppAngularModule } from '../../../../../../plugins/kibana_legacy/public/angular';
describe('Table Vis - AggTableGroup Directive', function() {
let $rootScope;
let $compile;
const initLocalAngular = () => {
const tableVisModule = getAngularModule('kibana/table_vis', npStart.core);
const tableVisModule = getInnerAngular('kibana/table_vis', npStart.core);
configureAppAngularModule(tableVisModule, npStart.core, true);
initTableVisLegacyModule(tableVisModule);
};

View file

@ -16,19 +16,23 @@
* specific language governing permissions and limitations
* under the License.
*/
import { PluginInitializerContext } from 'kibana/public';
import { npSetup, npStart } from './legacy_imports';
import { plugin } from '.';
import { TablePluginSetupDependencies } from './plugin';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { npStart, npSetup } from 'ui/new_platform';
import {
TableVisPlugin,
TablePluginSetupDependencies,
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
} from '../../../../../../plugins/vis_type_table/public/plugin';
const plugins: Readonly<TablePluginSetupDependencies> = {
expressions: npSetup.plugins.expressions,
visualizations: npSetup.plugins.visualizations,
};
const pluginInstance = plugin({} as PluginInitializerContext);
const pluginInstance = new TableVisPlugin({} as PluginInitializerContext);
export const setup = pluginInstance.setup(npSetup.core, plugins);
export const start = pluginInstance.start(npStart.core, { data: npStart.plugins.data });
export const start = pluginInstance.start(npStart.core, {
data: npStart.plugins.data,
});

View file

@ -1,44 +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 { resolve } from 'path';
import { Legacy } from 'kibana';
import { LegacyPluginApi, LegacyPluginInitializer } from '../../../../src/legacy/types';
const tableVisPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) =>
new Plugin({
id: 'table_vis',
require: ['kibana', 'elasticsearch'],
publicDir: resolve(__dirname, 'public'),
uiExports: {
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
hacks: [resolve(__dirname, 'public/legacy')],
injectDefaultVars: server => ({}),
},
init: (server: Legacy.Server) => ({}),
config(Joi: any) {
return Joi.object({
enabled: Joi.boolean().default(true),
}).default();
},
} as Legacy.PluginSpecOptions);
// eslint-disable-next-line import/no-default-export
export default tableVisPluginInitializer;

View file

@ -1,4 +0,0 @@
{
"name": "table_vis",
"version": "kibana"
}

View file

@ -1 +0,0 @@
@import 'agg_table';

View file

@ -1 +0,0 @@
@import './table_cell_filter';

View file

@ -1,98 +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 { i18n } from '@kbn/i18n';
import { AggGroupNames } from '../../../../plugins/data/public';
import { Schemas } from '../../../../plugins/vis_default_editor/public';
import { Vis } from '../../../../plugins/visualizations/public';
import { tableVisResponseHandler } from './table_vis_response_handler';
// @ts-ignore
import tableVisTemplate from './table_vis.html';
import { TableOptions } from './components/table_vis_options';
import { TableVisualizationController } from './vis_controller';
export const tableVisTypeDefinition = {
type: 'table',
name: 'table',
title: i18n.translate('visTypeTable.tableVisTitle', {
defaultMessage: 'Data Table',
}),
icon: 'visTable',
description: i18n.translate('visTypeTable.tableVisDescription', {
defaultMessage: 'Display values in a table',
}),
visualization: TableVisualizationController,
visConfig: {
defaults: {
perPage: 10,
showPartialRows: false,
showMetricsAtAllLevels: false,
sort: {
columnIndex: null,
direction: null,
},
showTotal: false,
totalFunc: 'sum',
percentageCol: '',
},
template: tableVisTemplate,
},
editorConfig: {
optionsTemplate: TableOptions,
schemas: new Schemas([
{
group: AggGroupNames.Metrics,
name: 'metric',
title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.metricTitle', {
defaultMessage: 'Metric',
}),
aggFilter: ['!geo_centroid', '!geo_bounds'],
aggSettings: {
top_hits: {
allowStrings: true,
},
},
min: 1,
defaults: [{ type: 'count', schema: 'metric' }],
},
{
group: AggGroupNames.Buckets,
name: 'bucket',
title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.bucketTitle', {
defaultMessage: 'Split rows',
}),
aggFilter: ['!filter'],
},
{
group: AggGroupNames.Buckets,
name: 'split',
title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.splitTitle', {
defaultMessage: 'Split table',
}),
min: 0,
max: 1,
aggFilter: ['!filter'],
},
]),
},
responseHandler: tableVisResponseHandler,
hierarchicalData: (vis: Vis) => {
return Boolean(vis.params.showPartialRows || vis.params.showMetricsAtAllLevels);
},
};

View file

@ -1,104 +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 angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular';
import $ from 'jquery';
import { VisParams, ExprVis } from '../../../../plugins/visualizations/public';
import { npStart } from './legacy_imports';
import { getAngularModule } from './get_inner_angular';
import { initTableVisLegacyModule } from './table_vis_legacy_module';
const innerAngularName = 'kibana/table_vis';
export class TableVisualizationController {
private tableVisModule: IModule | undefined;
private injector: auto.IInjectorService | undefined;
el: JQuery<Element>;
vis: ExprVis;
$rootScope: IRootScopeService | null = null;
$scope: (IScope & { [key: string]: any }) | undefined;
$compile: ICompileService | undefined;
constructor(domeElement: Element, vis: ExprVis) {
this.el = $(domeElement);
this.vis = vis;
}
getInjector() {
if (!this.injector) {
const mountpoint = document.createElement('div');
mountpoint.setAttribute('style', 'height: 100%; width: 100%;');
this.injector = angular.bootstrap(mountpoint, [innerAngularName]);
this.el.append(mountpoint);
}
return this.injector;
}
initLocalAngular() {
if (!this.tableVisModule) {
this.tableVisModule = getAngularModule(innerAngularName, npStart.core);
initTableVisLegacyModule(this.tableVisModule);
}
}
async render(esResponse: object, visParams: VisParams) {
this.initLocalAngular();
return new Promise(async (resolve, reject) => {
if (!this.$rootScope) {
const $injector = this.getInjector();
this.$rootScope = $injector.get('$rootScope');
this.$compile = $injector.get('$compile');
}
const updateScope = () => {
if (!this.$scope) {
return;
}
this.$scope.vis = this.vis;
this.$scope.visState = { params: visParams };
this.$scope.esResponse = esResponse;
this.$scope.visParams = visParams;
this.$scope.renderComplete = resolve;
this.$scope.renderFailed = reject;
this.$scope.resize = Date.now();
this.$scope.$apply();
};
if (!this.$scope && this.$compile) {
this.$scope = this.$rootScope.$new();
this.$scope.uiState = this.vis.getUiState();
updateScope();
this.el.find('div').append(this.$compile(this.vis.type!.visConfig.template)(this.$scope));
this.$scope.$apply();
} else {
updateScope();
}
});
}
destroy() {
if (this.$rootScope) {
this.$rootScope.$destroy();
this.$rootScope = null;
}
}
}

View file

@ -92,9 +92,9 @@ export const configureAppAngularModule = (
) => {
const core = 'core' in newPlatform ? newPlatform.core : newPlatform;
const packageInfo =
'injectedMetadata' in newPlatform
? newPlatform.injectedMetadata.getLegacyMetadata()
: newPlatform.env.packageInfo;
'env' in newPlatform
? newPlatform.env.packageInfo
: newPlatform.injectedMetadata.getLegacyMetadata();
if ('injectedMetadata' in newPlatform) {
forOwn(newPlatform.injectedMetadata.getInjectedVars(), (val, name) => {

View file

@ -17,4 +17,10 @@
* under the License.
*/
export { npSetup, npStart } from 'ui/new_platform';
import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
});
export type ConfigSchema = TypeOf<typeof configSchema>;

View file

@ -0,0 +1,11 @@
{
"id": "visTypeTable",
"version": "kibana",
"server": true,
"ui": true,
"requiredPlugins": [
"expressions",
"visualizations",
"data"
]
}

View file

@ -0,0 +1 @@
@import './agg_table';

View file

@ -238,9 +238,9 @@ export function KbnAggTable(config, RecursionHelper) {
}
/**
* @param {[]Object} columns - the formatted columns that will be displayed
* @param {Object[]} columns - the formatted columns that will be displayed
* @param {String} title - the title of the column to add to
* @param {[]Object} rows - the row data for the columns
* @param {Object[]} rows - the row data for the columns
* @param {Number} insertAtIndex - the index to insert the percentage column at
* @returns {Object} - cols and rows for the table to render now included percentage column(s)
*/

View file

@ -24,12 +24,8 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
import { search } from '../../../../../plugins/data/public';
import {
SwitchOption,
SelectOption,
NumberInputOption,
} from '../../../../../plugins/charts/public';
import { search } from '../../../data/public';
import { SwitchOption, SelectOption, NumberInputOption } from '../../../charts/public';
import { TableVisParams } from '../types';
import { totalAggregations } from './utils';

View file

@ -23,7 +23,7 @@
import angular from 'angular';
import 'angular-recursion';
import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular';
import { CoreStart, LegacyCoreStart, IUiSettingsClient } from 'kibana/public';
import { CoreStart, IUiSettingsClient, PluginInitializerContext } from 'kibana/public';
import {
initAngularBootstrap,
PaginateDirectiveProvider,
@ -32,15 +32,15 @@ import {
watchMultiDecorator,
KbnAccessibleClickProvider,
configureAppAngularModule,
} from '../../../../plugins/kibana_legacy/public';
} from '../../kibana_legacy/public';
initAngularBootstrap();
const thirdPartyAngularDependencies = ['ngSanitize', 'ui.bootstrap', 'RecursionHelper'];
export function getAngularModule(name: string, core: CoreStart) {
export function getAngularModule(name: string, core: CoreStart, context: PluginInitializerContext) {
const uiModule = getInnerAngular(name, core);
configureAppAngularModule(uiModule, core as LegacyCoreStart, true);
configureAppAngularModule(uiModule, { core, env: context.env }, true);
return uiModule;
}

View file

@ -1,5 +1,3 @@
@import 'src/legacy/ui/public/styles/styling_constants';
// Prefix all styles with "tbv" to avoid conflicts.
// Examples
// tbvChart
@ -7,6 +5,6 @@
// tbvChart__legend--small
// tbvChart__legend-isLoading
@import 'agg_table/index';
@import 'paginated_table/index';
@import './agg_table/index';
@import './paginated_table/index';
@import './table_vis';

View file

@ -16,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
import { PluginInitializerContext } from '../../../../core/public';
import './index.scss';
import { PluginInitializerContext } from 'kibana/public';
import { TableVisPlugin as Plugin } from './plugin';
export function plugin(initializerContext: PluginInitializerContext) {

View file

@ -0,0 +1 @@
@import './_table_cell_filter';

View file

@ -25,10 +25,9 @@ import 'angular-mocks';
import { getAngularModule } from '../get_inner_angular';
import { initTableVisLegacyModule } from '../table_vis_legacy_module';
import { coreMock } from '../../../../../core/public/mocks';
import { coreMock } from '../../../../core/public/mocks';
jest.mock('ui/new_platform');
jest.mock('../../../../../plugins/kibana_legacy/public/angular/angular_config', () => ({
jest.mock('../../../kibana_legacy/public/angular/angular_config', () => ({
configureAppAngularModule: () => {},
}));
@ -73,7 +72,11 @@ describe('Table Vis - Paginated table', () => {
let paginatedTable: any;
const initLocalAngular = () => {
const tableVisModule = getAngularModule('kibana/table_vis', coreMock.createStart());
const tableVisModule = getAngularModule(
'kibana/table_vis',
coreMock.createStart(),
coreMock.createPluginInitializerContext()
);
initTableVisLegacyModule(tableVisModule);
};

View file

@ -16,14 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Plugin as ExpressionsPublicPlugin } from '../../../../plugins/expressions/public';
import { VisualizationsSetup } from '../../../../plugins/visualizations/public';
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../../core/public';
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'kibana/public';
import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public';
import { VisualizationsSetup } from '../../visualizations/public';
import { createTableVisFn } from './table_vis_fn';
import { tableVisTypeDefinition } from './table_vis_type';
import { DataPublicPluginStart } from '../../../../plugins/data/public';
import { getTableVisTypeDefinition } from './table_vis_type';
import { DataPublicPluginStart } from '../../data/public';
import { setFormatService } from './services';
/** @internal */
@ -40,6 +39,7 @@ export interface TablePluginStartDependencies {
/** @internal */
export class TableVisPlugin implements Plugin<Promise<void>, void> {
initializerContext: PluginInitializerContext;
createBaseVisualization: any;
constructor(initializerContext: PluginInitializerContext) {
this.initializerContext = initializerContext;
@ -50,8 +50,9 @@ export class TableVisPlugin implements Plugin<Promise<void>, void> {
{ expressions, visualizations }: TablePluginSetupDependencies
) {
expressions.registerFunction(createTableVisFn);
visualizations.createBaseVisualization(tableVisTypeDefinition);
visualizations.createBaseVisualization(
getTableVisTypeDefinition(core, this.initializerContext)
);
}
public start(core: CoreStart, { data }: TablePluginStartDependencies) {

View file

@ -17,8 +17,8 @@
* under the License.
*/
import { createGetterSetter } from '../../../../plugins/kibana_utils/public';
import { DataPublicPluginStart } from '../../../../plugins/data/public';
import { createGetterSetter } from '../../kibana_utils/public';
import { DataPublicPluginStart } from '../../data/public';
export const [getFormatService, setFormatService] = createGetterSetter<
DataPublicPluginStart['fieldFormats']

View file

@ -26,24 +26,23 @@ import $ from 'jquery';
import StubIndexPattern from 'test_utils/stub_index_pattern';
import { getAngularModule } from './get_inner_angular';
import { initTableVisLegacyModule } from './table_vis_legacy_module';
import { tableVisTypeDefinition } from './table_vis_type';
import { Vis } from '../../../../plugins/visualizations/public';
import { getTableVisTypeDefinition } from './table_vis_type';
import { Vis } from '../../visualizations/public';
// eslint-disable-next-line
import { stubFields } from '../../../../plugins/data/public/stubs';
import { stubFields } from '../../data/public/stubs';
// eslint-disable-next-line
import { tableVisResponseHandler } from './table_vis_response_handler';
import { coreMock } from '../../../../core/public/mocks';
import { coreMock } from '../../../core/public/mocks';
import { IAggConfig, search } from '../../data/public';
// TODO: remove linting disable
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { npStart } from './legacy_imports';
import { IAggConfig, search } from '../../../../plugins/data/public';
import { searchStartMock } from '../../data/public/search/mocks';
// should be mocked once get rid of 'ui/new_platform' legacy imports
const { createAggConfigs } = npStart.plugins.data.search.aggs;
const { createAggConfigs } = searchStartMock.aggs;
const { tabifyAggResponse } = search;
jest.mock('ui/new_platform');
jest.mock('../../../../plugins/kibana_legacy/public/angular/angular_config', () => ({
jest.mock('../../kibana_legacy/public/angular/angular_config', () => ({
configureAppAngularModule: () => {},
}));
@ -89,7 +88,11 @@ describe('Table Vis - Controller', () => {
let stubIndexPattern: any;
const initLocalAngular = () => {
const tableVisModule = getAngularModule('kibana/table_vis', coreMock.createStart());
const tableVisModule = getAngularModule(
'kibana/table_vis',
coreMock.createStart(),
coreMock.createPluginInitializerContext()
);
initTableVisLegacyModule(tableVisModule);
};
@ -110,9 +113,13 @@ describe('Table Vis - Controller', () => {
(cfg: any) => cfg,
'time',
stubFields,
coreMock.createStart()
coreMock.createSetup()
);
});
const tableVisTypeDefinition = getTableVisTypeDefinition(
coreMock.createSetup(),
coreMock.createPluginInitializerContext()
);
function getRangeVis(params?: object) {
return ({

View file

@ -21,7 +21,7 @@ import { createTableVisFn } from './table_vis_fn';
import { tableVisResponseHandler } from './table_vis_response_handler';
// eslint-disable-next-line
import { functionWrapper } from '../../../../plugins/expressions/common/expression_functions/specs/tests/utils';
import { functionWrapper } from '../../expressions/common/expression_functions/specs/tests/utils';
jest.mock('./table_vis_response_handler', () => ({
tableVisResponseHandler: jest.fn().mockReturnValue({

View file

@ -19,11 +19,7 @@
import { i18n } from '@kbn/i18n';
import { tableVisResponseHandler, TableContext } from './table_vis_response_handler';
import {
ExpressionFunctionDefinition,
KibanaDatatable,
Render,
} from '../../../../plugins/expressions/public';
import { ExpressionFunctionDefinition, KibanaDatatable, Render } from '../../expressions/public';
export type Input = KibanaDatatable;

View file

@ -0,0 +1,100 @@
/*
* 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 { CoreSetup, PluginInitializerContext } from 'kibana/public';
import { i18n } from '@kbn/i18n';
import { AggGroupNames } from '../../data/public';
import { Schemas } from '../../vis_default_editor/public';
import { Vis } from '../../visualizations/public';
import { tableVisResponseHandler } from './table_vis_response_handler';
// @ts-ignore
import tableVisTemplate from './table_vis.html';
import { TableOptions } from './components/table_vis_options';
import { getTableVisualizationControllerClass } from './vis_controller';
export function getTableVisTypeDefinition(core: CoreSetup, context: PluginInitializerContext) {
return {
type: 'table',
name: 'table',
title: i18n.translate('visTypeTable.tableVisTitle', {
defaultMessage: 'Data Table',
}),
icon: 'visTable',
description: i18n.translate('visTypeTable.tableVisDescription', {
defaultMessage: 'Display values in a table',
}),
visualization: getTableVisualizationControllerClass(core, context),
visConfig: {
defaults: {
perPage: 10,
showPartialRows: false,
showMetricsAtAllLevels: false,
sort: {
columnIndex: null,
direction: null,
},
showTotal: false,
totalFunc: 'sum',
percentageCol: '',
},
template: tableVisTemplate,
},
editorConfig: {
optionsTemplate: TableOptions,
schemas: new Schemas([
{
group: AggGroupNames.Metrics,
name: 'metric',
title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.metricTitle', {
defaultMessage: 'Metric',
}),
aggFilter: ['!geo_centroid', '!geo_bounds'],
aggSettings: {
top_hits: {
allowStrings: true,
},
},
min: 1,
defaults: [{ type: 'count', schema: 'metric' }],
},
{
group: AggGroupNames.Buckets,
name: 'bucket',
title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.bucketTitle', {
defaultMessage: 'Split rows',
}),
aggFilter: ['!filter'],
},
{
group: AggGroupNames.Buckets,
name: 'split',
title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.splitTitle', {
defaultMessage: 'Split table',
}),
min: 0,
max: 1,
aggFilter: ['!filter'],
},
]),
},
responseHandler: tableVisResponseHandler,
hierarchicalData: (vis: Vis) => {
return Boolean(vis.params.showPartialRows || vis.params.showMetricsAtAllLevels);
},
};
}

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { SchemaConfig } from '../../../../plugins/visualizations/public';
import { SchemaConfig } from '../../visualizations/public';
export enum AggTypes {
SUM = 'sum',

View file

@ -0,0 +1,109 @@
/*
* 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 { CoreSetup, PluginInitializerContext } from 'kibana/public';
import angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular';
import $ from 'jquery';
import { VisParams, ExprVis } from '../../visualizations/public';
import { getAngularModule } from './get_inner_angular';
import { initTableVisLegacyModule } from './table_vis_legacy_module';
const innerAngularName = 'kibana/table_vis';
export function getTableVisualizationControllerClass(
core: CoreSetup,
context: PluginInitializerContext
) {
return class TableVisualizationController {
private tableVisModule: IModule | undefined;
private injector: auto.IInjectorService | undefined;
el: JQuery<Element>;
vis: ExprVis;
$rootScope: IRootScopeService | null = null;
$scope: (IScope & { [key: string]: any }) | undefined;
$compile: ICompileService | undefined;
constructor(domeElement: Element, vis: ExprVis) {
this.el = $(domeElement);
this.vis = vis;
}
getInjector() {
if (!this.injector) {
const mountpoint = document.createElement('div');
mountpoint.setAttribute('style', 'height: 100%; width: 100%;');
this.injector = angular.bootstrap(mountpoint, [innerAngularName]);
this.el.append(mountpoint);
}
return this.injector;
}
async initLocalAngular() {
if (!this.tableVisModule) {
const [coreStart] = await core.getStartServices();
this.tableVisModule = getAngularModule(innerAngularName, coreStart, context);
initTableVisLegacyModule(this.tableVisModule);
}
}
async render(esResponse: object, visParams: VisParams) {
await this.initLocalAngular();
return new Promise(async (resolve, reject) => {
if (!this.$rootScope) {
const $injector = this.getInjector();
this.$rootScope = $injector.get('$rootScope');
this.$compile = $injector.get('$compile');
}
const updateScope = () => {
if (!this.$scope) {
return;
}
this.$scope.vis = this.vis;
this.$scope.visState = { params: visParams };
this.$scope.esResponse = esResponse;
this.$scope.visParams = visParams;
this.$scope.renderComplete = resolve;
this.$scope.renderFailed = reject;
this.$scope.resize = Date.now();
this.$scope.$apply();
};
if (!this.$scope && this.$compile) {
this.$scope = this.$rootScope.$new();
this.$scope.uiState = this.vis.getUiState();
updateScope();
this.el.find('div').append(this.$compile(this.vis.type!.visConfig.template)(this.$scope));
this.$scope.$apply();
} else {
updateScope();
}
});
}
destroy() {
if (this.$rootScope) {
this.$rootScope.$destroy();
this.$rootScope = null;
}
}
};
}

View file

@ -0,0 +1,34 @@
/*
* 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 { PluginConfigDescriptor } from 'kibana/server';
import { configSchema, ConfigSchema } from '../config';
export const config: PluginConfigDescriptor<ConfigSchema> = {
schema: configSchema,
deprecations: ({ renameFromRoot }) => [
renameFromRoot('table_vis.enabled', 'vis_type_table.enabled'),
],
};
export const plugin = () => ({
setup() {},
start() {},
});