Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature/Reporting] Export Saved Search CSV as Dashboard Panel Action #34571

Merged
merged 83 commits into from
May 29, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
59034e0
[Feature/Reporting] Export Saved Search CSV as Dashboard Panel Action
tsullivan Apr 4, 2019
de9b5e5
Merge remote-tracking branch 'upstream/master' into feature/reporting…
tsullivan Apr 5, 2019
b01cc5a
fixes for new lint rules
tsullivan Apr 5, 2019
2a28080
Merge branch 'master' into feature/reporting/csv-export-panel-action
tsullivan Apr 9, 2019
0c810c8
Date field formatted via docvalue_fields; none else formatted (#34584)
tsullivan Apr 10, 2019
f258931
Self Review items for Export to CSV from Saved Object (#34877)
tsullivan Apr 10, 2019
f79848a
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 11, 2019
9de6d56
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 11, 2019
fd2b146
UI fixes/tech-debt addressed
Apr 11, 2019
78a1162
[Reporting/CSV-Panel-Action] Allow state params sent in POST payload …
tsullivan Apr 12, 2019
472b2d6
LevelLogger TS
tsullivan Apr 12, 2019
4b999e9
Prevent creating a job in the reporting index when the type is immediate
tsullivan Apr 4, 2019
0e8d0bf
self-review cleanup
tsullivan Apr 12, 2019
ad99f1b
a change that depends on another pr
tsullivan Apr 12, 2019
c0bb802
these shouldn't be needed, not accessed in our code
tsullivan Apr 12, 2019
6d53f0f
self review cleanup 2
tsullivan Apr 12, 2019
0bdbf93
logger bug fix
tsullivan Apr 12, 2019
976f0ed
types fix
tsullivan Apr 12, 2019
4446428
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 12, 2019
aab2aa7
pretty
tsullivan Apr 12, 2019
b097aeb
Merge branch 'feature/reporting/csv-export-panel-action' into feature…
tsullivan Apr 12, 2019
7c3ca7f
squash logger lint fix
tsullivan Apr 12, 2019
3b966c3
cleanup
tsullivan Apr 12, 2019
527df35
fix non-immediate
tsullivan Apr 12, 2019
a22a172
fix an un-exported config mixin
tsullivan Apr 12, 2019
486d6a6
fix space mapping
tsullivan Apr 12, 2019
910a721
Merge branch 'feature/reporting/csv-export-panel-action' into feature…
tsullivan Apr 12, 2019
cba56ad
Merge branch 'feature/reporting/csv-export-panel-action-no-job-create…
tsullivan Apr 12, 2019
18281c6
oops
tsullivan Apr 13, 2019
b0e594c
fix from an experiment
tsullivan Apr 13, 2019
4c39b71
Merge branch 'feature/reporting/csv-export-panel-action-no-job-create…
tsullivan Apr 13, 2019
61c1c1b
fix ts
tsullivan Apr 13, 2019
bce1167
Merge branch 'feature/reporting/csv-export-panel-action-no-job-create…
tsullivan Apr 13, 2019
d67d468
fix post property for immediate
tsullivan Apr 13, 2019
4be22cb
use the same spelling that kibana browser side does
tsullivan Apr 13, 2019
b55e5e8
post payload should pretty much be optional
tsullivan Apr 13, 2019
d756e56
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 15, 2019
b570fd5
Fixing bad merge fix
Apr 15, 2019
9cd0499
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 16, 2019
03862d3
Adding missing report mapping for spaces
Apr 16, 2019
963d8f8
Smaller kfetch changes
Apr 16, 2019
2b0e2df
Stray debugger;
Apr 16, 2019
be68e0a
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 17, 2019
ec6c7e7
Feature-flagging this new export type (#35029)
joelgriffith Apr 17, 2019
c787652
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 17, 2019
9e58924
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 18, 2019
0bca683
Cleaning up UI post body, still needs columns sent
Apr 18, 2019
b86614b
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 18, 2019
4d7878a
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 19, 2019
5a38acf
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 29, 2019
63a30b5
Merge remote-tracking branch 'upstream/master' into feature/reporting…
Apr 30, 2019
98193be
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 2, 2019
7593463
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 3, 2019
70c87c4
Merge branch 'feature/reporting/csv-export-panel-action' into feature…
joelgriffith May 3, 2019
5bff2ed
adjust tests to pass on Firefox (#35597)
dmlemeshko May 3, 2019
3741789
enable security plugin in basic (#35891)
May 3, 2019
7e9a0a1
Run mocha test (for review) (#35924)
zfy0701 May 3, 2019
2376f43
Adding a toast-notification that downloading has begun
May 3, 2019
14dea94
Lint fixes and merging PR
May 3, 2019
11d4eb7
Fixing duplicate i18n message
May 6, 2019
63d53fb
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 6, 2019
1b38b22
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 6, 2019
23b4050
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 8, 2019
1daa11d
Fixing kfetch API changes
May 8, 2019
22cb23c
[Reporting/CSV from Saved Search]: Fix bug on max size reached (#35048)
tsullivan May 9, 2019
84a4feb
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 10, 2019
6f60b35
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 10, 2019
de2cd45
Fixing title/displayname breaking change
May 10, 2019
63c4e8a
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 21, 2019
b389e81
Snapshot updates
May 21, 2019
08c217d
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 21, 2019
35dad23
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 22, 2019
f7ee97b
Cross-browser fixes
May 22, 2019
43f2b47
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 22, 2019
2633b33
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 24, 2019
aa98bcf
Refactoring routes out to their own files, breaking out helper tools
May 24, 2019
c7b603c
New helper libs
May 24, 2019
e288caa
Fixing isImmediate flag in getJobParamsFromRequest
May 24, 2019
e0c21fb
Fixing test
May 24, 2019
ed31f6f
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 24, 2019
adbce40
Merge remote-tracking branch 'upstream/master' into feature/reporting…
May 28, 2019
f8d4ecf
Fixing Browser wonkiness and timezone tests
May 28, 2019
59825d9
When you forget to add that one really important commit 🤦
May 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ class PanelActionsStore {
*/
public initializeFromRegistry(panelActionsRegistry: ContextMenuAction[]) {
panelActionsRegistry.forEach(panelAction => {
this.actions.push(panelAction);
if (!this.actions.includes(panelAction)) {
this.actions.push(panelAction);
}
});
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/legacy/ui/public/kfetch/kfetch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,19 @@ describe('kfetch', () => {
});
});

it('should return response', async () => {
it('should return JSON responses by default', async () => {
fetchMock.get('*', { foo: 'bar' });
const res = await kfetch({ pathname: 'my/path' });
expect(res).toEqual({ foo: 'bar' });
});

it('should not return JSON responses by defaul when `parseJson` is `false`', async () => {
fetchMock.get('*', { foo: 'bar' });
const raw = await kfetch({ pathname: 'my/path' }, { parseJson: false });
const res = await raw.text();
expect(res).toEqual('{"foo":"bar"}');
});

it('should prepend url with basepath by default', async () => {
fetchMock.get('*', {});
await kfetch({ pathname: 'my/path' });
Expand Down
8 changes: 5 additions & 3 deletions src/legacy/ui/public/kfetch/kfetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface KFetchOptions extends RequestInit {

export interface KFetchKibanaOptions {
prependBasePath?: boolean;
parseJson?: boolean;
}

export interface Interceptor {
Expand All @@ -50,7 +51,7 @@ export const addInterceptor = (interceptor: Interceptor) => interceptors.push(in

export async function kfetch(
options: KFetchOptions,
{ prependBasePath = true }: KFetchKibanaOptions = {}
{ prependBasePath = true, parseJson = true }: KFetchKibanaOptions = {}
) {
const combinedOptions = withDefaultOptions(options);
const promise = requestInterceptors(combinedOptions).then(
Expand All @@ -61,10 +62,11 @@ export async function kfetch(
});

return window.fetch(fullUrl, restOptions).then(async res => {
const body = await getBodyAsJson(res);
const body = parseJson ? await getBodyAsJson(res) : null;
if (res.ok) {
return body;
return parseJson ? body : res;
}

kertal marked this conversation as resolved.
Show resolved Hide resolved
throw new KFetchError(res, body);
});
}
Expand Down
8 changes: 6 additions & 2 deletions x-pack/plugins/reporting/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ export const PLUGIN_ID = 'reporting';
export const JOB_COMPLETION_NOTIFICATIONS_SESSION_KEY =
'xpack.reporting.jobCompletionNotifications';

export const API_BASE_URL = '/api/reporting';
export const API_BASE_URL = '/api/reporting'; // "Generation URL" from share menu
export const API_BASE_URL_V1 = '/api/reporting/v1'; //

export const CONTENT_TYPE_CSV = 'text/csv';

export const WHITELISTED_JOB_CONTENT_TYPES = [
'application/json',
'application/pdf',
'text/csv',
CONTENT_TYPE_CSV,
'image/png',
];

Expand All @@ -41,4 +44,5 @@ export const KIBANA_REPORTING_TYPE = 'reporting';
export const PDF_JOB_TYPE = 'printable_pdf';
export const PNG_JOB_TYPE = 'PNG';
export const CSV_JOB_TYPE = 'csv';
export const CSV_FROM_SAVEDOBJECT_JOB_TYPE = 'csv_from_savedobject';
export const USES_HEADLESS_JOB_TYPES = [PDF_JOB_TYPE, PNG_JOB_TYPE];
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ beforeEach(() => {
test(`fails if no URL is passed`, async () => {
await expect(
addForceNowQuerystring({
job: {},
job: {
title: 'cool-job-bro',
type: 'csv',
jobParams: {
savedObjectId: 'abc-123',
isImmediate: false,
savedObjectType: 'search',
},
},
server: mockServer,
})
).rejects.toBeDefined();
Expand All @@ -24,7 +32,17 @@ test(`fails if no URL is passed`, async () => {
test(`adds forceNow to hash's query, if it exists`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
const { urls } = await addForceNowQuerystring({
job: { relativeUrl: '/app/kibana#/something', forceNow },
job: {
title: 'cool-job-bro',
type: 'csv',
jobParams: {
savedObjectId: 'abc-123',
isImmediate: false,
savedObjectType: 'search',
},
relativeUrl: '/app/kibana#/something',
forceNow,
},
server: mockServer,
});

Expand All @@ -38,6 +56,13 @@ test(`appends forceNow to hash's query, if it exists`, async () => {

const { urls } = await addForceNowQuerystring({
job: {
title: 'cool-job-bro',
type: 'csv',
jobParams: {
savedObjectId: 'abc-123',
isImmediate: false,
savedObjectType: 'search',
},
relativeUrl: '/app/kibana#/something?_g=something',
forceNow,
},
Expand All @@ -52,6 +77,13 @@ test(`appends forceNow to hash's query, if it exists`, async () => {
test(`doesn't append forceNow query to url, if it doesn't exists`, async () => {
const { urls } = await addForceNowQuerystring({
job: {
title: 'cool-job-bro',
type: 'csv',
jobParams: {
savedObjectId: 'abc-123',
isImmediate: false,
savedObjectType: 'search',
},
relativeUrl: '/app/kibana#/something',
},
server: mockServer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// @ts-ignore
import url from 'url';
import { getAbsoluteUrlFactory } from '../../../common/get_absolute_url';
import { ConditionalHeaders, KbnServer, ReportingJob } from '../../../types';
import { ConditionalHeaders, JobDocPayload, KbnServer } from '../../../types';

function getSavedObjectAbsoluteUrl(job: ReportingJob, relativeUrl: string, server: KbnServer) {
function getSavedObjectAbsoluteUrl(job: JobDocPayload, relativeUrl: string, server: KbnServer) {
const getAbsoluteUrl: any = getAbsoluteUrlFactory(server);

const { pathname: path, hash, search } = url.parse(relativeUrl);
Expand All @@ -21,7 +21,7 @@ export const addForceNowQuerystring = async ({
logo,
server,
}: {
job: ReportingJob;
job: JobDocPayload;
conditionalHeaders?: ConditionalHeaders;
logo?: any;
server: KbnServer;
Expand All @@ -34,7 +34,7 @@ export const addForceNowQuerystring = async ({
job.urls = [getSavedObjectAbsoluteUrl(job, job.relativeUrl, server)];
}

const urls = job.urls.map(jobUrl => {
const urls = job.urls.map((jobUrl: string) => {
if (!job.forceNow) {
return jobUrl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,17 @@ describe('headers', () => {
test(`fails if it can't decrypt headers`, async () => {
await expect(
decryptJobHeaders({
job: { relativeUrl: '/app/kibana#/something', timeRange: {} },
job: {
title: 'cool-job-bro',
type: 'csv',
jobParams: {
savedObjectId: 'abc-123',
isImmediate: false,
savedObjectType: 'search',
},
relativeUrl: '/app/kibana#/something',
timeRange: {},
},
server: mockServer,
})
).rejects.toBeDefined();
Expand All @@ -37,7 +47,17 @@ describe('headers', () => {

const encryptedHeaders = await encryptHeaders(headers);
const { decryptedHeaders } = await decryptJobHeaders({
job: { relativeUrl: '/app/kibana#/something', headers: encryptedHeaders },
job: {
title: 'cool-job-bro',
type: 'csv',
jobParams: {
savedObjectId: 'abc-123',
isImmediate: false,
savedObjectType: 'search',
},
relativeUrl: '/app/kibana#/something',
headers: encryptedHeaders,
},
server: mockServer,
});
expect(decryptedHeaders).toEqual(headers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
*/
// @ts-ignore
import { cryptoFactory } from '../../../server/lib/crypto';
import { CryptoFactory, KbnServer, ReportingJob } from '../../../types';
import { CryptoFactory, JobDocPayload, KbnServer } from '../../../types';

export const decryptJobHeaders = async ({
job,
server,
}: {
job: ReportingJob;
job: JobDocPayload;
server: KbnServer;
}) => {
const crypto: CryptoFactory = cryptoFactory(server);
Expand Down
Loading