Skip to content

Commit

Permalink
[Canvas/Reporting] Migrate Canvas to V2 reporting (#109860) (#111272)
Browse files Browse the repository at this point in the history
* first iteration of canvas reporting using v2 PDF generator

* updated jest test

* made v2 report URLs compatible with spaces and simplified some code

* remove non-existent import

* updated import of lib

Co-authored-by: Kibana Machine <[email protected]>

Co-authored-by: Jean-Louis Leysens <[email protected]>
  • Loading branch information
kibanamachine and jloleysens authored Sep 6, 2021
1 parent b4444c1 commit 4eb8b6f
Show file tree
Hide file tree
Showing 21 changed files with 269 additions and 97 deletions.
1 change: 1 addition & 0 deletions src/plugins/share/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export {
UrlGeneratorsService,
} from './url_generators';

export { RedirectOptions } from './url_service';
export { useLocatorUrl } from '../common/url_service/locators/use_locator_url';

import { SharePlugin } from './plugin';
Expand Down
12 changes: 10 additions & 2 deletions src/plugins/share/public/url_service/redirect/redirect_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,23 @@ import type { UrlService } from '../../../common/url_service';
import { render } from './render';
import { parseSearchParams } from './util/parse_search_params';

export interface RedirectOptions {
/**
* @public
* Serializable locator parameters that can be used by the redirect service to navigate to a location
* in Kibana.
*
* When passed to the public {@link SharePluginSetup['navigate']} function, locator params will also be
* migrated.
*/
export interface RedirectOptions<P extends SerializableRecord = unknown & SerializableRecord> {
/** Locator ID. */
id: string;

/** Kibana version when locator params where generated. */
version: string;

/** Locator params. */
params: unknown & SerializableRecord;
params: P;
}

export interface RedirectManagerDependencies {
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/canvas/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
export const UI_SETTINGS = {
ENABLE_LABS_UI: 'labs:canvas:enable_ui',
};

export { CANVAS_APP_LOCATOR, CanvasAppLocator, CanvasAppLocatorParams } from './locator';
45 changes: 45 additions & 0 deletions x-pack/plugins/canvas/common/locator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { LocatorDefinition, LocatorPublic } from 'src/plugins/share/common';

import { CANVAS_APP } from './lib/constants';

// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type CanvasAppLocatorParams = {
view: 'workpadPDF';
id: string;
page: number;
};

export type CanvasAppLocator = LocatorPublic<CanvasAppLocatorParams>;

export const CANVAS_APP_LOCATOR = 'CANVAS_APP_LOCATOR';

export class CanvasAppLocatorDefinition implements LocatorDefinition<CanvasAppLocatorParams> {
id = CANVAS_APP_LOCATOR;

public async getLocation(params: CanvasAppLocatorParams) {
const app = CANVAS_APP;

if (params.view === 'workpadPDF') {
const { id, page } = params;

return {
app,
path: `#/export/workpad/pdf/${id}/page/${page}`,
state: {},
};
}

return {
app,
path: '#/',
state: {},
};
}
}
3 changes: 2 additions & 1 deletion x-pack/plugins/canvas/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"features",
"inspector",
"presentationUtil",
"uiActions"
"uiActions",
"share"
],
"optionalPlugins": ["home", "reporting", "usageCollection"],
"requiredBundles": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ export const ShareMenu = () => {
ReportingPanelPDFComponent !== null
? ({ onClose }: { onClose: () => void }) => (
<ReportingPanelPDFComponent
getJobParams={() =>
getPdfJobParams(sharingData, platformService.getBasePathInterface())
}
getJobParams={() => getPdfJobParams(sharingData, platformService.getKibanaVersion())}
layoutOption="canvas"
onClose={onClose}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,11 @@ jest.mock('../../../../common/lib/fetch');

import { getPdfJobParams } from './utils';
import { workpads } from '../../../../__fixtures__/workpads';
import { IBasePath } from 'kibana/public';

const basePath = ({
prepend: jest.fn().mockImplementation((s) => `basepath/s/spacey/${s}`),
get: () => 'basepath/s/spacey',
serverBasePath: `basepath`,
} as unknown) as IBasePath;
const workpadSharingData = { workpad: workpads[0], pageCount: 12 };

test('getPdfJobParams returns the correct job params for canvas layout', () => {
const jobParams = getPdfJobParams(workpadSharingData, basePath);
const jobParams = getPdfJobParams(workpadSharingData, 'v99.99.99');
expect(jobParams).toMatchInlineSnapshot(`
Object {
"layout": Object {
Expand All @@ -29,21 +23,117 @@ test('getPdfJobParams returns the correct job params for canvas layout', () => {
},
"id": "canvas",
},
"objectType": "canvas workpad",
"relativeUrls": Array [
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/1",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/2",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/3",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/4",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/5",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/6",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/7",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/8",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/9",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/10",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/11",
"/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/12",
"locatorParams": Array [
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 1,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 2,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 3,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 4,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 5,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 6,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 7,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 8,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 9,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 10,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 11,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
Object {
"id": "CANVAS_APP_LOCATOR",
"params": Object {
"id": "base-workpad",
"page": 12,
"view": "workpadPDF",
},
"version": "v99.99.99",
},
],
"objectType": "canvas workpad",
"title": "base workpad",
}
`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
* 2.0.
*/

import { IBasePath } from 'kibana/public';
import rison from 'rison-node';
import type { RedirectOptions } from 'src/plugins/share/public';
import { CANVAS_APP_LOCATOR } from '../../../../common/locator';
import { CanvasAppLocatorParams } from '../../../../common/locator';
import { CanvasWorkpad } from '../../../../types';

export interface CanvasWorkpadSharingData {
Expand All @@ -16,11 +17,8 @@ export interface CanvasWorkpadSharingData {

export function getPdfJobParams(
{ workpad: { id, name: title, width, height }, pageCount }: CanvasWorkpadSharingData,
basePath: IBasePath
version: string
) {
const urlPrefix = basePath.get().replace(basePath.serverBasePath, ''); // for Spaces prefix, which is included in basePath.get()
const canvasEntry = `${urlPrefix}/app/canvas#`;

// The viewport in Reporting by specifying the dimensions. In order for things to work,
// we need a viewport that will include all of the pages in the workpad. The viewport
// also needs to include any offset values from the 0,0 position, otherwise the cropped
Expand All @@ -32,9 +30,18 @@ export function getPdfJobParams(
// viewport size.

// build a list of all page urls for exporting, they are captured one at a time
const workpadUrls = [];

const locatorParams: Array<RedirectOptions<CanvasAppLocatorParams>> = [];
for (let i = 1; i <= pageCount; i++) {
workpadUrls.push(rison.encode(`${canvasEntry}/export/workpad/pdf/${id}/page/${i}`));
locatorParams.push({
id: CANVAS_APP_LOCATOR,
version,
params: {
view: 'workpadPDF',
id,
page: i,
},
});
}

return {
Expand All @@ -43,7 +50,7 @@ export function getPdfJobParams(
id: 'canvas',
},
objectType: 'canvas workpad',
relativeUrls: workpadUrls,
locatorParams,
title,
};
}
11 changes: 9 additions & 2 deletions x-pack/plugins/canvas/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import { BehaviorSubject } from 'rxjs';
import type { SharePluginSetup } from 'src/plugins/share/public';
import { ChartsPluginSetup, ChartsPluginStart } from 'src/plugins/charts/public';
import { ReportingStart } from '../../reporting/public';
import {
Expand All @@ -20,7 +21,8 @@ import {
import { HomePublicPluginSetup } from '../../../../src/plugins/home/public';
import { initLoadingIndicator } from './lib/loading_indicator';
import { getSessionStorage } from './lib/storage';
import { SESSIONSTORAGE_LASTPATH } from '../common/lib/constants';
import { SESSIONSTORAGE_LASTPATH, CANVAS_APP } from '../common/lib/constants';
import { CanvasAppLocatorDefinition } from '../common/locator';
import { featureCatalogueEntry } from './feature_catalogue_entry';
import { ExpressionsSetup, ExpressionsStart } from '../../../../src/plugins/expressions/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../../src/plugins/data/public';
Expand All @@ -43,6 +45,7 @@ export { CoreStart, CoreSetup };
// This interface will be built out as we require other plugins for setup
export interface CanvasSetupDeps {
data: DataPublicPluginSetup;
share: SharePluginSetup;
expressions: ExpressionsSetup;
home?: HomePublicPluginSetup;
usageCollection?: UsageCollectionSetup;
Expand Down Expand Up @@ -97,7 +100,7 @@ export class CanvasPlugin

coreSetup.application.register({
category: DEFAULT_APP_CATEGORIES.kibana,
id: 'canvas',
id: CANVAS_APP,
title: 'Canvas',
euiIconType: 'logoKibana',
order: 3000,
Expand Down Expand Up @@ -145,6 +148,10 @@ export class CanvasPlugin
setupPlugins.home.featureCatalogue.register(featureCatalogueEntry);
}

if (setupPlugins.share) {
setupPlugins.share.url.locators.create(new CanvasAppLocatorDefinition());
}

canvasApi.addArgumentUIs(async () => {
// @ts-expect-error
const { argTypeSpecs } = await import('./expression_types/arg_types');
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/canvas/public/services/kibana/reporting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const reportingServiceFactory: CanvasReportingServiceFactory = ({
const { reporting } = startPlugins;

const reportingEnabled = () => ({
getReportingPanelPDFComponent: () => reporting?.components.ReportingPanelPDF || null,
getReportingPanelPDFComponent: () => reporting?.components.ReportingPanelPDFV2 || null,
});
const reportingDisabled = () => ({ getReportingPanelPDFComponent: () => null });

Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/canvas/public/services/reporting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { ReportingStart } from '../../../reporting/public';

type ReportingPanelPDFComponent = ReportingStart['components']['ReportingPanelPDF'];
type ReportingPanelPDFComponent = ReportingStart['components']['ReportingPanelPDFV2'];
export interface CanvasReportingService {
getReportingPanelPDFComponent: () => ReportingPanelPDFComponent | null;
}
Loading

0 comments on commit 4eb8b6f

Please sign in to comment.