From 701416d8de9bd249d62b941212db81f2691c365b Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Thu, 1 Apr 2021 13:30:26 -0700 Subject: [PATCH 1/8] Reporting: Fix _index and _id columns in CSV export --- .../helpers/get_sharing_data.test.ts | 69 ++++++--- .../application/helpers/get_sharing_data.ts | 19 +-- .../get_csv_panel_action.test.ts | 65 +++++++-- .../panel_actions/get_csv_panel_action.tsx | 10 +- .../register_csv_reporting.tsx | 4 +- .../__snapshots__/generate_csv.test.ts.snap | 24 +++- .../generate_csv/generate_csv.test.ts | 136 +++++++++++++++++- .../generate_csv/generate_csv.ts | 25 ++-- .../export_types/csv_searchsource/types.d.ts | 6 +- .../csv_searchsource_immediate/types.d.ts | 5 +- .../routes/csv_searchsource_immediate.ts | 1 + .../apps/dashboard/reporting/download_csv.ts | 3 +- .../csv_searchsource_immediate.ts | 9 +- 13 files changed, 297 insertions(+), 79 deletions(-) diff --git a/src/plugins/discover/public/application/helpers/get_sharing_data.test.ts b/src/plugins/discover/public/application/helpers/get_sharing_data.test.ts index ebb1946b524cd..6a51c085ebbc9 100644 --- a/src/plugins/discover/public/application/helpers/get_sharing_data.test.ts +++ b/src/plugins/discover/public/application/helpers/get_sharing_data.test.ts @@ -6,13 +6,12 @@ * Side Public License, v 1. */ -import { Capabilities } from 'kibana/public'; -import { getSharingData, showPublicUrlSwitch } from './get_sharing_data'; -import { IUiSettingsClient } from 'kibana/public'; +import { Capabilities, IUiSettingsClient } from 'kibana/public'; +import { IndexPattern } from 'src/plugins/data/public'; import { createSearchSourceMock } from '../../../../data/common/search/search_source/mocks'; -import { indexPatternMock } from '../../__mocks__/index_pattern'; import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../common'; -import { IndexPattern } from 'src/plugins/data/public'; +import { indexPatternMock } from '../../__mocks__/index_pattern'; +import { getSharingData, showPublicUrlSwitch } from './get_sharing_data'; describe('getSharingData', () => { let mockConfig: IUiSettingsClient; @@ -36,6 +35,32 @@ describe('getSharingData', () => { const result = await getSharingData(searchSourceMock, { columns: [] }, mockConfig); expect(result).toMatchInlineSnapshot(` Object { + "columns": Array [], + "searchSource": Object { + "index": "the-index-pattern-id", + "sort": Array [ + Object { + "_score": "desc", + }, + ], + }, + } + `); + }); + + test('returns valid data for sharing when columns are selected', async () => { + const searchSourceMock = createSearchSourceMock({ index: indexPatternMock }); + const result = await getSharingData( + searchSourceMock, + { columns: ['column_a', 'column_b'] }, + mockConfig + ); + expect(result).toMatchInlineSnapshot(` + Object { + "columns": Array [ + "column_a", + "column_b", + ], "searchSource": Object { "index": "the-index-pattern-id", "sort": Array [ @@ -69,16 +94,16 @@ describe('getSharingData', () => { ); expect(result).toMatchInlineSnapshot(` Object { + "columns": Array [ + "cool-timefield", + "cool-field-1", + "cool-field-2", + "cool-field-3", + "cool-field-4", + "cool-field-5", + "cool-field-6", + ], "searchSource": Object { - "fields": Array [ - "cool-timefield", - "cool-field-1", - "cool-field-2", - "cool-field-3", - "cool-field-4", - "cool-field-5", - "cool-field-6", - ], "index": "the-index-pattern-id", "sort": Array [ Object { @@ -120,15 +145,15 @@ describe('getSharingData', () => { ); expect(result).toMatchInlineSnapshot(` Object { + "columns": Array [ + "cool-field-1", + "cool-field-2", + "cool-field-3", + "cool-field-4", + "cool-field-5", + "cool-field-6", + ], "searchSource": Object { - "fields": Array [ - "cool-field-1", - "cool-field-2", - "cool-field-3", - "cool-field-4", - "cool-field-5", - "cool-field-6", - ], "index": "the-index-pattern-id", "sort": Array [ Object { diff --git a/src/plugins/discover/public/application/helpers/get_sharing_data.ts b/src/plugins/discover/public/application/helpers/get_sharing_data.ts index f0e07ccc38deb..be4a88448c1fc 100644 --- a/src/plugins/discover/public/application/helpers/get_sharing_data.ts +++ b/src/plugins/discover/public/application/helpers/get_sharing_data.ts @@ -7,11 +7,11 @@ */ import type { Capabilities, IUiSettingsClient } from 'kibana/public'; +import { ISearchSource, SearchSourceFields } from '../../../../data/common'; import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../common'; -import { getSortForSearchSource } from '../angular/doc_table'; -import { ISearchSource } from '../../../../data/common'; -import { AppState } from '../angular/discover_state'; import type { SavedSearch, SortOrder } from '../../saved_searches/types'; +import { AppState } from '../angular/discover_state'; +import { getSortForSearchSource } from '../angular/doc_table'; /** * Preparing data to share the current state as link or CSV/Report @@ -20,13 +20,9 @@ export async function getSharingData( currentSearchSource: ISearchSource, state: AppState | SavedSearch, config: IUiSettingsClient -) { +): Promise<{ columns: string[]; searchSource: SearchSourceFields }> { const searchSource = currentSearchSource.createCopy(); const index = searchSource.getField('index')!; - const fields = { - fields: searchSource.getField('fields'), - fieldsFromSource: searchSource.getField('fieldsFromSource'), - }; searchSource.setField( 'sort', @@ -37,7 +33,7 @@ export async function getSharingData( searchSource.removeField('aggs'); searchSource.removeField('size'); - // fields get re-set to match the saved search columns + // Columns that the user has selected in the saved search let columns = state.columns || []; if (columns && columns.length > 0) { @@ -50,14 +46,11 @@ export async function getSharingData( if (timeFieldName && !columns.includes(timeFieldName)) { columns = [timeFieldName, ...columns]; } - - // if columns were selected in the saved search, use them for the searchSource's fields - const fieldsKey = fields.fieldsFromSource ? 'fieldsFromSource' : 'fields'; - searchSource.setField(fieldsKey, columns); } return { searchSource: searchSource.getSerializedFields(true), + columns, }; } diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts index 4e1b9ccd2642f..06d626a4c4044 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.test.ts @@ -16,6 +16,7 @@ describe('GetCsvReportPanelAction', () => { let core: any; let context: any; let mockLicense$: any; + let mockSearchSource: any; beforeAll(() => { if (typeof window.URL.revokeObjectURL === 'undefined') { @@ -49,22 +50,19 @@ describe('GetCsvReportPanelAction', () => { }, } as any; + mockSearchSource = { + createCopy: () => mockSearchSource, + removeField: jest.fn(), + setField: jest.fn(), + getField: jest.fn(), + getSerializedFields: jest.fn().mockImplementation(() => ({})), + }; + context = { embeddable: { type: 'search', getSavedSearch: () => { - const searchSource = { - createCopy: () => searchSource, - removeField: jest.fn(), - setField: jest.fn(), - getField: jest.fn().mockImplementation((key: string) => { - if (key === 'index') { - return 'my-test-index-*'; - } - }), - getSerializedFields: jest.fn().mockImplementation(() => ({})), - }; - return { searchSource }; + return { searchSource: mockSearchSource }; }, getTitle: () => `The Dude`, getInspectorAdapters: () => null, @@ -79,6 +77,49 @@ describe('GetCsvReportPanelAction', () => { } as any; }); + it('translates empty embeddable context into job params', async () => { + const panel = new GetCsvReportPanelAction(core, mockLicense$()); + + await panel.execute(context); + + expect(core.http.post).toHaveBeenCalledWith( + '/api/reporting/v1/generate/immediate/csv_searchsource', + { + body: '{"searchSource":{},"columns":[],"browserTimezone":"America/New_York"}', + } + ); + }); + + it('translates embeddable context into job params', async () => { + // setup + mockSearchSource = { + createCopy: () => mockSearchSource, + removeField: jest.fn(), + setField: jest.fn(), + getField: jest.fn(), + getSerializedFields: jest.fn().mockImplementation(() => ({ testData: 'testDataValue' })), + }; + context.embeddable.getSavedSearch = () => { + return { + searchSource: mockSearchSource, + columns: ['column_a', 'column_b'], + }; + }; + + const panel = new GetCsvReportPanelAction(core, mockLicense$()); + + // test + await panel.execute(context); + + expect(core.http.post).toHaveBeenCalledWith( + '/api/reporting/v1/generate/immediate/csv_searchsource', + { + body: + '{"searchSource":{"testData":"testDataValue"},"columns":["column_a","column_b"],"browserTimezone":"America/New_York"}', + } + ); + }); + it('allows downloading for valid licenses', async () => { const panel = new GetCsvReportPanelAction(core, mockLicense$()); diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx index d440edc3f3fe9..13e26cbaa1ccd 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx @@ -64,14 +64,11 @@ export class GetCsvReportPanelAction implements ActionDefinition public async getSearchSource(savedSearch: SavedSearch, embeddable: ISearchEmbeddable) { const { getSharingData } = await loadSharingDataHelpers(); - const searchSource = savedSearch.searchSource.createCopy(); - const { searchSource: serializedSearchSource } = await getSharingData( - searchSource, + return await getSharingData( + savedSearch.searchSource, savedSearch, // TODO: get unsaved state (using embeddale.searchScope): https://github.com/elastic/kibana/issues/43977 this.core.uiSettings ); - - return serializedSearchSource; } public isCompatible = async (context: ActionContext) => { @@ -96,12 +93,13 @@ export class GetCsvReportPanelAction implements ActionDefinition } const savedSearch = embeddable.getSavedSearch(); - const searchSource = await this.getSearchSource(savedSearch, embeddable); + const { columns, searchSource } = await this.getSearchSource(savedSearch, embeddable); const kibanaTimezone = this.core.uiSettings.get('dateFormat:tz'); const browserTimezone = kibanaTimezone === 'Browser' ? moment.tz.guess() : kibanaTimezone; const immediateJobParams: JobParamsDownloadCSV = { searchSource, + columns, browserTimezone, title: savedSearch.title, }; diff --git a/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx b/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx index 97433f7a4f0c1..1d2aa063e300b 100644 --- a/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx +++ b/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import moment from 'moment-timezone'; import React from 'react'; import { IUiSettingsClient, ToastsSetup } from 'src/core/public'; +import { SearchSourceFields } from 'src/plugins/data/common'; import { ShareContext } from '../../../../../src/plugins/share/public'; import { LicensingPluginSetup } from '../../../licensing/public'; import { CSV_JOB_TYPE } from '../../common/constants'; @@ -65,7 +66,8 @@ export const csvReportingProvider = ({ browserTimezone, title: sharingData.title as string, objectType, - searchSource: sharingData.searchSource, + searchSource: sharingData.searchSource as SearchSourceFields, + columns: sharingData.columns as string[] | undefined, }; const getJobParams = () => jobParams; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/__snapshots__/generate_csv.test.ts.snap b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/__snapshots__/generate_csv.test.ts.snap index 62c9ecff830ff..789b68a25ac42 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/__snapshots__/generate_csv.test.ts.snap +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/__snapshots__/generate_csv.test.ts.snap @@ -1,18 +1,36 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`fields cells can be multi-value 1`] = ` +exports[`fields from job.columns (7.13+ generated) cells can be multi-value 1`] = ` +"product,category +coconut,\\"cool, rad\\" +" +`; + +exports[`fields from job.columns (7.13+ generated) columns can be top-level fields such as _id and _index 1`] = ` +"\\"_id\\",\\"_index\\",product,category +\\"my-cool-id\\",\\"my-cool-index\\",coconut,\\"cool, rad\\" +" +`; + +exports[`fields from job.columns (7.13+ generated) empty columns defaults to using searchSource.getFields() 1`] = ` +"product +coconut +" +`; + +exports[`fields from job.searchSource.getFields() (7.12 generated) cells can be multi-value 1`] = ` "\\"_id\\",sku \\"my-cool-id\\",\\"This is a cool SKU., This is also a cool SKU.\\" " `; -exports[`fields provides top-level underscored fields as columns 1`] = ` +exports[`fields from job.searchSource.getFields() (7.12 generated) provides top-level underscored fields as columns 1`] = ` "\\"_id\\",\\"_index\\",date,message \\"my-cool-id\\",\\"my-cool-index\\",\\"2020-12-31T00:14:28.000Z\\",\\"it's nice to see you\\" " `; -exports[`fields sorts the fields when they are to be used as table column names 1`] = ` +exports[`fields from job.searchSource.getFields() (7.12 generated) sorts the fields when they are to be used as table column names 1`] = ` "\\"_id\\",\\"_index\\",\\"_score\\",\\"_type\\",date,\\"message_t\\",\\"message_u\\",\\"message_v\\",\\"message_w\\",\\"message_x\\",\\"message_y\\",\\"message_z\\" \\"my-cool-id\\",\\"my-cool-index\\",\\"'-\\",\\"'-\\",\\"2020-12-31T00:14:28.000Z\\",\\"test field T\\",\\"test field U\\",\\"test field V\\",\\"test field W\\",\\"test field X\\",\\"test field Y\\",\\"test field Z\\" " diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts index 0193eaaff2c8d..8694eddce7967 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.test.ts @@ -326,7 +326,7 @@ it('uses the scrollId to page all the data', async () => { expect(csvResult.content).toMatchSnapshot(); }); -describe('fields', () => { +describe('fields from job.searchSource.getFields() (7.12 generated)', () => { it('cells can be multi-value', async () => { searchSourceMock.getField = jest.fn().mockImplementation((key: string) => { if (key === 'fields') { @@ -497,6 +497,140 @@ describe('fields', () => { }); }); +describe('fields from job.columns (7.13+ generated)', () => { + it('cells can be multi-value', async () => { + mockDataClient.search = jest.fn().mockImplementation(() => + Rx.of({ + rawResponse: { + hits: { + hits: [ + { + _id: 'my-cool-id', + _index: 'my-cool-index', + _version: 4, + fields: { + product: 'coconut', + category: [`cool`, `rad`], + }, + }, + ], + total: 1, + }, + }, + }) + ); + + const generateCsv = new CsvGenerator( + createMockJob({ searchSource: {}, columns: ['product', 'category'] }), + mockConfig, + { + es: mockEsClient, + data: mockDataClient, + uiSettings: uiSettingsClient, + }, + { + searchSourceStart: mockSearchSourceService, + fieldFormatsRegistry: mockFieldFormatsRegistry, + }, + new CancellationToken(), + logger + ); + const csvResult = await generateCsv.generateData(); + + expect(csvResult.content).toMatchSnapshot(); + }); + + it('columns can be top-level fields such as _id and _index', async () => { + mockDataClient.search = jest.fn().mockImplementation(() => + Rx.of({ + rawResponse: { + hits: { + hits: [ + { + _id: 'my-cool-id', + _index: 'my-cool-index', + _version: 4, + fields: { + product: 'coconut', + category: [`cool`, `rad`], + }, + }, + ], + total: 1, + }, + }, + }) + ); + + const generateCsv = new CsvGenerator( + createMockJob({ searchSource: {}, columns: ['_id', '_index', 'product', 'category'] }), + mockConfig, + { + es: mockEsClient, + data: mockDataClient, + uiSettings: uiSettingsClient, + }, + { + searchSourceStart: mockSearchSourceService, + fieldFormatsRegistry: mockFieldFormatsRegistry, + }, + new CancellationToken(), + logger + ); + const csvResult = await generateCsv.generateData(); + + expect(csvResult.content).toMatchSnapshot(); + }); + + it('empty columns defaults to using searchSource.getFields()', async () => { + searchSourceMock.getField = jest.fn().mockImplementation((key: string) => { + if (key === 'fields') { + return ['product']; + } + return mockSearchSourceGetFieldDefault(key); + }); + mockDataClient.search = jest.fn().mockImplementation(() => + Rx.of({ + rawResponse: { + hits: { + hits: [ + { + _id: 'my-cool-id', + _index: 'my-cool-index', + _version: 4, + fields: { + product: 'coconut', + category: [`cool`, `rad`], + }, + }, + ], + total: 1, + }, + }, + }) + ); + + const generateCsv = new CsvGenerator( + createMockJob({ searchSource: {}, columns: [] }), + mockConfig, + { + es: mockEsClient, + data: mockDataClient, + uiSettings: uiSettingsClient, + }, + { + searchSourceStart: mockSearchSourceService, + fieldFormatsRegistry: mockFieldFormatsRegistry, + }, + new CancellationToken(), + logger + ); + const csvResult = await generateCsv.generateData(); + + expect(csvResult.content).toMatchSnapshot(); + }); +}); + describe('formulas', () => { const TEST_FORMULA = '=SUM(A1:A2)'; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts index 85c5379a63b7f..b7dc35ba922a7 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts @@ -137,13 +137,13 @@ export class CsvGenerator { // use fields/fieldsFromSource from the searchSource to get the ordering of columns // otherwise use the table columns as they are - private getFields(searchSource: ISearchSource, table: Datatable): string[] { + private getColumnsFromSearchSource(searchSource: ISearchSource, table: Datatable): string[] { const fieldValues: Record = { fields: searchSource.getField('fields'), fieldsFromSource: searchSource.getField('fieldsFromSource'), }; const fieldSource = fieldValues.fieldsFromSource ? 'fieldsFromSource' : 'fields'; - this.logger.debug(`Getting search source fields from: '${fieldSource}'`); + this.logger.debug(`Getting columns from '${fieldSource}' in search source.`); const fields = fieldValues[fieldSource]; // Check if field name values are string[] and if the fields are user-defined @@ -202,16 +202,16 @@ export class CsvGenerator { } /* - * Use the list of fields to generate the header row + * Use the list of columns to generate the header row */ private generateHeader( - fields: string[], + columns: string[], table: Datatable, builder: MaxSizeStringBuilder, settings: CsvExportSettings ) { this.logger.debug(`Building CSV header row...`); - const header = fields.map(this.escapeValues(settings)).join(settings.separator) + '\n'; + const header = columns.map(this.escapeValues(settings)).join(settings.separator) + '\n'; if (!builder.tryAppend(header)) { return { @@ -227,7 +227,7 @@ export class CsvGenerator { * Format a Datatable into rows of CSV content */ private generateRows( - fields: string[], + columns: string[], table: Datatable, builder: MaxSizeStringBuilder, formatters: Record, @@ -240,7 +240,7 @@ export class CsvGenerator { } const row = - fields + columns .map((f) => ({ column: f, data: dataTableRow[f] })) .map(this.formatCellValues(formatters)) .map(this.escapeValues(settings)) @@ -338,11 +338,16 @@ export class CsvGenerator { break; } - const fields = this.getFields(searchSource, table); + // If columns exists in the job params, use it to order the CSV columns + // otherwise, get the ordering from the searchSource's fields / fieldsFromSource + const jobColumns = this.job.columns && this.job.columns.length > 0 && this.job.columns; + const columns = jobColumns + ? jobColumns + : this.getColumnsFromSearchSource(searchSource, table); if (first) { first = false; - this.generateHeader(fields, table, builder, settings); + this.generateHeader(columns, table, builder, settings); } if (table.rows.length < 1) { @@ -350,7 +355,7 @@ export class CsvGenerator { } const formatters = this.getFormatters(table); - this.generateRows(fields, table, builder, formatters, settings); + this.generateRows(columns, table, builder, formatters, settings); // update iterator currentRecord += table.rows.length; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/types.d.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/types.d.ts index f0ad4e00ebd5c..d2a9e2b5bf783 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/types.d.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/types.d.ts @@ -5,13 +5,15 @@ * 2.0. */ -import { BaseParams, BasePayload } from '../../types'; +import type { SearchSourceFields } from 'src/plugins/data/common'; +import type { BaseParams, BasePayload } from '../../types'; export type RawValue = string | object | null | undefined; interface BaseParamsCSV { browserTimezone: string; - searchSource: any; + searchSource: SearchSourceFields; + columns?: string[]; } export type JobParamsCSV = BaseParamsCSV & BaseParams; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/types.d.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/types.d.ts index 276016dd61233..cb1dd659ee2c2 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/types.d.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource_immediate/types.d.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { TimeRangeParams } from '../common'; +import type { SearchSourceFields } from 'src/plugins/data/common'; export interface FakeRequest { headers: Record; @@ -14,7 +14,8 @@ export interface FakeRequest { export interface JobParamsDownloadCSV { browserTimezone: string; title: string; - searchSource: any; + searchSource: SearchSourceFields; + columns?: string[]; } export interface SavedObjectServiceError { diff --git a/x-pack/plugins/reporting/server/routes/csv_searchsource_immediate.ts b/x-pack/plugins/reporting/server/routes/csv_searchsource_immediate.ts index 55092b5236ce6..5d2b77c082ca5 100644 --- a/x-pack/plugins/reporting/server/routes/csv_searchsource_immediate.ts +++ b/x-pack/plugins/reporting/server/routes/csv_searchsource_immediate.ts @@ -44,6 +44,7 @@ export function registerGenerateCsvFromSavedObjectImmediate( path: `${API_BASE_GENERATE_V1}/immediate/csv_searchsource`, validate: { body: schema.object({ + columns: schema.maybe(schema.arrayOf(schema.string())), searchSource: schema.object({}, { unknowns: 'allow' }), browserTimezone: schema.string({ defaultValue: 'UTC' }), title: schema.string(), diff --git a/x-pack/test/functional/apps/dashboard/reporting/download_csv.ts b/x-pack/test/functional/apps/dashboard/reporting/download_csv.ts index c437cfaa8f5dc..d4a909f6a0474 100644 --- a/x-pack/test/functional/apps/dashboard/reporting/download_csv.ts +++ b/x-pack/test/functional/apps/dashboard/reporting/download_csv.ts @@ -50,8 +50,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.existOrFail('csvDownloadStarted'); // validate toast panel }; - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/96000 - describe.skip('Download CSV', () => { + describe('Download CSV', () => { before('initialize tests', async () => { log.debug('ReportingPage:initTests'); await browser.setWindowSize(1600, 850); diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/csv_searchsource_immediate.ts b/x-pack/test/reporting_api_integration/reporting_and_security/csv_searchsource_immediate.ts index ebc7badd88f42..f381bc1edd28e 100644 --- a/x-pack/test/reporting_api_integration/reporting_and_security/csv_searchsource_immediate.ts +++ b/x-pack/test/reporting_api_integration/reporting_and_security/csv_searchsource_immediate.ts @@ -10,9 +10,9 @@ import supertest from 'supertest'; import { JobParamsDownloadCSV } from '../../../plugins/reporting/server/export_types/csv_searchsource_immediate/types'; import { FtrProviderContext } from '../ftr_provider_context'; -const getMockJobParams = (obj: Partial): JobParamsDownloadCSV => ({ +const getMockJobParams = (obj: any): JobParamsDownloadCSV => ({ title: `Mock CSV Title`, - ...(obj as any), + ...obj, }); // eslint-disable-next-line import/no-default-export @@ -31,8 +31,7 @@ export default function ({ getService }: FtrProviderContext) { }, }; - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/96000 - describe.skip('CSV Generation from SearchSource', () => { + describe('CSV Generation from SearchSource', () => { before(async () => { await kibanaServer.uiSettings.update({ 'csv:quoteValues': false, @@ -387,9 +386,9 @@ export default function ({ getService }: FtrProviderContext) { version: true, index: '907bc200-a294-11e9-a900-ef10e0ac769e', sort: [{ date: 'desc' }], - fields: ['date', 'message', '_id', '_index'], filter: [], }, + columns: ['date', 'message', '_id', '_index'], }) ); const { status: resStatus, text: resText, type: resType } = res; From 7889a8665c2bac42434e5e151e658cd6e83da211 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Fri, 2 Apr 2021 13:50:46 -0700 Subject: [PATCH 2/8] optimize - cache _columns and run getColumns once per execution --- .../generate_csv/generate_csv.ts | 54 +++++++++++-------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts index b7dc35ba922a7..8e113673e0697 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts @@ -60,6 +60,7 @@ function isPlainStringArray( } export class CsvGenerator { + private _columns: string[] | null = null; private _formatters: Record | null = null; private csvContainsFormulas = false; private maxSizeReached = false; @@ -135,27 +136,37 @@ export class CsvGenerator { }; } - // use fields/fieldsFromSource from the searchSource to get the ordering of columns - // otherwise use the table columns as they are - private getColumnsFromSearchSource(searchSource: ISearchSource, table: Datatable): string[] { - const fieldValues: Record = { - fields: searchSource.getField('fields'), - fieldsFromSource: searchSource.getField('fieldsFromSource'), - }; - const fieldSource = fieldValues.fieldsFromSource ? 'fieldsFromSource' : 'fields'; - this.logger.debug(`Getting columns from '${fieldSource}' in search source.`); - - const fields = fieldValues[fieldSource]; - // Check if field name values are string[] and if the fields are user-defined - if (isPlainStringArray(fields)) { - return fields; + private getColumns(searchSource: ISearchSource, table: Datatable) { + if (this._columns != null) { + return this._columns; } - // Default to using the table column IDs as the fields - const columnIds = table.columns.map((c) => c.id); - // Fields in the API response don't come sorted - they need to be sorted client-side - columnIds.sort(); - return columnIds; + // if columns is not provided in job params, + // default to use fields/fieldsFromSource from the searchSource to get the ordering of columns + const getFromSearchSource = (): string[] => { + const fieldValues: Record = { + fields: searchSource.getField('fields'), + fieldsFromSource: searchSource.getField('fieldsFromSource'), + }; + const fieldSource = fieldValues.fieldsFromSource ? 'fieldsFromSource' : 'fields'; + this.logger.debug(`Getting columns from '${fieldSource}' in search source.`); + + const fields = fieldValues[fieldSource]; + // Check if field name values are string[] and if the fields are user-defined + if (isPlainStringArray(fields)) { + return fields; + } + + // Default to using the table column IDs as the fields + const columnIds = table.columns.map((c) => c.id); + // Fields in the API response don't come sorted - they need to be sorted client-side + columnIds.sort(); + return columnIds; + }; + const jobColumns = this.job.columns && this.job.columns.length > 0 && this.job.columns; + this._columns = jobColumns ? jobColumns : getFromSearchSource(); + + return this._columns; } private formatCellValues(formatters: Record) { @@ -340,10 +351,7 @@ export class CsvGenerator { // If columns exists in the job params, use it to order the CSV columns // otherwise, get the ordering from the searchSource's fields / fieldsFromSource - const jobColumns = this.job.columns && this.job.columns.length > 0 && this.job.columns; - const columns = jobColumns - ? jobColumns - : this.getColumnsFromSearchSource(searchSource, table); + const columns = this.getColumns(searchSource, table); if (first) { first = false; From e38f8b6d92b6b4d4b72198d6c00262bf2107c7fb Mon Sep 17 00:00:00 2001 From: Tim Sullivan Date: Wed, 7 Apr 2021 11:36:29 -0700 Subject: [PATCH 3/8] Update x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts Co-authored-by: Michael Dokolin --- .../export_types/csv_searchsource/generate_csv/generate_csv.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts index 8e113673e0697..d0da3c91ea5fe 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts @@ -163,8 +163,7 @@ export class CsvGenerator { columnIds.sort(); return columnIds; }; - const jobColumns = this.job.columns && this.job.columns.length > 0 && this.job.columns; - this._columns = jobColumns ? jobColumns : getFromSearchSource(); + this._columns = this.job.columns?.length ? this.job.columns : getFromSearchSource(); return this._columns; } From dbac3973eee9eefb537e09e3fafa08150de01b1a Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 7 Apr 2021 11:42:27 -0700 Subject: [PATCH 4/8] feedback --- .../public/application/helpers/get_sharing_data.ts | 7 ++++++- .../csv_searchsource/generate_csv/generate_csv.ts | 7 ++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/plugins/discover/public/application/helpers/get_sharing_data.ts b/src/plugins/discover/public/application/helpers/get_sharing_data.ts index be4a88448c1fc..ffa965e90fea6 100644 --- a/src/plugins/discover/public/application/helpers/get_sharing_data.ts +++ b/src/plugins/discover/public/application/helpers/get_sharing_data.ts @@ -13,6 +13,11 @@ import type { SavedSearch, SortOrder } from '../../saved_searches/types'; import { AppState } from '../angular/discover_state'; import { getSortForSearchSource } from '../angular/doc_table'; +interface SharingData { + columns: string[]; + searchSource: SearchSourceFields; +} + /** * Preparing data to share the current state as link or CSV/Report */ @@ -20,7 +25,7 @@ export async function getSharingData( currentSearchSource: ISearchSource, state: AppState | SavedSearch, config: IUiSettingsClient -): Promise<{ columns: string[]; searchSource: SearchSourceFields }> { +): Promise { const searchSource = currentSearchSource.createCopy(); const index = searchSource.getField('index')!; diff --git a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts index d0da3c91ea5fe..c1081961dbc58 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_searchsource/generate_csv/generate_csv.ts @@ -20,6 +20,7 @@ import { ISearchSource, ISearchStartSearchSource, SearchFieldValue, + SearchSourceFields, tabifyDocs, } from '../../../../../../../src/plugins/data/common'; import { KbnServerError } from '../../../../../../../src/plugins/kibana_utils/server'; @@ -60,8 +61,8 @@ function isPlainStringArray( } export class CsvGenerator { - private _columns: string[] | null = null; - private _formatters: Record | null = null; + private _columns?: string[]; + private _formatters?: Record; private csvContainsFormulas = false; private maxSizeReached = false; private csvRowCount = 0; @@ -144,7 +145,7 @@ export class CsvGenerator { // if columns is not provided in job params, // default to use fields/fieldsFromSource from the searchSource to get the ordering of columns const getFromSearchSource = (): string[] => { - const fieldValues: Record = { + const fieldValues: Pick = { fields: searchSource.getField('fields'), fieldsFromSource: searchSource.getField('fieldsFromSource'), }; From 072961677c0f433219006456e0e7f2ba2da548b3 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 7 Apr 2021 14:51:32 -0700 Subject: [PATCH 5/8] fix typescripts --- .../application/helpers/get_sharing_data.ts | 4 +-- src/plugins/discover/public/index.ts | 2 +- src/plugins/discover/public/shared/index.ts | 2 ++ .../panel_actions/get_csv_panel_action.tsx | 27 +++++++++++-------- .../register_csv_reporting.tsx | 12 ++++----- .../register_pdf_png_reporting.tsx | 14 +++++----- 6 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/plugins/discover/public/application/helpers/get_sharing_data.ts b/src/plugins/discover/public/application/helpers/get_sharing_data.ts index ffa965e90fea6..f77480a421642 100644 --- a/src/plugins/discover/public/application/helpers/get_sharing_data.ts +++ b/src/plugins/discover/public/application/helpers/get_sharing_data.ts @@ -13,7 +13,7 @@ import type { SavedSearch, SortOrder } from '../../saved_searches/types'; import { AppState } from '../angular/discover_state'; import { getSortForSearchSource } from '../angular/doc_table'; -interface SharingData { +export interface ISharingData { columns: string[]; searchSource: SearchSourceFields; } @@ -25,7 +25,7 @@ export async function getSharingData( currentSearchSource: ISearchSource, state: AppState | SavedSearch, config: IUiSettingsClient -): Promise { +): Promise { const searchSource = currentSearchSource.createCopy(); const index = searchSource.getField('index')!; diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index fbe853ec6deb5..4ca9d2330adc4 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -16,5 +16,5 @@ export function plugin(initializerContext: PluginInitializerContext) { export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches'; export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable'; -export { loadSharingDataHelpers } from './shared'; +export { ISharingData, loadSharingDataHelpers } from './shared'; export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator'; diff --git a/src/plugins/discover/public/shared/index.ts b/src/plugins/discover/public/shared/index.ts index b1e4d9d87000e..57fd62ce8dfc9 100644 --- a/src/plugins/discover/public/shared/index.ts +++ b/src/plugins/discover/public/shared/index.ts @@ -12,3 +12,5 @@ export async function loadSharingDataHelpers() { return await import('../application/helpers/get_sharing_data'); } + +export { ISharingData } from '../application/helpers/get_sharing_data'; diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx index 13e26cbaa1ccd..658ff5afaf7f8 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx @@ -7,21 +7,23 @@ import { i18n } from '@kbn/i18n'; import moment from 'moment-timezone'; -import { CoreSetup } from 'src/core/public'; -import { - loadSharingDataHelpers, +import type { CoreSetup } from 'src/core/public'; +import type { ISearchEmbeddable, + ISharingData, SavedSearch, - SEARCH_EMBEDDABLE_TYPE, } from '../../../../../src/plugins/discover/public'; -import { IEmbeddable, ViewMode } from '../../../../../src/plugins/embeddable/public'; import { - IncompatibleActionError, - UiActionsActionDefinition as ActionDefinition, -} from '../../../../../src/plugins/ui_actions/public'; -import { LicensingPluginSetup } from '../../../licensing/public'; + loadSharingDataHelpers, + SEARCH_EMBEDDABLE_TYPE, +} from '../../../../../src/plugins/discover/public'; +import type { IEmbeddable } from '../../../../../src/plugins/embeddable/public'; +import { ViewMode } from '../../../../../src/plugins/embeddable/public'; +import type { UiActionsActionDefinition as ActionDefinition } from '../../../../../src/plugins/ui_actions/public'; +import { IncompatibleActionError } from '../../../../../src/plugins/ui_actions/public'; +import type { LicensingPluginSetup } from '../../../licensing/public'; import { API_GENERATE_IMMEDIATE, CSV_REPORTING_ACTION } from '../../common/constants'; -import { JobParamsDownloadCSV } from '../../server/export_types/csv_searchsource_immediate/types'; +import type { JobParamsDownloadCSV } from '../../server/export_types/csv_searchsource_immediate/types'; import { checkLicense } from '../lib/license_check'; function isSavedSearchEmbeddable( @@ -62,7 +64,10 @@ export class GetCsvReportPanelAction implements ActionDefinition }); } - public async getSearchSource(savedSearch: SavedSearch, embeddable: ISearchEmbeddable) { + public async getSearchSource( + savedSearch: SavedSearch, + embeddable: ISearchEmbeddable + ): Promise { const { getSharingData } = await loadSharingDataHelpers(); return await getSharingData( savedSearch.searchSource, diff --git a/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx b/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx index 1d2aa063e300b..8995ef4739b09 100644 --- a/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx +++ b/x-pack/plugins/reporting/public/share_context_menu/register_csv_reporting.tsx @@ -8,15 +8,15 @@ import { i18n } from '@kbn/i18n'; import moment from 'moment-timezone'; import React from 'react'; -import { IUiSettingsClient, ToastsSetup } from 'src/core/public'; -import { SearchSourceFields } from 'src/plugins/data/common'; -import { ShareContext } from '../../../../../src/plugins/share/public'; -import { LicensingPluginSetup } from '../../../licensing/public'; +import type { IUiSettingsClient, ToastsSetup } from 'src/core/public'; +import type { SearchSourceFields } from 'src/plugins/data/common'; +import type { ShareContext } from '../../../../../src/plugins/share/public'; +import type { LicensingPluginSetup } from '../../../licensing/public'; import { CSV_JOB_TYPE } from '../../common/constants'; -import { JobParamsCSV } from '../../server/export_types/csv_searchsource/types'; +import type { JobParamsCSV } from '../../server/export_types/csv_searchsource/types'; import { ReportingPanelContent } from '../components/reporting_panel_content_lazy'; import { checkLicense } from '../lib/license_check'; -import { ReportingAPIClient } from '../lib/reporting_api_client'; +import type { ReportingAPIClient } from '../lib/reporting_api_client'; interface ReportingProvider { apiClient: ReportingAPIClient; diff --git a/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx b/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx index 87011cc918587..00ba167c50ae6 100644 --- a/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx +++ b/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx @@ -8,15 +8,15 @@ import { i18n } from '@kbn/i18n'; import moment from 'moment-timezone'; import React from 'react'; -import { IUiSettingsClient, ToastsSetup } from 'src/core/public'; -import { ShareContext } from '../../../../../src/plugins/share/public'; -import { LicensingPluginSetup } from '../../../licensing/public'; -import { LayoutParams } from '../../common/types'; -import { JobParamsPNG } from '../../server/export_types/png/types'; -import { JobParamsPDF } from '../../server/export_types/printable_pdf/types'; +import type { IUiSettingsClient, ToastsSetup } from 'src/core/public'; +import type { ShareContext } from '../../../../../src/plugins/share/public'; +import type { LicensingPluginSetup } from '../../../licensing/public'; +import type { LayoutParams } from '../../common/types'; +import type { JobParamsPNG } from '../../server/export_types/png/types'; +import type { JobParamsPDF } from '../../server/export_types/printable_pdf/types'; import { ScreenCapturePanelContent } from '../components/screen_capture_panel_content_lazy'; import { checkLicense } from '../lib/license_check'; -import { ReportingAPIClient } from '../lib/reporting_api_client'; +import type { ReportingAPIClient } from '../lib/reporting_api_client'; interface ReportingPDFPNGProvider { apiClient: ReportingAPIClient; From 09770356d345ac32ae7c5b993364b1df96cfa8ca Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Mon, 12 Apr 2021 13:02:43 -0700 Subject: [PATCH 6/8] fix plugin list test --- docs/developer/plugin-list.asciidoc | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 0c40c2a8c4db9..353a77527d1d5 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -216,14 +216,27 @@ which also contains the timelion APIs and backend, look at the vis_type_timelion |<> -|An API for: - -- creating custom functionality (`actions`) -- creating custom user interaction events (`triggers`) -- attaching and detaching `actions` to `triggers`. -- emitting `trigger` events -- executing `actions` attached to a given `trigger`. -- exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger. +|UI Actions plugins provides API to manage *triggers* and *actions*. + +*Trigger* is an abstract description of user's intent to perform an action +(like user clicking on a value inside chart). It allows us to do runtime +binding between code from different plugins. For, example one such +trigger is when somebody applies filters on dashboard; another one is when +somebody opens a Dashboard panel context menu. + +*Actions* are pieces of code that execute in response to a trigger. For example, +to the dashboard filtering trigger multiple actions can be attached. Once a user +filters on the dashboard all possible actions are displayed to the user in a +popup menu and the user has to chose one. + +In general this plugin provides: + +- Creating custom functionality (actions). +- Creating custom user interaction events (triggers). +- Attaching and detaching actions to triggers. +- Emitting trigger events. +- Executing actions attached to a given trigger. +- Exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger. |{kib-repo}blob/{branch}/src/plugins/url_forwarding/README.md[urlForwarding] From a8796675cc130bf24a696d8f8eee0496d3be0a54 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Mon, 12 Apr 2021 13:24:07 -0700 Subject: [PATCH 7/8] fix plugin list --- docs/developer/plugin-list.asciidoc | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 353a77527d1d5..0c40c2a8c4db9 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -216,27 +216,14 @@ which also contains the timelion APIs and backend, look at the vis_type_timelion |<> -|UI Actions plugins provides API to manage *triggers* and *actions*. - -*Trigger* is an abstract description of user's intent to perform an action -(like user clicking on a value inside chart). It allows us to do runtime -binding between code from different plugins. For, example one such -trigger is when somebody applies filters on dashboard; another one is when -somebody opens a Dashboard panel context menu. - -*Actions* are pieces of code that execute in response to a trigger. For example, -to the dashboard filtering trigger multiple actions can be attached. Once a user -filters on the dashboard all possible actions are displayed to the user in a -popup menu and the user has to chose one. - -In general this plugin provides: - -- Creating custom functionality (actions). -- Creating custom user interaction events (triggers). -- Attaching and detaching actions to triggers. -- Emitting trigger events. -- Executing actions attached to a given trigger. -- Exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger. +|An API for: + +- creating custom functionality (`actions`) +- creating custom user interaction events (`triggers`) +- attaching and detaching `actions` to `triggers`. +- emitting `trigger` events +- executing `actions` attached to a given `trigger`. +- exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger. |{kib-repo}blob/{branch}/src/plugins/url_forwarding/README.md[urlForwarding] From fc16f85c48915aa0859490539101e969ed14ef91 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Mon, 12 Apr 2021 14:53:42 -0700 Subject: [PATCH 8/8] take away the export interface to test CI build stats --- .../public/application/helpers/get_sharing_data.ts | 9 ++------- src/plugins/discover/public/index.ts | 2 +- src/plugins/discover/public/shared/index.ts | 2 -- .../public/panel_actions/get_csv_panel_action.tsx | 11 ++--------- 4 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/plugins/discover/public/application/helpers/get_sharing_data.ts b/src/plugins/discover/public/application/helpers/get_sharing_data.ts index f77480a421642..47be4b8037152 100644 --- a/src/plugins/discover/public/application/helpers/get_sharing_data.ts +++ b/src/plugins/discover/public/application/helpers/get_sharing_data.ts @@ -7,17 +7,12 @@ */ import type { Capabilities, IUiSettingsClient } from 'kibana/public'; -import { ISearchSource, SearchSourceFields } from '../../../../data/common'; +import { ISearchSource } from '../../../../data/common'; import { DOC_HIDE_TIME_COLUMN_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../common'; import type { SavedSearch, SortOrder } from '../../saved_searches/types'; import { AppState } from '../angular/discover_state'; import { getSortForSearchSource } from '../angular/doc_table'; -export interface ISharingData { - columns: string[]; - searchSource: SearchSourceFields; -} - /** * Preparing data to share the current state as link or CSV/Report */ @@ -25,7 +20,7 @@ export async function getSharingData( currentSearchSource: ISearchSource, state: AppState | SavedSearch, config: IUiSettingsClient -): Promise { +) { const searchSource = currentSearchSource.createCopy(); const index = searchSource.getField('index')!; diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index 4ca9d2330adc4..fbe853ec6deb5 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -16,5 +16,5 @@ export function plugin(initializerContext: PluginInitializerContext) { export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches'; export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable'; -export { ISharingData, loadSharingDataHelpers } from './shared'; +export { loadSharingDataHelpers } from './shared'; export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator'; diff --git a/src/plugins/discover/public/shared/index.ts b/src/plugins/discover/public/shared/index.ts index 57fd62ce8dfc9..b1e4d9d87000e 100644 --- a/src/plugins/discover/public/shared/index.ts +++ b/src/plugins/discover/public/shared/index.ts @@ -12,5 +12,3 @@ export async function loadSharingDataHelpers() { return await import('../application/helpers/get_sharing_data'); } - -export { ISharingData } from '../application/helpers/get_sharing_data'; diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx index 658ff5afaf7f8..95d193880975c 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx @@ -8,11 +8,7 @@ import { i18n } from '@kbn/i18n'; import moment from 'moment-timezone'; import type { CoreSetup } from 'src/core/public'; -import type { - ISearchEmbeddable, - ISharingData, - SavedSearch, -} from '../../../../../src/plugins/discover/public'; +import type { ISearchEmbeddable, SavedSearch } from '../../../../../src/plugins/discover/public'; import { loadSharingDataHelpers, SEARCH_EMBEDDABLE_TYPE, @@ -64,10 +60,7 @@ export class GetCsvReportPanelAction implements ActionDefinition }); } - public async getSearchSource( - savedSearch: SavedSearch, - embeddable: ISearchEmbeddable - ): Promise { + public async getSearchSource(savedSearch: SavedSearch, embeddable: ISearchEmbeddable) { const { getSharingData } = await loadSharingDataHelpers(); return await getSharingData( savedSearch.searchSource,