From 46fbbd6a2fdc45e23344852b50cd945831a9d4ac Mon Sep 17 00:00:00 2001 From: Yulong Date: Wed, 9 Oct 2019 11:50:34 +0800 Subject: [PATCH 01/60] [Code] improve lsp proxy state management (#47580) --- .../plugins/code/server/lsp/abstract_launcher.ts | 4 ++++ x-pack/legacy/plugins/code/server/lsp/proxy.ts | 9 ++++++--- .../plugins/code/server/lsp/request_expander.ts | 14 +++++++++----- .../plugins/code/server/lsp/workspace_handler.ts | 3 +++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/x-pack/legacy/plugins/code/server/lsp/abstract_launcher.ts b/x-pack/legacy/plugins/code/server/lsp/abstract_launcher.ts index a467838ca4cd5..946075e1e7dea 100644 --- a/x-pack/legacy/plugins/code/server/lsp/abstract_launcher.ts +++ b/x-pack/legacy/plugins/code/server/lsp/abstract_launcher.ts @@ -43,6 +43,8 @@ export abstract class AbstractLauncher implements ILanguageServerLauncher { log.debug('Detach mode, expected language server launch externally'); proxy.onConnected(() => { this.running = true; + // reset spawn times + this.spawnTimes = 0; }); proxy.onDisconnected(() => { this.running = false; @@ -81,6 +83,8 @@ export abstract class AbstractLauncher implements ILanguageServerLauncher { await new Promise((resolve, reject) => { proxy.onConnected(() => { this.proxyConnected = true; + // reset spawn times + this.spawnTimes = 0; resolve(); }); this.launchReject = err => { diff --git a/x-pack/legacy/plugins/code/server/lsp/proxy.ts b/x-pack/legacy/plugins/code/server/lsp/proxy.ts index 998a5663424ef..3ba796df9e733 100644 --- a/x-pack/legacy/plugins/code/server/lsp/proxy.ts +++ b/x-pack/legacy/plugins/code/server/lsp/proxy.ts @@ -93,9 +93,10 @@ export class LanguageServerProxy implements ILanguageServerHandler { this.eventEmitter.on('err', error => reject(new ResponseError(InternalError, 'Server error', error)) ); - this.eventEmitter.on('exit', () => - reject(new ResponseError(RequestCancelled, 'Server closed')) - ); + this.eventEmitter.on('exit', () => { + reject(new ResponseError(RequestCancelled, 'Server closed')); + this.initialized = false; + }); this.eventEmitter.on('connect', () => resolve(this.clientConnection!)); }); } @@ -164,6 +165,7 @@ export class LanguageServerProxy implements ILanguageServerHandler { clientConn.sendNotification(ExitNotification.type); } this.eventEmitter.emit('exit'); + this.initialized = false; } public startServerConnection() { @@ -246,6 +248,7 @@ export class LanguageServerProxy implements ILanguageServerHandler { private onSocketClosed() { this.clientConnection = null; + this.initialized = false; this.eventEmitter.emit('close'); } diff --git a/x-pack/legacy/plugins/code/server/lsp/request_expander.ts b/x-pack/legacy/plugins/code/server/lsp/request_expander.ts index 8d3aa62d61b39..3e746710117a5 100644 --- a/x-pack/legacy/plugins/code/server/lsp/request_expander.ts +++ b/x-pack/legacy/plugins/code/server/lsp/request_expander.ts @@ -56,9 +56,12 @@ export class RequestExpander implements ILanguageServerHandler { readonly log: Logger ) { this.proxy = proxy; - proxy.onDisconnected(() => { + const clearListener = () => { + this.log.debug('proxy disconnected, clearing workspace status'); this.workspaces.clear(); - }); + }; + proxy.onDisconnected(clearListener); + proxy.onExit(clearListener); this.workspaceRoot = fs.realpathSync(this.serverOptions.workspacePath); } @@ -260,9 +263,10 @@ export class RequestExpander implements ILanguageServerHandler { } initializeState(workspaceDir: string): WorkspaceStatus { - if (this.hasWorkspacePath(workspaceDir)) { - return this.getWorkspace(workspaceDir).status; + const ws = this.getWorkspace(workspaceDir); + if (ws.status === WorkspaceStatus.Uninitialized) { + ws.initPromise = Cancelable.fromPromise(this.initialize(workspaceDir)); } - return WorkspaceStatus.Uninitialized; + return ws.status; } } diff --git a/x-pack/legacy/plugins/code/server/lsp/workspace_handler.ts b/x-pack/legacy/plugins/code/server/lsp/workspace_handler.ts index 535e60ae0dadf..4c0314851bcd9 100644 --- a/x-pack/legacy/plugins/code/server/lsp/workspace_handler.ts +++ b/x-pack/legacy/plugins/code/server/lsp/workspace_handler.ts @@ -158,6 +158,9 @@ export class WorkspaceHandler { } public handleResponse(request: LspRequest, response: ResponseMessage): ResponseMessage { + if (!response.result) { + return response; + } const { method } = request; switch (method) { case 'textDocument/hover': { From 08de89b588502be8fc3e3ced71149dd6f813a12a Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Wed, 9 Oct 2019 07:34:51 +0200 Subject: [PATCH 02/60] [discover] fix shared links tests for cloud testing (#47572) * Add method to open permalinks menu entry if available * Migrate to TypeScript --- .../{share_page.js => share_page.ts} | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) rename test/functional/page_objects/{share_page.js => share_page.ts} (75%) diff --git a/test/functional/page_objects/share_page.js b/test/functional/page_objects/share_page.ts similarity index 75% rename from test/functional/page_objects/share_page.js rename to test/functional/page_objects/share_page.ts index 0bd2def010274..906effcb54a26 100644 --- a/test/functional/page_objects/share_page.js +++ b/test/functional/page_objects/share_page.ts @@ -17,7 +17,9 @@ * under the License. */ -export function SharePageProvider({ getService, getPageObjects }) { +import { FtrProviderContext } from '../ftr_provider_context'; + +export function SharePageProvider({ getService, getPageObjects }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const find = getService('find'); const PageObjects = getPageObjects(['visualize', 'common']); @@ -32,7 +34,7 @@ export function SharePageProvider({ getService, getPageObjects }) { return testSubjects.click('shareTopNavButton'); } - async openShareMenuItem(itemTitle) { + async openShareMenuItem(itemTitle: string) { log.debug(`openShareMenuItem title:${itemTitle}`); const isShareMenuOpen = await this.isShareMenuOpen(); if (!isShareMenuOpen) { @@ -45,11 +47,24 @@ export function SharePageProvider({ getService, getPageObjects }) { await this.clickShareTopNavButton(); } const menuPanel = await find.byCssSelector('div.euiContextMenuPanel'); - testSubjects.click(`sharePanel-${itemTitle.replace(' ', '')}`); + await testSubjects.click(`sharePanel-${itemTitle.replace(' ', '')}`); await testSubjects.waitForDeleted(menuPanel); } + /** + * if there are more entries in the share menu, the permalinks entry has to be clicked first + * else the selection isn't displayed. this happens if you're testing against an instance + * with xpack features enabled, where there's also a csv sharing option + * in a pure OSS environment, the permalinks sharing panel is displayed initially + */ + async openPermaLinks() { + if (await testSubjects.exists('sharePanel-Permalinks')) { + await testSubjects.click(`sharePanel-Permalinks`); + } + } + async getSharedUrl() { + await this.openPermaLinks(); return await testSubjects.getAttribute('copyShareUrlButton', 'data-share-url'); } @@ -68,9 +83,9 @@ export function SharePageProvider({ getService, getPageObjects }) { } async exportAsSavedObject() { + await this.openPermaLinks(); return await testSubjects.click('exportAsSavedObject'); } - } return new SharePage(); From dba9da9b9f7483a29781badea9fe4b4aa1470976 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 9 Oct 2019 09:29:40 +0200 Subject: [PATCH 03/60] [Graph] Fix default discover url template building (#47587) --- .../graph/public/state_management/legacy.test.ts | 15 ++++++++++++++- .../public/state_management/url_templates.test.ts | 3 ++- .../public/state_management/url_templates.ts | 7 +++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/graph/public/state_management/legacy.test.ts b/x-pack/legacy/plugins/graph/public/state_management/legacy.test.ts index e6ab7213a872e..dd71c7c6c077d 100644 --- a/x-pack/legacy/plugins/graph/public/state_management/legacy.test.ts +++ b/x-pack/legacy/plugins/graph/public/state_management/legacy.test.ts @@ -14,6 +14,7 @@ import { updateFieldProperties, } from './fields'; import { AdvancedSettings, WorkspaceField, WorkspaceNode } from '../types'; +import { loadTemplates, syncTemplatesSaga } from './url_templates'; /** * This suite tests all the sagas that only exist to sync the legacy world @@ -25,7 +26,13 @@ describe('legacy sync sagas', () => { beforeEach(() => { env = createMockGraphStore({ - sagas: [syncSettingsSaga, updateSaveButtonSaga, syncFieldsSaga, syncNodeStyleSaga], + sagas: [ + syncSettingsSaga, + updateSaveButtonSaga, + syncFieldsSaga, + syncNodeStyleSaga, + syncTemplatesSaga, + ], initialStateOverwrites: { fields: { field1: { @@ -67,6 +74,12 @@ describe('legacy sync sagas', () => { expect(env.mockedDeps.getWorkspace()!.options.exploreControls).toBe(newSettings); }); + it('syncs templates with workspace', () => { + env.store.dispatch(loadTemplates([])); + expect(env.mockedDeps.setUrlTemplates).toHaveBeenCalledWith([]); + expect(env.mockedDeps.notifyAngular).toHaveBeenCalled(); + }); + it('notifies angular when fields are selected', () => { env.store.dispatch(selectField('field1')); expect(env.mockedDeps.notifyAngular).toHaveBeenCalled(); diff --git a/x-pack/legacy/plugins/graph/public/state_management/url_templates.test.ts b/x-pack/legacy/plugins/graph/public/state_management/url_templates.test.ts index 83ed426830ff9..c4a3b0fb776a0 100644 --- a/x-pack/legacy/plugins/graph/public/state_management/url_templates.test.ts +++ b/x-pack/legacy/plugins/graph/public/state_management/url_templates.test.ts @@ -22,7 +22,8 @@ describe('url_templates', () => { ); expect(templates.length).toBe(1); expect(templates[0].encoder).toBe(outlinkEncoders[0]); - expect(templates[0].url).toContain('test-pattern'); + expect(templates[0].url).not.toContain('test-pattern'); + expect(templates[0].url).toContain('123456'); expect(templates[0].isDefault).toBe(true); }); diff --git a/x-pack/legacy/plugins/graph/public/state_management/url_templates.ts b/x-pack/legacy/plugins/graph/public/state_management/url_templates.ts index 7618646c18816..eac29d0ec9116 100644 --- a/x-pack/legacy/plugins/graph/public/state_management/url_templates.ts +++ b/x-pack/legacy/plugins/graph/public/state_management/url_templates.ts @@ -44,7 +44,7 @@ function generateDefaultTemplate( '_a', rison.encode({ columns: ['_source'], - index: datasource.title, + index: datasource.id, interval: 'auto', query: { language: 'kuery', query: urlTemplatePlaceholder }, sort: ['_score', 'desc'], @@ -106,6 +106,9 @@ export const syncTemplatesSaga = ({ setUrlTemplates, notifyAngular }: GraphStore } return function*() { - yield takeEvery(matchesOne(loadTemplates, saveTemplate, removeTemplate), syncTemplates); + yield takeEvery( + matchesOne(loadTemplates, saveTemplate, removeTemplate, requestDatasource, setDatasource), + syncTemplates + ); }; }; From 6a0da3ddda06d6b10e4b671934c65dc57032e7b8 Mon Sep 17 00:00:00 2001 From: Maryia Lapata Date: Wed, 9 Oct 2019 12:19:45 +0300 Subject: [PATCH 04/60] [Vis: Default Editor] Euificate table options tab (#46013) * Euificate table options tab * Add validation * Use SchemaConfig for dimensions * Update snapshots --- .../public/components/common/switch.tsx | 4 +- .../components/options/gauge/ranges_panel.tsx | 2 +- .../components/options/heatmap/index.tsx | 2 +- .../custom_extents_options.test.tsx.snap | 2 +- .../__snapshots__/label_options.test.tsx.snap | 2 +- .../metrics_axes/custom_extents_options.tsx | 2 +- .../options/metrics_axes/label_options.tsx | 4 +- .../options/point_series/grid_panel.tsx | 2 +- .../public/settings_options.tsx | 10 +- .../public/components/table_vis_options.tsx | 154 ++++++++++++++++++ .../vis_type_table/public/components/utils.ts | 68 ++++++++ .../public/shim/table_vis_legacy_module.ts | 3 - .../public/table_vis_params.html | 115 ------------- .../vis_type_table/public/table_vis_params.js | 83 ---------- .../vis_type_table/public/table_vis_type.ts | 10 +- .../vis_type_table/public/types.ts | 48 ++++++ .../{_get_columns.js => _get_columns.ts} | 24 ++- .../loader/pipeline_helpers/utilities.ts | 3 +- .../translations/translations/ja-JP.json | 4 - .../translations/translations/zh-CN.json | 4 - 20 files changed, 304 insertions(+), 242 deletions(-) create mode 100644 src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx create mode 100644 src/legacy/core_plugins/vis_type_table/public/components/utils.ts delete mode 100644 src/legacy/core_plugins/vis_type_table/public/table_vis_params.html delete mode 100644 src/legacy/core_plugins/vis_type_table/public/table_vis_params.js create mode 100644 src/legacy/core_plugins/vis_type_table/public/types.ts rename src/legacy/ui/public/agg_response/tabify/{_get_columns.js => _get_columns.ts} (78%) diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/switch.tsx b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/switch.tsx index 40991d6bdfb1d..6f41c6f12867d 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/switch.tsx +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/common/switch.tsx @@ -22,7 +22,7 @@ import React from 'react'; import { EuiFormRow, EuiSwitch, EuiToolTip } from '@elastic/eui'; interface SwitchOptionProps { - dataTestSubj?: string; + 'data-test-subj'?: string; label?: string; tooltip?: string; disabled?: boolean; @@ -32,7 +32,7 @@ interface SwitchOptionProps { } function SwitchOption({ - dataTestSubj, + 'data-test-subj': dataTestSubj, tooltip, label, disabled, diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx index 4e3b511782c9e..c1fa3475470f1 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/gauge/ranges_panel.tsx @@ -69,7 +69,7 @@ function RangesPanel({ /> ) { /> ) { return ( - -

- -

-
- - ) { + const percentageColumns = useMemo( + () => [ + { + value: '', + text: i18n.translate('visTypeTable.params.defaultPercentageCol', { + defaultMessage: 'Don’t show', + }), + }, + ...tabifyGetColumns(aggs.getResponseAggs(), true) + .filter(col => isAggConfigNumeric(get(col, 'aggConfig.type.name'), stateParams.dimensions)) + .map(({ name }) => ({ value: name, text: name })), + ], + [aggs, aggsLabels, stateParams.percentageCol, stateParams.dimensions] + ); + + const isPerPageValid = stateParams.perPage === '' || stateParams.perPage > 0; + + useEffect(() => { + setValidity(isPerPageValid); + }, [isPerPageValid]); + + useEffect(() => { + if ( + !percentageColumns.find(({ value }) => value === stateParams.percentageCol) && + percentageColumns[0] && + percentageColumns[0].value !== stateParams.percentageCol + ) { + setValue('percentageCol', percentageColumns[0].value); + } + }, [percentageColumns, stateParams.percentageCol]); + + return ( + + + {' '} + + + } + isInvalid={!isPerPageValid} + min={1} + paramName="perPage" + value={stateParams.perPage} + setValue={setValue} + /> + + + + + + + + + + + + ); +} + +export { TableOptions }; diff --git a/src/legacy/core_plugins/vis_type_table/public/components/utils.ts b/src/legacy/core_plugins/vis_type_table/public/components/utils.ts new file mode 100644 index 0000000000000..365566503e25b --- /dev/null +++ b/src/legacy/core_plugins/vis_type_table/public/components/utils.ts @@ -0,0 +1,68 @@ +/* + * 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 { get } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { AggTypes, Dimensions } from '../types'; + +function isAggConfigNumeric( + type: AggTypes, + { buckets, metrics }: Dimensions = { buckets: [], metrics: [] } +) { + const dimension = + buckets.find(({ aggType }) => aggType === type) || + metrics.find(({ aggType }) => aggType === type); + const formatType = get(dimension, 'format.id') || get(dimension, 'format.params.id'); + return formatType === 'number'; +} + +const totalAggregations = [ + { + value: AggTypes.SUM, + text: i18n.translate('visTypeTable.totalAggregations.sumText', { + defaultMessage: 'Sum', + }), + }, + { + value: AggTypes.AVG, + text: i18n.translate('visTypeTable.totalAggregations.averageText', { + defaultMessage: 'Average', + }), + }, + { + value: AggTypes.MIN, + text: i18n.translate('visTypeTable.totalAggregations.minText', { + defaultMessage: 'Min', + }), + }, + { + value: AggTypes.MAX, + text: i18n.translate('visTypeTable.totalAggregations.maxText', { + defaultMessage: 'Max', + }), + }, + { + value: AggTypes.COUNT, + text: i18n.translate('visTypeTable.totalAggregations.countText', { + defaultMessage: 'Count', + }), + }, +]; + +export { isAggConfigNumeric, totalAggregations }; diff --git a/src/legacy/core_plugins/vis_type_table/public/shim/table_vis_legacy_module.ts b/src/legacy/core_plugins/vis_type_table/public/shim/table_vis_legacy_module.ts index 7750804fb5879..e148fd98490df 100644 --- a/src/legacy/core_plugins/vis_type_table/public/shim/table_vis_legacy_module.ts +++ b/src/legacy/core_plugins/vis_type_table/public/shim/table_vis_legacy_module.ts @@ -28,8 +28,6 @@ import 'ui/directives/paginate'; // @ts-ignore import { TableVisController } from '../table_vis_controller.js'; // @ts-ignore -import { TableVisParams } from '../table_vis_params'; -// @ts-ignore import { KbnAggTable } from '../agg_table/agg_table'; // @ts-ignore import { KbnAggTableGroup } from '../agg_table/agg_table_group'; @@ -43,7 +41,6 @@ export const initTableVisLegacyModule = once((): void => { uiModules .get('kibana/table_vis', ['kibana', 'RecursionHelper']) .controller('KbnTableVisController', TableVisController) - .directive('tableVisParams', TableVisParams) .directive('kbnAggTable', KbnAggTable) .directive('kbnAggTableGroup', KbnAggTableGroup) .directive('kbnRows', KbnRows) diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_params.html b/src/legacy/core_plugins/vis_type_table/public/table_vis_params.html deleted file mode 100644 index 272aebecebe31..0000000000000 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_params.html +++ /dev/null @@ -1,115 +0,0 @@ -
-
-
-
-
- -
- -
-
-
- -
- -
-
-
-
- - -
-
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_params.js b/src/legacy/core_plugins/vis_type_table/public/table_vis_params.js deleted file mode 100644 index 8e4b113c3bca0..0000000000000 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_params.js +++ /dev/null @@ -1,83 +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 _ from 'lodash'; -import { tabifyGetColumns } from 'ui/agg_response/tabify/_get_columns'; -import tableVisParamsTemplate from './table_vis_params.html'; -import { i18n } from '@kbn/i18n'; - -export function TableVisParams() { - return { - restrict: 'E', - template: tableVisParamsTemplate, - link: function ($scope) { - const noCol = { - value: '', - name: i18n.translate('visTypeTable.params.defaultPercetangeCol', { - defaultMessage: 'Don’t show', - }) - }; - $scope.totalAggregations = ['sum', 'avg', 'min', 'max', 'count']; - $scope.percentageColumns = [noCol]; - - $scope.$watchMulti([ - '[]editorState.aggs.aggs', - 'editorState.params.percentageCol', - '=editorState.params.dimensions.buckets', - '=editorState.params.dimensions.metrics', - 'vis.dirty' // though not used directly in the callback, it is a strong indicator that we should recompute - ], function () { - const { aggs, params } = $scope.editorState; - - $scope.percentageColumns = [noCol, ...tabifyGetColumns(aggs.getResponseAggs(), true) - .filter(col => isNumeric(_.get(col, 'aggConfig.type.name'), params.dimensions)) - .map(col => ({ value: col.name, name: col.name }))]; - - if (!_.find($scope.percentageColumns, { value: params.percentageCol })) { - params.percentageCol = $scope.percentageColumns[0].value; - } - }, true); - - $scope.$watchMulti( - ['editorState.params.showPartialRows', 'editorState.params.showMetricsAtAllLevels'], - function () { - if (!$scope.vis) return; - const params = $scope.editorState.params; - $scope.metricsAtAllLevels = params.showPartialRows || params.showMetricsAtAllLevels; - } - ); - }, - }; -} - -/** - * Determines if a aggConfig is numeric - * @param {String} type - the type of the aggConfig - * @param {Object} obj - dimensions of the current visualization or editor - * @param {Object} obj.buckets - * @param {Object} obj.metrics - * @returns {Boolean} - */ -export function isNumeric(type, { buckets = [], metrics = [] } = {}) { - const dimension = - buckets.find(({ aggType }) => aggType === type) || - metrics.find(({ aggType }) => aggType === type); - const formatType = _.get(dimension, 'format.id') || _.get(dimension, 'format.params.id'); - return formatType === 'number'; -} diff --git a/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts b/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts index dced7a1836f44..1de72c0b33a4c 100644 --- a/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts +++ b/src/legacy/core_plugins/vis_type_table/public/table_vis_type.ts @@ -26,9 +26,11 @@ import { visFactory } from 'ui/vis/vis_factory'; import { Schemas } from 'ui/vis/editors/default/schemas'; // @ts-ignore import { AngularVisController } from 'ui/vis/vis_types/angular_vis_type'; +import { AggGroupNames } from 'ui/vis/editors/default'; import { tableVisResponseHandler } from './table_vis_request_handler'; // @ts-ignore import tableVisTemplate from './table_vis.html'; +import { TableOptions } from './components/table_vis_options'; export const createTableVisTypeDefinition = () => { return visFactory.createBaseVisualization({ @@ -58,10 +60,10 @@ export const createTableVisTypeDefinition = () => { template: tableVisTemplate, }, editorConfig: { - optionsTemplate: '', + optionsTemplate: TableOptions, schemas: new Schemas([ { - group: 'metrics', + group: AggGroupNames.Metrics, name: 'metric', title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.metricTitle', { defaultMessage: 'Metric', @@ -76,7 +78,7 @@ export const createTableVisTypeDefinition = () => { defaults: [{ type: 'count', schema: 'metric' }], }, { - group: 'buckets', + group: AggGroupNames.Buckets, name: 'bucket', title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.bucketTitle', { defaultMessage: 'Split rows', @@ -84,7 +86,7 @@ export const createTableVisTypeDefinition = () => { aggFilter: ['!filter'], }, { - group: 'buckets', + group: AggGroupNames.Buckets, name: 'split', title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.splitTitle', { defaultMessage: 'Split table', diff --git a/src/legacy/core_plugins/vis_type_table/public/types.ts b/src/legacy/core_plugins/vis_type_table/public/types.ts new file mode 100644 index 0000000000000..4a16bb72bd2e3 --- /dev/null +++ b/src/legacy/core_plugins/vis_type_table/public/types.ts @@ -0,0 +1,48 @@ +/* + * 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 { SchemaConfig } from 'ui/visualize/loader/pipeline_helpers/build_pipeline'; + +export enum AggTypes { + SUM = 'sum', + AVG = 'avg', + MIN = 'min', + MAX = 'max', + COUNT = 'count', +} + +export interface Dimensions { + buckets: SchemaConfig[]; + metrics: SchemaConfig[]; +} + +export interface TableVisParams { + type: 'table'; + perPage: number | ''; + showPartialRows: boolean; + showMetricsAtAllLevels: boolean; + sort: { + columnIndex: number | null; + direction: string | null; + }; + showTotal: boolean; + totalFunc: AggTypes; + percentageCol: string; + dimensions: Dimensions; +} diff --git a/src/legacy/ui/public/agg_response/tabify/_get_columns.js b/src/legacy/ui/public/agg_response/tabify/_get_columns.ts similarity index 78% rename from src/legacy/ui/public/agg_response/tabify/_get_columns.js rename to src/legacy/ui/public/agg_response/tabify/_get_columns.ts index ac7cb3bcac334..80facc978d4d1 100644 --- a/src/legacy/ui/public/agg_response/tabify/_get_columns.js +++ b/src/legacy/ui/public/agg_response/tabify/_get_columns.ts @@ -17,13 +17,20 @@ * under the License. */ -import _ from 'lodash'; +import { groupBy } from 'lodash'; +import { AggConfig } from '../../vis/'; -const getColumn = (agg, i) => { +export interface AggColumn { + aggConfig: AggConfig; + id: string; + name: string; +} + +const getColumn = (agg: AggConfig, i: number): AggColumn => { return { aggConfig: agg, id: `col-${i}-${agg.id}`, - name: agg.makeLabel() + name: agg.makeLabel(), }; }; @@ -33,18 +40,17 @@ const getColumn = (agg, i) => { * @param {AggConfigs} aggs - the agg configs object to which the aggregation response correlates * @param {boolean} minimalColumns - setting to true will only return a column for the last bucket/metric instead of one for each level */ -export function tabifyGetColumns(aggs, minimalColumns) { - +export function tabifyGetColumns(aggs: AggConfig[], minimalColumns: boolean) { // pick the columns if (minimalColumns) { return aggs.map((agg, i) => getColumn(agg, i)); } // supposed to be bucket,...metrics,bucket,...metrics - const columns = []; + const columns: AggColumn[] = []; // separate the metrics - const grouped = _.groupBy(aggs, function (agg) { + const grouped = groupBy(aggs, agg => { return agg.type.type; }); @@ -55,9 +61,9 @@ export function tabifyGetColumns(aggs, minimalColumns) { let columnIndex = 0; // return the buckets, and after each place all of the metrics - grouped.buckets.forEach(function (agg) { + grouped.buckets.forEach(agg => { columns.push(getColumn(agg, columnIndex++)); - grouped.metrics.forEach(function (metric) { + grouped.metrics.forEach(metric => { columns.push(getColumn(metric, columnIndex++)); }); }); diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts index 29c3caed2f7dd..c8cc63f742df4 100644 --- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts +++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts @@ -24,7 +24,6 @@ import { SerializedFieldFormat } from 'src/plugins/expressions/common/expression import { FieldFormat } from '../../../../../../plugins/data/common/field_formats'; -// @ts-ignore import { tabifyGetColumns } from '../../../agg_response/tabify/_get_columns'; import chrome from '../../../chrome'; // @ts-ignore @@ -158,5 +157,5 @@ export const getTableAggs = (vis: Vis): AggConfig[] => { return []; } const columns = tabifyGetColumns(vis.aggs.getResponseAggs(), !vis.isHierarchical()); - return columns.map((c: any) => c.aggConfig); + return columns.map(c => c.aggConfig); }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 20b0471d678fd..d75c730d5e25d 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2775,7 +2775,6 @@ "visTypeTable.directives.tableCellFilter.filterForValueTooltip": "値でフィルタリング", "visTypeTable.directives.tableCellFilter.filterOutValueTooltip": "値を除外", "visTypeTable.function.help": "表ビジュアライゼーション", - "visTypeTable.params.perPageLabel": "1 ページあたり", "visTypeTable.params.showMetricsLabel": "すべてのバケット/レベルのメトリックを表示", "visTypeTable.params.showPartialRowsLabel": "部分的な行を表示", "visTypeTable.params.showPartialRowsTip": "部分データのある行を表示。表示されていなくてもすべてのバケット/レベルのメトリックが計算されます。", @@ -2787,10 +2786,8 @@ "visTypeTable.tableVisEditorConfig.schemas.splitTitle": "テーブルを分割", "visTypeTable.tableVisTitle": "データテーブル", "visTypeTable.vis.noResultsFoundTitle": "結果が見つかりませんでした", - "visTypeTable.params.defaultPercetangeCol": "非表示", "visTypeTable.params.PercentageColLabel": "パーセンテージ列", "visTypeTable.params.percentageTableColumnName": "{title} パーセント", - "visTypeTable.params.showMetricsLabel.optionsTitle": "オプション", "visTypeTagCloud.feedbackMessage.tooSmallContainerDescription": "コンテナーが小さすぎてクラウド全体を表示できません。タグが切り取られたか省略されている可能性があります。", "visTypeTagCloud.feedbackMessage.truncatedTagsDescription": "描写時間が長くなるのを防ぐため、タグの数が切り捨てられています。", "visTypeTagCloud.function.bucket.help": "バケットディメンションの構成です。", @@ -11333,7 +11330,6 @@ "esUi.cronEditor.month.october": "10 月", "esUi.cronEditor.month.september": "9 月", "esUi.cronEditor.textEveryLabel": "毎", - "visTypeMarkdown.params.settingsTitle": "設定", "visTypeMarkdown.tabs.dataText": "データ", "visTypeMarkdown.tabs.optionsText": "オプション", "visTypeMarkdown.params.fontSizeLabel": "ポイント単位のベースフォントサイズです。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 435819fed7a68..6e450431cc28e 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2776,7 +2776,6 @@ "visTypeTable.directives.tableCellFilter.filterForValueTooltip": "筛留值", "visTypeTable.directives.tableCellFilter.filterOutValueTooltip": "筛除值", "visTypeTable.function.help": "表可视化", - "visTypeTable.params.perPageLabel": "每页", "visTypeTable.params.showMetricsLabel": "显示每个桶/级别的指标", "visTypeTable.params.showPartialRowsLabel": "显示部分行", "visTypeTable.params.showPartialRowsTip": "显示具有部分数据的行。这仍将计算每个桶/级别的指标,即使它们未显示。", @@ -2788,10 +2787,8 @@ "visTypeTable.tableVisEditorConfig.schemas.splitTitle": "拆分表", "visTypeTable.tableVisTitle": "数据表", "visTypeTable.vis.noResultsFoundTitle": "找不到结果", - "visTypeTable.params.defaultPercetangeCol": "不显示", "visTypeTable.params.PercentageColLabel": "百分比列", "visTypeTable.params.percentageTableColumnName": "{title} 百分比", - "visTypeTable.params.showMetricsLabel.optionsTitle": "选项", "visTypeTagCloud.feedbackMessage.tooSmallContainerDescription": "容器太小,无法显示整个云。标记可能被裁剪或省略。", "visTypeTagCloud.feedbackMessage.truncatedTagsDescription": "标记数量已截断,以避免绘制时间过长。", "visTypeTagCloud.function.bucket.help": "存储桶维度配置", @@ -11335,7 +11332,6 @@ "esUi.cronEditor.month.october": "十月", "esUi.cronEditor.month.september": "九月", "esUi.cronEditor.textEveryLabel": "所有", - "visTypeMarkdown.params.settingsTitle": "设置", "visTypeMarkdown.tabs.dataText": "数据", "visTypeMarkdown.tabs.optionsText": "选项", "visTypeMarkdown.params.fontSizeLabel": "基础字体大小(磅)", From 9430ca1abccfcbb5cdd4b63f644ec169dc3aa723 Mon Sep 17 00:00:00 2001 From: Artyom Gospodarsky Date: Wed, 9 Oct 2019 12:53:45 +0300 Subject: [PATCH 05/60] [NP] Migrate field format utils to TS (#47124) * Migrate url.js to TS * Typescriptify truncate util * Typescriptify string util * Change method name by constant * Typescriptify relative date util * Refactor url util * Typescriptify percent util * Typescriptify bytes util * Typescriptify number util * Make _convert as method of derived class * Get rid of Field Format type * Typescriptify IP and Color utils * Typescriptify dates utils * Change functions to arrow functions in tests * Convert Duration, Source and Static Lookup to TS * Remove Field Format type from Numeral * Use MomentJS types instead of any * Use KBN_FIELD_TYPES as field types * Make timezone as string * Make memoizedConverter and memoizedPattern types * Make ugly type for createNumberFormat * Replace any types by certain ones * Add types to tests * Internationalize Duration, String, Url utils * Get rid of implicit _convert method * Fix conflicts * Make htmlConvert, textConvert and setupContentType as public * Make some any's more certain --- .../public/index_patterns/fields/field.ts | 1 - .../field_formats/types/__tests__/color.js | 109 ------- .../types/__tests__/date_nanos.js | 102 ------ .../field_formats/types/__tests__/ip.js | 41 --- .../field_formats/types/__tests__/string.js | 80 ----- .../field_formats/types/__tests__/url.js | 260 --------------- .../types/{_numeral.js => _numeral.ts} | 36 ++- .../{__tests__/boolean.js => boolean.test.ts} | 44 ++- .../common/field_formats/types/boolean.ts | 5 +- .../{__tests__/bytes.js => bytes.test.ts} | 24 +- .../types/{bytes.js => bytes.ts} | 6 +- .../common/field_formats/types/color.test.ts | 117 +++++++ .../types/{color.js => color.ts} | 44 +-- .../{color_default.js => color_default.ts} | 2 +- .../types/{__tests__/date.js => date.test.ts} | 31 +- .../field_formats/types/{date.js => date.ts} | 48 +-- .../field_formats/types/date_nanos.test.js | 42 --- .../field_formats/types/date_nanos.test.ts | 131 ++++++++ .../types/{date_nanos.js => date_nanos.ts} | 82 +++-- .../types/{date_server.js => date_server.ts} | 46 +-- .../common/field_formats/types/duration.js | 93 ------ .../duration.js => duration.test.ts} | 95 +++--- .../common/field_formats/types/duration.ts | 201 ++++++++++++ .../common/field_formats/types/ip.test.ts | 39 +++ .../field_formats/types/{ip.js => ip.ts} | 23 +- .../{__tests__/number.js => number.test.ts} | 24 +- .../types/{number.js => number.ts} | 6 +- .../{__tests__/percent.js => percent.test.ts} | 24 +- .../types/{percent.js => percent.ts} | 14 +- ...relative_date.js => relative_date.test.ts} | 26 +- .../{relative_date.js => relative_date.ts} | 25 +- .../types/{source.js => source.ts} | 55 ++-- .../{static_lookup.js => static_lookup.ts} | 38 ++- .../common/field_formats/types/string.js | 83 ----- .../common/field_formats/types/string.test.ts | 78 +++++ .../common/field_formats/types/string.ts | 136 ++++++++ .../truncate.js => truncate.test.ts} | 25 +- .../types/{truncate.js => truncate.ts} | 31 +- .../common/field_formats/types/url.test.ts | 301 ++++++++++++++++++ .../field_formats/types/{url.js => url.ts} | 120 ++++--- .../mixin/field_formats_service.test.ts | 16 +- .../lib/__tests__/get_default_format.test.js | 3 +- .../content_types/html_content_type.ts | 13 +- .../content_types/text_content_type.ts | 10 +- .../common/field_formats/converters/custom.ts | 6 +- .../common/field_formats/field_format.test.ts | 76 ++--- .../data/common/field_formats/field_format.ts | 45 +-- .../data/common/field_formats/index.ts | 1 + .../csv/server/__tests__/execute_job.js | 3 +- .../server/lib/__tests__/field_format_map.js | 3 +- 50 files changed, 1558 insertions(+), 1306 deletions(-) delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/color.js delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/date_nanos.js delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/ip.js delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/string.js delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/url.js rename src/legacy/core_plugins/kibana/common/field_formats/types/{_numeral.js => _numeral.ts} (68%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{__tests__/boolean.js => boolean.test.ts} (59%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{__tests__/bytes.js => bytes.test.ts} (67%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{bytes.js => bytes.ts} (88%) create mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/color.test.ts rename src/legacy/core_plugins/kibana/common/field_formats/types/{color.js => color.ts} (67%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{color_default.js => color_default.ts} (97%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{__tests__/date.js => date.test.ts} (65%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{date.js => date.ts} (59%) delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/date_nanos.test.js create mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/date_nanos.test.ts rename src/legacy/core_plugins/kibana/common/field_formats/types/{date_nanos.js => date_nanos.ts} (57%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{date_server.js => date_server.ts} (67%) delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/duration.js rename src/legacy/core_plugins/kibana/common/field_formats/types/{__tests__/duration.js => duration.test.ts} (60%) create mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/duration.ts create mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/ip.test.ts rename src/legacy/core_plugins/kibana/common/field_formats/types/{ip.js => ip.ts} (72%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{__tests__/number.js => number.test.ts} (66%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{number.js => number.ts} (88%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{__tests__/percent.js => percent.test.ts} (66%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{percent.js => percent.ts} (84%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{__tests__/relative_date.js => relative_date.test.ts} (58%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{relative_date.js => relative_date.ts} (74%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{source.js => source.ts} (60%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{static_lookup.js => static_lookup.ts} (67%) delete mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/string.js create mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/string.test.ts create mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/string.ts rename src/legacy/core_plugins/kibana/common/field_formats/types/{__tests__/truncate.js => truncate.test.ts} (55%) rename src/legacy/core_plugins/kibana/common/field_formats/types/{truncate.js => truncate.ts} (70%) create mode 100644 src/legacy/core_plugins/kibana/common/field_formats/types/url.test.ts rename src/legacy/core_plugins/kibana/common/field_formats/types/{url.js => url.ts} (66%) diff --git a/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts b/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts index a92c7674d8725..2cf038cd5bd47 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts @@ -23,7 +23,6 @@ import { toastNotifications } from 'ui/notify'; import { i18n } from '@kbn/i18n'; // @ts-ignore import { ObjDefine } from './obj_define'; -// @ts-ignore import { FieldFormat } from '../../../../../../plugins/data/common/field_formats'; // @ts-ignore import { shortenDottedString } from '../../../../../core_plugins/kibana/common/utils/shorten_dotted_string'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/color.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/color.js deleted file mode 100644 index 39746ffe5894f..0000000000000 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/color.js +++ /dev/null @@ -1,109 +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 expect from '@kbn/expect'; -import { createColorFormat } from '../color'; -import { FieldFormat } from '../../../../../../../plugins/data/common/field_formats'; - -const ColorFormat = createColorFormat(FieldFormat); - -describe('Color Format', function () { - - describe('field is a number', () => { - it('should add colors if the value is in range', function () { - const colorer = new ColorFormat({ - fieldType: 'number', - colors: [{ - range: '100:150', - text: 'blue', - background: 'yellow' - }] - }); - expect(colorer.convert(99, 'html')).to.eql('99'); - expect(colorer.convert(100, 'html')).to.eql( - '100' - ); - expect(colorer.convert(150, 'html')).to.eql( - '150' - ); - expect(colorer.convert(151, 'html')).to.eql('151'); - }); - - it('should not convert invalid ranges', function () { - const colorer = new ColorFormat({ - fieldType: 'number', - colors: [{ - range: '100150', - text: 'blue', - background: 'yellow' - }] - }); - expect(colorer.convert(99, 'html')).to.eql('99'); - }); - }); - - describe('field is a string', () => { - it('should add colors if the regex matches', function () { - const colorer = new ColorFormat({ - fieldType: 'string', - colors: [{ - regex: 'A.*', - text: 'blue', - background: 'yellow' - }] - }); - - const converter = colorer.getConverterFor('html'); - expect(converter('B', 'html')).to.eql('B'); - expect(converter('AAA', 'html')).to.eql( - 'AAA' - ); - expect(converter('AB', 'html')).to.eql( - 'AB' - ); - expect(converter('a', 'html')).to.eql('a'); - - expect(converter('B', 'html')).to.eql('B'); - expect(converter('AAA', 'html')).to.eql( - 'AAA' - ); - expect(converter('AB', 'html')).to.eql( - 'AB' - ); - expect(converter('AB <', 'html')).to.eql( - 'AB <' - ); - expect(converter('a', 'html')).to.eql('a'); - }); - - it('returns original value (escaped) when regex is invalid', function () { - const colorer = new ColorFormat({ - fieldType: 'string', - colors: [{ - regex: 'A.*', - text: 'blue', - background: 'yellow' - }] - }); - - const converter = colorer.getConverterFor('html'); - expect(converter('<', 'html')).to.eql('<'); - }); - }); -}); diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/date_nanos.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/date_nanos.js deleted file mode 100644 index c17574f6794fb..0000000000000 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/date_nanos.js +++ /dev/null @@ -1,102 +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 expect from '@kbn/expect'; -import moment from 'moment-timezone'; -import { createDateNanosFormat, analysePatternForFract, formatWithNanos } from '../date_nanos'; -import { FieldFormat } from '../../../../../../../plugins/data/common/field_formats'; - -const DateFormat = createDateNanosFormat(FieldFormat); - -describe('Date Nanos Format', function () { - let convert; - let mockConfig; - - beforeEach(function () { - mockConfig = {}; - mockConfig.dateNanosFormat = 'MMMM Do YYYY, HH:mm:ss.SSSSSSSSS'; - mockConfig['dateFormat:tz'] = 'Browser'; - const getConfig = (key) => mockConfig[key]; - const date = new DateFormat({}, getConfig); - - convert = date.convert.bind(date); - }); - - - it('should inject fractional seconds into formatted timestamp', function () { - [{ - input: '2019-05-20T14:04:56.357001234Z', - pattern: 'MMM D, YYYY @ HH:mm:ss.SSSSSSSSS', - expected: 'May 20, 2019 @ 14:04:56.357001234', - }, { - input: '2019-05-05T14:04:56.357111234Z', - pattern: 'MMM D, YYYY @ HH:mm:ss.SSSSSSSSS', - expected: 'May 5, 2019 @ 14:04:56.357111234', - }, { - input: '2019-05-05T14:04:56.357Z', - pattern: 'MMM D, YYYY @ HH:mm:ss.SSSSSSSSS', - expected: 'May 5, 2019 @ 14:04:56.357000000', - }, { - input: '2019-05-05T14:04:56Z', - pattern: 'MMM D, YYYY @ HH:mm:ss.SSSSSSSSS', - expected: 'May 5, 2019 @ 14:04:56.000000000', - }, { - input: '2019-05-05T14:04:56.201900001Z', - pattern: 'MMM D, YYYY @ HH:mm:ss SSSS', - expected: 'May 5, 2019 @ 14:04:56 2019', - }, { - input: '2019-05-05T14:04:56.201900001Z', - pattern: 'SSSSSSSSS', - expected: '201900001', - }].forEach(fixture => { - const fracPattern = analysePatternForFract(fixture.pattern); - const momentDate = moment(fixture.input).utc(); - const value = formatWithNanos(momentDate, fixture.input, fracPattern); - expect(value).to.be(fixture.expected); - }); - }); - - it('decoding an undefined or null date should return an empty string', function () { - expect(convert(null)).to.be('-'); - expect(convert(undefined)).to.be('-'); - }); - - it('should clear the memoization cache after changing the date', function () { - function setDefaultTimezone() { - moment.tz.setDefault(mockConfig['dateFormat:tz']); - } - - const dateTime = '2019-05-05T14:04:56.201900001Z'; - - mockConfig['dateFormat:tz'] = 'America/Chicago'; - setDefaultTimezone(); - const chicagoTime = convert(dateTime); - - mockConfig['dateFormat:tz'] = 'America/Phoenix'; - setDefaultTimezone(); - const phoenixTime = convert(dateTime); - - expect(chicagoTime).not.to.equal(phoenixTime); - }); - - it('should return the value itself when it cannot successfully be formatted', function () { - const dateMath = 'now+1M/d'; - expect(convert(dateMath)).to.be(dateMath); - }); -}); diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/ip.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/ip.js deleted file mode 100644 index cb23fc07194be..0000000000000 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/ip.js +++ /dev/null @@ -1,41 +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 expect from '@kbn/expect'; -import { createIpFormat } from '../ip'; -import { FieldFormat } from '../../../../../../../plugins/data/common/field_formats'; - -const IpFormat = createIpFormat(FieldFormat); - -describe('IP Address Format', function () { - let ip; - beforeEach(function () { - ip = new IpFormat(); - }); - - it('converts a value from a decimal to a string', function () { - expect(ip.convert(1186489492)).to.be('70.184.100.148'); - }); - - it('converts null and undefined to -', function () { - expect(ip.convert(null)).to.be('-'); - expect(ip.convert(undefined)).to.be('-'); - }); - -}); diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/string.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/string.js deleted file mode 100644 index f08d5c8ddb152..0000000000000 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/string.js +++ /dev/null @@ -1,80 +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 expect from '@kbn/expect'; -import { createStringFormat } from '../string'; -import { FieldFormat } from '../../../../../../../plugins/data/common/field_formats'; - -const StringFormat = createStringFormat(FieldFormat); - -describe('String Format', function () { - - it('convert a string to lower case', function () { - const string = new StringFormat({ - transform: 'lower' - }); - expect(string.convert('Kibana')).to.be('kibana'); - }); - - it('convert a string to upper case', function () { - const string = new StringFormat({ - transform: 'upper' - }); - expect(string.convert('Kibana')).to.be('KIBANA'); - }); - - it('decode a base64 string', function () { - const string = new StringFormat({ - transform: 'base64' - }); - expect(string.convert('Zm9vYmFy')).to.be('foobar'); - }); - - it('convert a string to title case', function () { - const string = new StringFormat({ - transform: 'title' - }); - expect(string.convert('PLEASE DO NOT SHOUT')).to.be('Please Do Not Shout'); - expect(string.convert('Mean, variance and standard_deviation.')).to.be('Mean, Variance And Standard_deviation.'); - expect(string.convert('Stay CALM!')).to.be('Stay Calm!'); - }); - - it('convert a string to short case', function () { - const string = new StringFormat({ - transform: 'short' - }); - expect(string.convert('dot.notated.string')).to.be('d.n.string'); - }); - - it('convert a string to unknown transform case', function () { - const string = new StringFormat({ - transform: 'unknown_transform' - }); - const value = 'test test test'; - expect(string.convert(value)).to.be(value); - }); - - it('decode a URL Param string', function () { - const string = new StringFormat({ - transform: 'urlparam' - }); - expect(string.convert('%EC%95%88%EB%85%95%20%ED%82%A4%EB%B0%94%EB%82%98')).to.be('안녕 키바나'); - }); - -}); diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/url.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/url.js deleted file mode 100644 index 74172dbcce314..0000000000000 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/url.js +++ /dev/null @@ -1,260 +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 expect from '@kbn/expect'; -import { createUrlFormat } from '../url'; -import { FieldFormat } from '../../../../../../../plugins/data/common/field_formats'; - -const UrlFormat = createUrlFormat(FieldFormat); - -describe('UrlFormat', function () { - - it('outputs a simple tab by default', function () { - const url = new UrlFormat(); - - expect(url.convert('http://elastic.co', 'html')) - .to.be('http://elastic.co'); - }); - - it('outputs an