Skip to content

Commit 75cc43c

Browse files
Corey Robertsonelasticmachine
andcommitted
[Canvas] Fixes the Copy Post Url link (#54831)
* Fixes the Copy Post Url link * Adds tests Co-authored-by: Elastic Machine <[email protected]>
1 parent 922117d commit 75cc43c

File tree

5 files changed

+215
-4
lines changed

5 files changed

+215
-4
lines changed

x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ export const WorkpadExport = compose<ComponentProps, {}>(
5858
enabled,
5959
getExportUrl: type => {
6060
if (type === 'pdf') {
61-
const { createPdfUri } = getPdfUrl(workpad, { pageCount });
62-
return getAbsoluteUrl(createPdfUri);
61+
const pdfUrl = getPdfUrl(workpad, { pageCount });
62+
return getAbsoluteUrl(pdfUrl);
6363
}
6464

6565
throw new Error(strings.getUnknownExportErrorMessage(type));
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
jest.mock('../../../../common/lib/fetch');
8+
9+
import { getPdfUrl, createPdf } from './utils';
10+
import { workpads } from '../../../../__tests__/fixtures/workpads';
11+
import { fetch } from '../../../../common/lib/fetch';
12+
13+
const addBasePath = jest.fn().mockImplementation(s => `basepath/${s}`);
14+
const workpad = workpads[0];
15+
16+
test('getPdfUrl returns the correct url', () => {
17+
const url = getPdfUrl(workpad, { pageCount: 2 }, addBasePath);
18+
19+
expect(url).toMatchInlineSnapshot(
20+
`"basepath//api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FPhoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas%20workpad',relativeUrls:!(%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F1,%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F2),title:'base%20workpad')"`
21+
);
22+
});
23+
24+
test('createPdf posts to create the pdf', () => {
25+
createPdf(workpad, { pageCount: 2 }, addBasePath);
26+
27+
expect(fetch.post).toBeCalled();
28+
29+
const args = (fetch.post as jest.MockedFunction<typeof fetch.post>).mock.calls[0];
30+
31+
expect(args[0]).toMatchInlineSnapshot(`"basepath//api/reporting/generate/printablePdf"`);
32+
expect(args[1]).toMatchInlineSnapshot(`
33+
Object {
34+
"jobParams": "(browserTimezone:America/Phoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas workpad',relativeUrls:!(/app/canvas#/export/workpad/pdf/base-workpad/page/1,/app/canvas#/export/workpad/pdf/base-workpad/page/2),title:'base workpad')",
35+
}
36+
`);
37+
});

x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import rison from 'rison-node';
88
import chrome from 'ui/chrome';
9+
import { QueryString } from 'ui/utils/query_string';
910
// @ts-ignore Untyped local.
1011
import { fetch } from '../../../../common/lib/fetch';
1112
import { CanvasWorkpad } from '../../../../types';
@@ -24,7 +25,7 @@ interface PdfUrlData {
2425
createPdfPayload: { jobParams: string };
2526
}
2627

27-
export function getPdfUrl(
28+
function getPdfUrlParts(
2829
{ id, name: title, width, height }: CanvasWorkpad,
2930
{ pageCount }: PageCount
3031
): PdfUrlData {
@@ -66,7 +67,16 @@ export function getPdfUrl(
6667
};
6768
}
6869

70+
export function getPdfUrl(...args: Arguments): string {
71+
const urlParts = getPdfUrlParts(...args);
72+
73+
return `${urlParts.createPdfUri}?${QueryString.param(
74+
'jobParams',
75+
urlParts.createPdfPayload.jobParams
76+
)}`;
77+
}
78+
6979
export function createPdf(...args: Arguments) {
70-
const { createPdfUri, createPdfPayload } = getPdfUrl(...args);
80+
const { createPdfUri, createPdfPayload } = getPdfUrlParts(...args);
7181
return fetch.post(createPdfUri, createPdfPayload);
7282
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { npSetup, npStart } from 'ui/new_platform';
8+
import { CanvasStartDeps } from './plugin'; // eslint-disable-line import/order
9+
10+
// @ts-ignore Untyped Kibana Lib
11+
import chrome, { loadingCount } from 'ui/chrome'; // eslint-disable-line import/order
12+
// @ts-ignore Untyped Module
13+
import { uiModules } from 'ui/modules'; // eslint-disable-line import/order
14+
import { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url'; // eslint-disable-line import/order
15+
import { Storage } from '../../../../../src/plugins/kibana_utils/public'; // eslint-disable-line import/order
16+
// @ts-ignore Untyped Kibana Lib
17+
import { formatMsg } from 'ui/notify/lib/format_msg'; // eslint-disable-line import/order
18+
// @ts-ignore Untyped Kibana Lib
19+
import { QueryString } from 'ui/utils/query_string'; // eslint-disable-line import/order
20+
21+
const shimCoreSetup = {
22+
...npSetup.core,
23+
};
24+
const shimCoreStart = {
25+
...npStart.core,
26+
};
27+
const shimSetupPlugins = {};
28+
const shimStartPlugins: CanvasStartDeps = {
29+
...npStart.plugins,
30+
__LEGACY: {
31+
// ToDo: Copy directly into canvas
32+
absoluteToParsedUrl,
33+
// ToDo: Copy directly into canvas
34+
formatMsg,
35+
QueryString,
36+
// ToDo: Remove in favor of core.application.register
37+
setRootController: chrome.setRootController,
38+
storage: Storage,
39+
// ToDo: Won't be a part of New Platform. Will need to handle internally
40+
trackSubUrlForApp: chrome.trackSubUrlForApp,
41+
uiModules,
42+
},
43+
};
44+
45+
// These methods are intended to be a replacement for import from 'ui/whatever'
46+
// These will go away once all of this one plugin start/setup properly
47+
// injects wherever these need to go.
48+
export function getCoreSetup() {
49+
return shimCoreSetup;
50+
}
51+
52+
export function getCoreStart() {
53+
return shimCoreStart;
54+
}
55+
56+
export function getSetupPlugins() {
57+
return shimSetupPlugins;
58+
}
59+
60+
export function getStartPlugins() {
61+
return shimStartPlugins;
62+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import React from 'react';
8+
import ReactDOM from 'react-dom';
9+
import { Chrome } from 'ui/chrome';
10+
import { IModule } from 'angular';
11+
import { i18n } from '@kbn/i18n';
12+
import { Storage } from '../../../../../src/plugins/kibana_utils/public';
13+
import { CoreSetup, CoreStart, Plugin } from '../../../../../src/core/public';
14+
// @ts-ignore: Untyped Local
15+
import { initStateManagement, initLocationProvider } from './angular/config';
16+
import { CanvasRootControllerFactory } from './angular/controllers';
17+
// @ts-ignore: Untypled Local
18+
import { initStore } from './angular/services';
19+
// @ts-ignore: untyped local component
20+
import { HelpMenu } from './components/help_menu/help_menu';
21+
// @ts-ignore: untyped local
22+
import { loadExpressionTypes } from './lib/load_expression_types';
23+
// @ts-ignore: untyped local
24+
import { loadTransitions } from './lib/load_transitions';
25+
import { initLoadingIndicator } from './lib/loading_indicator';
26+
import { getDocumentationLinks } from './lib/documentation_links';
27+
28+
// @ts-ignore: untyped local
29+
import { initClipboard } from './lib/clipboard';
30+
31+
export { CoreStart };
32+
/**
33+
* These are the private interfaces for the services your plugin depends on.
34+
* @internal
35+
*/
36+
// This interface will be built out as we require other plugins for setup
37+
export interface CanvasSetupDeps {} // eslint-disable-line @typescript-eslint/no-empty-interface
38+
export interface CanvasStartDeps {
39+
__LEGACY: {
40+
absoluteToParsedUrl: (url: string, basePath: string) => any;
41+
formatMsg: any;
42+
QueryString: any;
43+
setRootController: Chrome['setRootController'];
44+
storage: typeof Storage;
45+
trackSubUrlForApp: Chrome['trackSubUrlForApp'];
46+
uiModules: {
47+
get: (module: string) => IModule;
48+
};
49+
};
50+
}
51+
52+
/**
53+
* These are the interfaces with your public contracts. You should export these
54+
* for other plugins to use in _their_ `SetupDeps`/`StartDeps` interfaces.
55+
* @public
56+
*/
57+
// These interfaces are empty for now but will be populate as we need to export
58+
// things for other plugins to use at startup or runtime
59+
export interface CanvasSetup {} // eslint-disable-line @typescript-eslint/no-empty-interface
60+
export interface CanvasStart {} // eslint-disable-line @typescript-eslint/no-empty-interface
61+
62+
/** @internal */
63+
export class CanvasPlugin
64+
implements Plugin<CanvasSetup, CanvasStart, CanvasSetupDeps, CanvasStartDeps> {
65+
public setup(core: CoreSetup, plugins: CanvasSetupDeps) {
66+
// This is where any setup actions need to occur.
67+
// Things like registering functions to the interpreter that need
68+
// to be available everywhere, not just in Canvas
69+
70+
return {};
71+
}
72+
73+
public start(core: CoreStart, plugins: CanvasStartDeps) {
74+
loadExpressionTypes();
75+
loadTransitions();
76+
77+
initStateManagement(core, plugins);
78+
initLocationProvider(core, plugins);
79+
initStore(core, plugins);
80+
initClipboard(plugins.__LEGACY.storage);
81+
initLoadingIndicator(core.http.addLoadingCountSource);
82+
83+
const CanvasRootController = CanvasRootControllerFactory(core, plugins);
84+
plugins.__LEGACY.setRootController('canvas', CanvasRootController);
85+
core.chrome.setHelpExtension({
86+
appName: i18n.translate('xpack.canvas.helpMenu.appName', {
87+
defaultMessage: 'Canvas',
88+
}),
89+
links: [
90+
{
91+
linkType: 'documentation',
92+
href: getDocumentationLinks().canvas,
93+
},
94+
],
95+
content: domNode => () => {
96+
ReactDOM.render(<HelpMenu />, domNode);
97+
},
98+
});
99+
100+
return {};
101+
}
102+
}

0 commit comments

Comments
 (0)