diff --git a/src/plugins/dashboard/kibana.json b/src/plugins/dashboard/kibana.json
index cb6a5383688dc..2be6e9b269e71 100644
--- a/src/plugins/dashboard/kibana.json
+++ b/src/plugins/dashboard/kibana.json
@@ -13,6 +13,7 @@
"navigation",
"savedObjects",
"share",
+ "screenshotMode",
"uiActions",
"urlForwarding",
"presentationUtil",
diff --git a/src/plugins/dashboard/public/application/actions/add_to_library_action.test.tsx b/src/plugins/dashboard/public/application/actions/add_to_library_action.test.tsx
index fa484de2180b4..40f6f872535f9 100644
--- a/src/plugins/dashboard/public/application/actions/add_to_library_action.test.tsx
+++ b/src/plugins/dashboard/public/application/actions/add_to_library_action.test.tsx
@@ -15,6 +15,7 @@ import { CoreStart } from 'kibana/public';
import { coreMock, uiSettingsServiceMock } from '../../../../../core/public/mocks';
import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks';
import { getStubPluginServices } from '../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
import {
EmbeddableInput,
@@ -65,6 +66,7 @@ beforeEach(async () => {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
diff --git a/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx b/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx
index 99665d312d32e..fc4c6b299284b 100644
--- a/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx
+++ b/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx
@@ -23,6 +23,7 @@ import {
} from '../../services/embeddable_test_samples';
import { ErrorEmbeddable, IContainer, isErrorEmbeddable } from '../../services/embeddable';
import { getStubPluginServices } from '../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(
@@ -56,6 +57,7 @@ beforeEach(async () => {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
const input = getSampleDashboardInput({
panels: {
diff --git a/src/plugins/dashboard/public/application/actions/expand_panel_action.test.tsx b/src/plugins/dashboard/public/application/actions/expand_panel_action.test.tsx
index 0635152332993..b20a96c79aed6 100644
--- a/src/plugins/dashboard/public/application/actions/expand_panel_action.test.tsx
+++ b/src/plugins/dashboard/public/application/actions/expand_panel_action.test.tsx
@@ -13,6 +13,7 @@ import { getSampleDashboardInput, getSampleDashboardPanel } from '../test_helper
import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks';
import { isErrorEmbeddable } from '../../services/embeddable';
import { getStubPluginServices } from '../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
import {
CONTACT_CARD_EMBEDDABLE,
@@ -48,6 +49,7 @@ beforeEach(async () => {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
const input = getSampleDashboardInput({
panels: {
diff --git a/src/plugins/dashboard/public/application/actions/export_csv_action.test.tsx b/src/plugins/dashboard/public/application/actions/export_csv_action.test.tsx
index 51c64f1875376..797765eda232d 100644
--- a/src/plugins/dashboard/public/application/actions/export_csv_action.test.tsx
+++ b/src/plugins/dashboard/public/application/actions/export_csv_action.test.tsx
@@ -25,6 +25,7 @@ import { DataPublicPluginStart } from '../../../../data/public/types';
import { dataPluginMock } from '../../../../data/public/mocks';
import { LINE_FEED_CHARACTER } from 'src/plugins/data/common/exports/export_csv';
import { getStubPluginServices } from '../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
describe('Export CSV action', () => {
const { setup, doStart } = embeddablePluginMock.createInstance();
@@ -61,6 +62,7 @@ describe('Export CSV action', () => {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
const input = getSampleDashboardInput({
panels: {
diff --git a/src/plugins/dashboard/public/application/actions/library_notification_action.test.tsx b/src/plugins/dashboard/public/application/actions/library_notification_action.test.tsx
index 587f741461bb4..ab442bf839e37 100644
--- a/src/plugins/dashboard/public/application/actions/library_notification_action.test.tsx
+++ b/src/plugins/dashboard/public/application/actions/library_notification_action.test.tsx
@@ -28,6 +28,7 @@ import {
CONTACT_CARD_EMBEDDABLE,
} from '../../services/embeddable_test_samples';
import { getStubPluginServices } from '../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(
@@ -62,6 +63,7 @@ beforeEach(async () => {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
diff --git a/src/plugins/dashboard/public/application/actions/library_notification_popover.test.tsx b/src/plugins/dashboard/public/application/actions/library_notification_popover.test.tsx
index b5efa0447e651..de1a475fdbd18 100644
--- a/src/plugins/dashboard/public/application/actions/library_notification_popover.test.tsx
+++ b/src/plugins/dashboard/public/application/actions/library_notification_popover.test.tsx
@@ -29,6 +29,7 @@ import {
ContactCardEmbeddable,
} from '../../services/embeddable_test_samples';
import { getStubPluginServices } from '../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
describe('LibraryNotificationPopover', () => {
const { setup, doStart } = embeddablePluginMock.createInstance();
@@ -58,6 +59,7 @@ describe('LibraryNotificationPopover', () => {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
diff --git a/src/plugins/dashboard/public/application/actions/replace_panel_action.test.tsx b/src/plugins/dashboard/public/application/actions/replace_panel_action.test.tsx
index f8880ac5618fc..fe39f6112a7f3 100644
--- a/src/plugins/dashboard/public/application/actions/replace_panel_action.test.tsx
+++ b/src/plugins/dashboard/public/application/actions/replace_panel_action.test.tsx
@@ -22,6 +22,7 @@ import {
ContactCardEmbeddableOutput,
} from '../../services/embeddable_test_samples';
import { getStubPluginServices } from '../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(
@@ -48,6 +49,7 @@ beforeEach(async () => {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
const input = getSampleDashboardInput({
panels: {
diff --git a/src/plugins/dashboard/public/application/actions/unlink_from_library_action.test.tsx b/src/plugins/dashboard/public/application/actions/unlink_from_library_action.test.tsx
index 7d87c49bda649..4f10f833f643c 100644
--- a/src/plugins/dashboard/public/application/actions/unlink_from_library_action.test.tsx
+++ b/src/plugins/dashboard/public/application/actions/unlink_from_library_action.test.tsx
@@ -30,6 +30,7 @@ import {
CONTACT_CARD_EMBEDDABLE,
} from '../../services/embeddable_test_samples';
import { getStubPluginServices } from '../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
const { setup, doStart } = embeddablePluginMock.createInstance();
setup.registerEmbeddableFactory(
@@ -57,6 +58,7 @@ beforeEach(async () => {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreStart.http,
presentationUtil: getStubPluginServices(),
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
container = new DashboardContainer(getSampleDashboardInput(), containerOptions);
diff --git a/src/plugins/dashboard/public/application/dashboard_app.tsx b/src/plugins/dashboard/public/application/dashboard_app.tsx
index 3e6566f0da0a4..7aedbe9e11001 100644
--- a/src/plugins/dashboard/public/application/dashboard_app.tsx
+++ b/src/plugins/dashboard/public/application/dashboard_app.tsx
@@ -17,11 +17,11 @@ import {
getDashboardTitle,
leaveConfirmStrings,
} from '../dashboard_strings';
-import { EmbeddableRenderer } from '../services/embeddable';
+import { createDashboardEditUrl } from '../dashboard_constants';
+import { EmbeddableRenderer, ViewMode } from '../services/embeddable';
import { DashboardTopNav, isCompleteDashboardAppState } from './top_nav/dashboard_top_nav';
import { DashboardAppServices, DashboardEmbedSettings, DashboardRedirect } from '../types';
import { createKbnUrlStateStorage, withNotifyOnErrors } from '../services/kibana_utils';
-import { createDashboardEditUrl } from '../dashboard_constants';
export interface DashboardAppProps {
history: History;
savedDashboardId?: string;
@@ -51,7 +51,6 @@ export function DashboardApp({
const dashboardState = useDashboardSelector((state) => state.dashboardStateReducer);
const dashboardAppState = useDashboardAppState({
history,
- redirectTo,
savedDashboardId,
kbnUrlStateStorage,
isEmbeddedExternally: Boolean(embedSettings),
@@ -101,15 +100,26 @@ export function DashboardApp({
};
}, [data.search.session]);
+ const printMode = useMemo(
+ () => dashboardAppState.getLatestDashboardState?.().viewMode === ViewMode.PRINT,
+ [dashboardAppState]
+ );
+
+ useEffect(() => {
+ if (!embedSettings) chrome.setIsVisible(!printMode);
+ }, [chrome, printMode, embedSettings]);
+
return (
<>
{isCompleteDashboardAppState(dashboardAppState) && (
<>
-
+ {!printMode && (
+
+ )}
{dashboardAppState.savedDashboard.outcome === 'conflict' &&
dashboardAppState.savedDashboard.id &&
diff --git a/src/plugins/dashboard/public/application/dashboard_router.tsx b/src/plugins/dashboard/public/application/dashboard_router.tsx
index 4a22899c12e8a..c74ac506e4809 100644
--- a/src/plugins/dashboard/public/application/dashboard_router.tsx
+++ b/src/plugins/dashboard/public/application/dashboard_router.tsx
@@ -109,6 +109,7 @@ export async function mountApp({
embeddable: embeddableStart,
uiSettings: coreStart.uiSettings,
scopedHistory: () => scopedHistory,
+ screenshotModeService: screenshotMode,
indexPatterns: dataStart.indexPatterns,
savedQueryService: dataStart.query.savedQueries,
savedObjectsClient: coreStart.savedObjects.client,
@@ -131,7 +132,6 @@ export async function mountApp({
activeSpaceId || 'default'
),
spacesService: spacesApi,
- screenshotModeService: screenshotMode,
};
const getUrlStateStorage = (history: RouteComponentProps['history']) =>
diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx
index 6cd102a4d4770..744d63c1ba04a 100644
--- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.test.tsx
@@ -43,11 +43,13 @@ import { getStubPluginServices } from '../../../../presentation_util/public';
const presentationUtil = getStubPluginServices();
const options: DashboardContainerServices = {
+ // TODO: clean up use of any
application: {} as any,
embeddable: {} as any,
notifications: {} as any,
overlays: {} as any,
inspector: {} as any,
+ screenshotMode: {} as any,
SavedObjectFinder: () => null,
ExitFullScreenButton: () => null,
uiActions: {} as any,
diff --git a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
index 54fa1f05b9c0d..d7081bf020d85 100644
--- a/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx
@@ -40,6 +40,7 @@ import {
import { PLACEHOLDER_EMBEDDABLE } from './placeholder';
import { DashboardAppCapabilities, DashboardContainerInput } from '../../types';
import { PresentationUtilPluginStart } from '../../services/presentation_util';
+import type { ScreenshotModePluginStart } from '../../services/screenshot_mode';
import { PanelPlacementMethod, IPanelPlacementArgs } from './panel/dashboard_panel_placement';
import {
combineDashboardFiltersWithControlGroupFilters,
@@ -55,6 +56,7 @@ export interface DashboardContainerServices {
application: CoreStart['application'];
inspector: InspectorStartContract;
overlays: CoreStart['overlays'];
+ screenshotMode: ScreenshotModePluginStart;
uiSettings: IUiSettingsClient;
embeddable: EmbeddableStart;
uiActions: UiActionsStart;
diff --git a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx
index 52f04bcead665..7518a36433d35 100644
--- a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.test.tsx
@@ -23,6 +23,7 @@ import {
} from '../../../services/embeddable_test_samples';
import { coreMock, uiSettingsServiceMock } from '../../../../../../core/public/mocks';
import { getStubPluginServices } from '../../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../../screenshot_mode/public/mocks';
let dashboardContainer: DashboardContainer | undefined;
const presentationUtil = getStubPluginServices();
@@ -71,6 +72,7 @@ function prepare(props?: Partial) {
uiSettings: uiSettingsServiceMock.createStartContract(),
http: coreMock.createStart().http,
presentationUtil,
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
dashboardContainer = new DashboardContainer(initialInput, options);
const defaultTestProps: DashboardGridProps = {
diff --git a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx
index 9d2afdba36dbc..09ac0c1dd94bb 100644
--- a/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/grid/dashboard_grid.tsx
@@ -154,7 +154,7 @@ class DashboardGridUi extends React.Component {
id: 'dashboard.dashboardGrid.toast.unableToLoadDashboardDangerMessage',
defaultMessage: 'Unable to load dashboard.',
}),
- body: error.message,
+ body: (error as { message: string }).message,
toastLifeTimeMs: 5000,
});
}
@@ -254,6 +254,11 @@ class DashboardGridUi extends React.Component {
/>
));
+ // in print mode, dashboard layout is not controlled by React Grid Layout
+ if (viewMode === ViewMode.PRINT) {
+ return <>{dashboardPanels}>;
+ }
+
return (
;
type DivProps = Pick, 'className' | 'style' | 'children'>;
@@ -20,6 +21,7 @@ type DivProps = Pick, 'className' | 'style'
interface Props extends PanelProps, DivProps {
id: DashboardPanelState['explicitInput']['id'];
type: DashboardPanelState['type'];
+ container: DashboardContainer;
focusedPanelId?: string;
expandedPanelId?: string;
key: string;
@@ -52,6 +54,8 @@ const Item = React.forwardRef(
'dshDashboardGrid__item--expanded': expandPanel,
// eslint-disable-next-line @typescript-eslint/naming-convention
'dshDashboardGrid__item--hidden': hidePanel,
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ printViewport__vis: container.getInput().viewMode === ViewMode.PRINT,
});
return (
@@ -116,7 +120,8 @@ export const ObservedItem: FC = (props: Props) => {
export const DashboardGridItem: FC = (props: Props) => {
const { isProjectEnabled } = useLabs();
- const isEnabled = isProjectEnabled('labs:dashboard:deferBelowFold');
+ const isPrintMode = props.container.getInput().viewMode === ViewMode.PRINT;
+ const isEnabled = !isPrintMode && isProjectEnabled('labs:dashboard:deferBelowFold');
return isEnabled ? : ;
};
diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/_index.scss b/src/plugins/dashboard/public/application/embeddable/viewport/_index.scss
index 56483d9d10195..02411f5902b3b 100644
--- a/src/plugins/dashboard/public/application/embeddable/viewport/_index.scss
+++ b/src/plugins/dashboard/public/application/embeddable/viewport/_index.scss
@@ -1 +1,2 @@
@import './dashboard_viewport';
+@import './print_viewport';
diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/_print_viewport.scss b/src/plugins/dashboard/public/application/embeddable/viewport/_print_viewport.scss
new file mode 100644
index 0000000000000..a451178cc46b0
--- /dev/null
+++ b/src/plugins/dashboard/public/application/embeddable/viewport/_print_viewport.scss
@@ -0,0 +1,9 @@
+.printViewport {
+ &__vis {
+ height: 600px; // These values might need to be passed in as dimensions for the report. I.e., print should use layout dimensions.
+ width: 975px;
+
+ // Some vertical space between vis, but center horizontally
+ margin: 10px auto;
+ }
+}
diff --git a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx
index 7c671ce7736d7..f0333cefd612f 100644
--- a/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx
+++ b/src/plugins/dashboard/public/application/embeddable/viewport/dashboard_viewport.test.tsx
@@ -27,6 +27,7 @@ import {
CONTACT_CARD_EMBEDDABLE,
} from '../../../../../embeddable/public/lib/test_samples';
import { getStubPluginServices } from '../../../../../presentation_util/public';
+import { screenshotModePluginMock } from '../../../../../screenshot_mode/public/mocks';
let dashboardContainer: DashboardContainer | undefined;
const presentationUtil = getStubPluginServices();
@@ -65,6 +66,7 @@ function getProps(props?: Partial): {
getTriggerCompatibleActions: (() => []) as any,
} as any,
presentationUtil,
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
};
const input = getSampleDashboardInput({
diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx
index 5561d1676e41c..0ef21fca26f29 100644
--- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx
+++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx
@@ -52,7 +52,6 @@ const createDashboardAppStateProps = (): UseDashboardStateProps => ({
savedDashboardId: 'testDashboardId',
history: createBrowserHistory(),
isEmbeddedExternally: false,
- redirectTo: jest.fn(),
});
const createDashboardAppStateServices = () => {
diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
index fddcc309e1ef1..cb5c7483f261a 100644
--- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
+++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
@@ -22,7 +22,6 @@ import {
DashboardBuildContext,
DashboardAppServices,
DashboardAppState,
- DashboardRedirect,
DashboardState,
} from '../../types';
import { DashboardAppLocatorParams } from '../../locator';
@@ -44,14 +43,12 @@ import {
export interface UseDashboardStateProps {
history: History;
savedDashboardId?: string;
- redirectTo: DashboardRedirect;
isEmbeddedExternally: boolean;
kbnUrlStateStorage: IKbnUrlStateStorage;
}
export const useDashboardAppState = ({
history,
- redirectTo,
savedDashboardId,
kbnUrlStateStorage,
isEmbeddedExternally,
@@ -184,12 +181,20 @@ export const useDashboardAppState = ({
savedDashboard,
});
+ // Backwards compatible way of detecting that we are taking a screenshot
+ const legacyPrintLayoutDetected =
+ screenshotModeService?.isScreenshotMode() &&
+ screenshotModeService.getScreenshotLayout() === 'print';
+
const initialDashboardState = {
...savedDashboardState,
...dashboardSessionStorageState,
...initialDashboardStateFromUrl,
...forwardedAppState,
+ // if we are in legacy print mode, dashboard needs to be in print viewMode
+ ...(legacyPrintLayoutDetected ? { viewMode: ViewMode.PRINT } : {}),
+
// if there is an incoming embeddable, dashboard always needs to be in edit mode to receive it.
...(incomingEmbeddable ? { viewMode: ViewMode.EDIT } : {}),
};
diff --git a/src/plugins/dashboard/public/application/test_helpers/make_default_services.ts b/src/plugins/dashboard/public/application/test_helpers/make_default_services.ts
index cce2b4eb042ef..616fe56102df9 100644
--- a/src/plugins/dashboard/public/application/test_helpers/make_default_services.ts
+++ b/src/plugins/dashboard/public/application/test_helpers/make_default_services.ts
@@ -15,6 +15,7 @@ import { DashboardAppServices, DashboardAppCapabilities } from '../../types';
import { embeddablePluginMock } from '../../../../embeddable/public/mocks';
import { IndexPatternsContract, SavedQueryService } from '../../services/data';
import { savedObjectsPluginMock } from '../../../../saved_objects/public/mocks';
+import { screenshotModePluginMock } from '../../../../screenshot_mode/public/mocks';
import { visualizationsPluginMock } from '../../../../visualizations/public/mocks';
import { PluginInitializerContext, ScopedHistory } from '../../../../../core/public';
import { SavedObjectLoader, SavedObjectLoaderFindOptions } from '../../services/saved_objects';
@@ -72,6 +73,7 @@ export function makeDefaultServices(): DashboardAppServices {
} as PluginInitializerContext;
return {
+ screenshotModeService: screenshotModePluginMock.createSetupContract(),
visualizations: visualizationsPluginMock.createStartContract(),
savedObjects: savedObjectsPluginMock.createStartContract(),
embeddable: embeddablePluginMock.createInstance().doStart(),
diff --git a/src/plugins/dashboard/public/dashboard_constants.ts b/src/plugins/dashboard/public/dashboard_constants.ts
index 409d80e2ef066..6f9a30e3a7041 100644
--- a/src/plugins/dashboard/public/dashboard_constants.ts
+++ b/src/plugins/dashboard/public/dashboard_constants.ts
@@ -14,6 +14,7 @@ export const DashboardConstants = {
LANDING_PAGE_PATH: '/list',
CREATE_NEW_DASHBOARD_URL: '/create',
VIEW_DASHBOARD_URL: '/view',
+ PRINT_DASHBOARD_URL: '/print',
ADD_EMBEDDABLE_ID: 'addEmbeddableId',
ADD_EMBEDDABLE_TYPE: 'addEmbeddableType',
DASHBOARDS_ID: 'dashboards',
diff --git a/src/plugins/dashboard/public/locator.ts b/src/plugins/dashboard/public/locator.ts
index a256a65a5d7f4..b6655e246de36 100644
--- a/src/plugins/dashboard/public/locator.ts
+++ b/src/plugins/dashboard/public/locator.ts
@@ -128,6 +128,7 @@ export class DashboardAppLocatorDefinition implements LocatorDefinition => {
diff --git a/src/plugins/dashboard/public/plugin.tsx b/src/plugins/dashboard/public/plugin.tsx
index ff0ac0642ec91..9912aef943144 100644
--- a/src/plugins/dashboard/public/plugin.tsx
+++ b/src/plugins/dashboard/public/plugin.tsx
@@ -12,7 +12,6 @@ import { filter, map } from 'rxjs/operators';
import { Start as InspectorStartContract } from 'src/plugins/inspector/public';
import { UrlForwardingSetup, UrlForwardingStart } from 'src/plugins/url_forwarding/public';
-import { ScreenshotModePluginStart } from 'src/plugins/screenshot_mode/public';
import { APP_WRAPPER_CLASS } from '../../../core/public';
import {
App,
@@ -37,6 +36,10 @@ import { NavigationPublicPluginStart as NavigationStart } from './services/navig
import { DataPublicPluginSetup, DataPublicPluginStart, esFilters } from './services/data';
import { SharePluginSetup, SharePluginStart, UrlGeneratorContract } from './services/share';
import type { SavedObjectTaggingOssPluginStart } from './services/saved_objects_tagging_oss';
+import type {
+ ScreenshotModePluginSetup,
+ ScreenshotModePluginStart,
+} from './services/screenshot_mode';
import {
getSavedObjectFinder,
SavedObjectLoader,
@@ -102,6 +105,7 @@ export interface DashboardSetupDependencies {
share?: SharePluginSetup;
uiActions: UiActionsSetup;
usageCollection?: UsageCollectionSetup;
+ screenshotMode: ScreenshotModePluginSetup;
}
export interface DashboardStartDependencies {
@@ -116,9 +120,9 @@ export interface DashboardStartDependencies {
savedObjects: SavedObjectsStart;
presentationUtil: PresentationUtilPluginStart;
savedObjectsTaggingOss?: SavedObjectTaggingOssPluginStart;
- screenshotMode?: ScreenshotModePluginStart;
spaces?: SpacesPluginStart;
visualizations: VisualizationsStart;
+ screenshotMode: ScreenshotModePluginStart;
}
export interface DashboardSetup {
@@ -162,7 +166,15 @@ export class DashboardPlugin
public setup(
core: CoreSetup,
- { share, embeddable, home, urlForwarding, data, usageCollection }: DashboardSetupDependencies
+ {
+ share,
+ embeddable,
+ home,
+ urlForwarding,
+ data,
+ usageCollection,
+ screenshotMode,
+ }: DashboardSetupDependencies
): DashboardSetup {
this.dashboardFeatureFlagConfig =
this.initializerContext.config.get();
@@ -197,6 +209,7 @@ export class DashboardPlugin
embeddable: deps.embeddable,
uiActions: deps.uiActions,
inspector: deps.inspector,
+ screenshotMode: deps.screenshotMode,
http: coreStart.http,
ExitFullScreenButton,
presentationUtil: deps.presentationUtil,
diff --git a/src/plugins/dashboard/public/services/screenshot_mode.ts b/src/plugins/dashboard/public/services/screenshot_mode.ts
new file mode 100644
index 0000000000000..12ec1bca2207f
--- /dev/null
+++ b/src/plugins/dashboard/public/services/screenshot_mode.ts
@@ -0,0 +1,14 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export type {
+ ScreenshotModePluginStart,
+ ScreenshotModePluginSetup,
+} from '../../../screenshot_mode/public';
+
+export type { Layout } from '../../../screenshot_mode/common';
diff --git a/src/plugins/dashboard/public/types.ts b/src/plugins/dashboard/public/types.ts
index d4a6cb20bc551..b7b146aeba348 100644
--- a/src/plugins/dashboard/public/types.ts
+++ b/src/plugins/dashboard/public/types.ts
@@ -19,7 +19,6 @@ import type {
import { History } from 'history';
import { AnyAction, Dispatch } from 'redux';
import { BehaviorSubject, Subject } from 'rxjs';
-import { ScreenshotModePluginStart } from 'src/plugins/screenshot_mode/public';
import { Query, Filter, IndexPattern, RefreshInterval, TimeRange } from './services/data';
import { ContainerInput, EmbeddableInput, ViewMode } from './services/embeddable';
import { SharePluginStart } from './services/share';
@@ -33,6 +32,7 @@ import { SavedObjectsTaggingApi } from './services/saved_objects_tagging_oss';
import { DataPublicPluginStart, IndexPatternsContract } from './services/data';
import { SavedObjectLoader, SavedObjectsStart } from './services/saved_objects';
import { IKbnUrlStateStorage } from './services/kibana_utils';
+import type { ScreenshotModePluginStart } from './services/screenshot_mode';
import type { DashboardContainer, DashboardSavedObject } from '.';
import { VisualizationsStart } from '../../visualizations/public';
import { DashboardAppLocatorParams } from './locator';
@@ -206,9 +206,9 @@ export interface DashboardAppServices {
onAppLeave: AppMountParameters['onAppLeave'];
savedObjectsTagging?: SavedObjectsTaggingApi;
savedObjectsClient: SavedObjectsClientContract;
+ screenshotModeService: ScreenshotModePluginStart;
dashboardSessionStorage: DashboardSessionStorage;
setHeaderActionMenu: AppMountParameters['setHeaderActionMenu'];
savedQueryService: DataPublicPluginStart['query']['savedQueries'];
spacesService?: SpacesPluginStart;
- screenshotModeService?: ScreenshotModePluginStart;
}
diff --git a/src/plugins/embeddable/common/types.ts b/src/plugins/embeddable/common/types.ts
index c3cac2d5d67db..b9d9d4cc34146 100644
--- a/src/plugins/embeddable/common/types.ts
+++ b/src/plugins/embeddable/common/types.ts
@@ -13,6 +13,7 @@ import { PersistableStateService, PersistableState } from '../../kibana_utils/co
export enum ViewMode {
EDIT = 'edit',
PREVIEW = 'preview',
+ PRINT = 'print',
VIEW = 'view',
}
diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
index 9807a47698a50..6748e9f3b1d08 100644
--- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
+++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx
@@ -251,7 +251,7 @@ export class EmbeddablePanel extends React.Component {
};
public render() {
- const viewOnlyMode = this.state.viewMode === ViewMode.VIEW;
+ const viewOnlyMode = [ViewMode.VIEW, ViewMode.PRINT].includes(this.state.viewMode);
const classes = classNames('embPanel', {
'embPanel--editing': !viewOnlyMode,
'embPanel--loading': this.state.loading,
diff --git a/src/plugins/newsfeed/public/plugin.test.ts b/src/plugins/newsfeed/public/plugin.test.ts
index 4be69feb79f55..3497a1e52697d 100644
--- a/src/plugins/newsfeed/public/plugin.test.ts
+++ b/src/plugins/newsfeed/public/plugin.test.ts
@@ -10,6 +10,7 @@ import { take } from 'rxjs/operators';
import { coreMock } from '../../../core/public/mocks';
import { NewsfeedPublicPlugin } from './plugin';
import { NewsfeedApiEndpoint } from './lib/api';
+import { screenshotModePluginMock } from '../../screenshot_mode/public/mocks';
describe('Newsfeed plugin', () => {
let plugin: NewsfeedPublicPlugin;
@@ -46,7 +47,7 @@ describe('Newsfeed plugin', () => {
describe('base case', () => {
it('makes fetch requests', () => {
const startContract = plugin.start(coreMock.createStart(), {
- screenshotMode: { isScreenshotMode: () => false },
+ screenshotMode: screenshotModePluginMock.createSetupContract(),
});
const sub = startContract
.createNewsFeed$(NewsfeedApiEndpoint.KIBANA) // Any endpoint will do
@@ -60,8 +61,10 @@ describe('Newsfeed plugin', () => {
describe('when in screenshot mode', () => {
it('makes no fetch requests in screenshot mode', () => {
+ const screenshotMode = screenshotModePluginMock.createSetupContract();
+ screenshotMode.isScreenshotMode.mockReturnValue(true);
const startContract = plugin.start(coreMock.createStart(), {
- screenshotMode: { isScreenshotMode: () => true },
+ screenshotMode,
});
const sub = startContract
.createNewsFeed$(NewsfeedApiEndpoint.KIBANA) // Any endpoint will do
diff --git a/src/plugins/screenshot_mode/common/get_set_browser_screenshot_mode.ts b/src/plugins/screenshot_mode/common/get_set_browser_screenshot_mode.ts
index ff79ccf0126f4..850f70d2d002a 100644
--- a/src/plugins/screenshot_mode/common/get_set_browser_screenshot_mode.ts
+++ b/src/plugins/screenshot_mode/common/get_set_browser_screenshot_mode.ts
@@ -7,7 +7,7 @@
*/
// **PLEASE NOTE**
-// The functionality in this file targets a browser environment and is intended to be used both in public and server.
+// The functionality in this file targets a browser environment AND is intended to be used both in public and server.
// For instance, reporting uses these functions when starting puppeteer to set the current browser into "screenshot" mode.
export const KBN_SCREENSHOT_MODE_ENABLED_KEY = '__KBN_SCREENSHOT_MODE_ENABLED_KEY__';
@@ -61,3 +61,31 @@ export const setScreenshotModeDisabled = () => {
}
);
};
+
+/** @deprecated */
+export const KBN_SCREENSHOT_MODE_LAYOUT_KEY = '__KBN_SCREENSHOT_MODE_LAYOUT_KEY__';
+
+/** @deprecated */
+export type Layout = 'canvas' | 'preserve_layout' | 'print';
+
+/** @deprecated */
+export const setScreenshotLayout = (value: Layout) => {
+ Object.defineProperty(
+ window,
+ '__KBN_SCREENSHOT_MODE_LAYOUT_KEY__', // Literal value to prevent adding an external reference
+ {
+ enumerable: true,
+ writable: true,
+ configurable: false,
+ value,
+ }
+ );
+};
+
+/** @deprecated */
+export const getScreenshotLayout = (): undefined | Layout => {
+ return (
+ (window as unknown as Record)[KBN_SCREENSHOT_MODE_LAYOUT_KEY] ||
+ (window.localStorage.getItem(KBN_SCREENSHOT_MODE_LAYOUT_KEY) as Layout)
+ );
+};
diff --git a/src/plugins/screenshot_mode/common/index.ts b/src/plugins/screenshot_mode/common/index.ts
index 9c8c3d24ef289..949691911fc27 100644
--- a/src/plugins/screenshot_mode/common/index.ts
+++ b/src/plugins/screenshot_mode/common/index.ts
@@ -11,6 +11,11 @@ export {
setScreenshotModeEnabled,
setScreenshotModeDisabled,
KBN_SCREENSHOT_MODE_ENABLED_KEY,
+ KBN_SCREENSHOT_MODE_LAYOUT_KEY,
+ setScreenshotLayout,
+ getScreenshotLayout,
} from './get_set_browser_screenshot_mode';
+export type { Layout } from './get_set_browser_screenshot_mode';
+
export { KBN_SCREENSHOT_MODE_HEADER } from './constants';
diff --git a/src/plugins/screenshot_mode/public/mocks.ts b/src/plugins/screenshot_mode/public/mocks.ts
index 7fa93ff0bcea8..d7e69e9d89211 100644
--- a/src/plugins/screenshot_mode/public/mocks.ts
+++ b/src/plugins/screenshot_mode/public/mocks.ts
@@ -11,9 +11,11 @@ import type { ScreenshotModePluginSetup, ScreenshotModePluginStart } from './typ
export const screenshotModePluginMock = {
createSetupContract: (): DeeplyMockedKeys => ({
+ getScreenshotLayout: jest.fn(),
isScreenshotMode: jest.fn(() => false),
}),
createStartContract: (): DeeplyMockedKeys => ({
+ getScreenshotLayout: jest.fn(),
isScreenshotMode: jest.fn(() => false),
}),
};
diff --git a/src/plugins/screenshot_mode/public/plugin.ts b/src/plugins/screenshot_mode/public/plugin.ts
index a005bb7c3d055..bb34fe84e2c39 100644
--- a/src/plugins/screenshot_mode/public/plugin.ts
+++ b/src/plugins/screenshot_mode/public/plugin.ts
@@ -10,11 +10,12 @@ import { CoreSetup, CoreStart, Plugin } from '../../../core/public';
import { ScreenshotModePluginSetup, ScreenshotModePluginStart } from './types';
-import { getScreenshotMode } from '../common';
+import { getScreenshotMode, getScreenshotLayout } from '../common';
export class ScreenshotModePlugin implements Plugin {
private publicContract = Object.freeze({
isScreenshotMode: () => getScreenshotMode() === true,
+ getScreenshotLayout,
});
public setup(core: CoreSetup): ScreenshotModePluginSetup {
diff --git a/src/plugins/screenshot_mode/public/types.ts b/src/plugins/screenshot_mode/public/types.ts
index f6963de0cbd63..d1603cbceb26f 100644
--- a/src/plugins/screenshot_mode/public/types.ts
+++ b/src/plugins/screenshot_mode/public/types.ts
@@ -6,12 +6,17 @@
* Side Public License, v 1.
*/
+import type { Layout } from '../common';
+
export interface IScreenshotModeService {
/**
* Returns a boolean indicating whether the current user agent (browser) would like to view UI optimized for
* screenshots or printing.
*/
isScreenshotMode: () => boolean;
+
+ /** @deprecated */
+ getScreenshotLayout: () => undefined | Layout;
}
export type ScreenshotModePluginSetup = IScreenshotModeService;
diff --git a/src/plugins/screenshot_mode/server/plugin.ts b/src/plugins/screenshot_mode/server/plugin.ts
index 9295451f640c2..b885ff97bf262 100644
--- a/src/plugins/screenshot_mode/server/plugin.ts
+++ b/src/plugins/screenshot_mode/server/plugin.ts
@@ -30,10 +30,11 @@ export class ScreenshotModePlugin
// We use "require" here to ensure the import does not have external references due to code bundling that
// commonly happens during transpiling. External references would be missing in the environment puppeteer creates.
// eslint-disable-next-line @typescript-eslint/no-var-requires
- const { setScreenshotModeEnabled } = require('../common');
+ const { setScreenshotModeEnabled, setScreenshotLayout } = require('../common');
return {
setScreenshotModeEnabled,
+ setScreenshotLayout,
isScreenshotMode,
};
}
diff --git a/src/plugins/screenshot_mode/server/types.ts b/src/plugins/screenshot_mode/server/types.ts
index 566ae19719454..1b9f3868f0966 100644
--- a/src/plugins/screenshot_mode/server/types.ts
+++ b/src/plugins/screenshot_mode/server/types.ts
@@ -6,7 +6,8 @@
* Side Public License, v 1.
*/
-import { RequestHandlerContext, KibanaRequest } from 'src/core/server';
+import type { RequestHandlerContext, KibanaRequest } from 'src/core/server';
+import type { Layout } from '../common';
/**
* Any context that requires access to the screenshot mode flag but does not have access
@@ -23,6 +24,9 @@ export interface ScreenshotModePluginSetup {
* on the page have run to ensure that screenshot mode is detected as early as possible.
*/
setScreenshotModeEnabled: () => void;
+
+ /** @deprecated */
+ setScreenshotLayout: (value: Layout) => void;
}
export interface ScreenshotModePluginStart {
diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts
index 0947d24f827c2..0f2572ff2b2e4 100644
--- a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts
+++ b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts
@@ -17,7 +17,7 @@ import { ReportingCore } from '../../..';
import { KBN_SCREENSHOT_MODE_HEADER } from '../../../../../../../src/plugins/screenshot_mode/server';
import { ConditionalHeaders, ConditionalHeadersConditions } from '../../../export_types/common';
import { LevelLogger } from '../../../lib';
-import { ViewZoomWidthHeight } from '../../../lib/layouts/layout';
+import { Layout, ViewZoomWidthHeight } from '../../../lib/layouts/layout';
import { ElementPosition } from '../../../lib/screenshots';
import { allowRequest, NetworkPolicy } from '../../network_policy';
@@ -97,11 +97,13 @@ export class HeadlessChromiumDriver {
waitForSelector: pageLoadSelector,
timeout,
locator,
+ layout,
}: {
conditionalHeaders: ConditionalHeaders;
waitForSelector: string;
timeout: number;
locator?: LocatorParams;
+ layout?: Layout;
},
logger: LevelLogger
): Promise {
@@ -116,6 +118,10 @@ export class HeadlessChromiumDriver {
*/
await this.page.evaluateOnNewDocument(this.core.getEnableScreenshotMode());
+ if (layout) {
+ await this.page.evaluateOnNewDocument(this.core.getSetScreenshotLayout(), layout.id);
+ }
+
if (locator) {
await this.page.evaluateOnNewDocument(
(key: string, value: unknown) => {
diff --git a/x-pack/plugins/reporting/server/core.ts b/x-pack/plugins/reporting/server/core.ts
index bc74f5463ba33..43aefb73aebb9 100644
--- a/x-pack/plugins/reporting/server/core.ts
+++ b/x-pack/plugins/reporting/server/core.ts
@@ -253,9 +253,16 @@ export class ReportingCore {
.toPromise();
}
+ private getScreenshotModeDep() {
+ return this.getPluginSetupDeps().screenshotMode;
+ }
+
public getEnableScreenshotMode() {
- const { screenshotMode } = this.getPluginSetupDeps();
- return screenshotMode.setScreenshotModeEnabled;
+ return this.getScreenshotModeDep().setScreenshotModeEnabled;
+ }
+
+ public getSetScreenshotLayout() {
+ return this.getScreenshotModeDep().setScreenshotLayout;
}
/*
diff --git a/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.css b/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.css
index 508d217cdd030..60513c417165f 100644
--- a/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.css
+++ b/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.css
@@ -5,7 +5,7 @@
******
*/
- /**
+/**
* global
*/
@@ -27,7 +27,6 @@ filter-bar,
* Discover Tweaks
*/
-
/* hide unusable controls */
discover-app .dscTimechart,
discover-app .dscSidebar__container,
@@ -36,7 +35,6 @@ discover-app .discover-table-footer {
display: none;
}
-
/**
* The global banner (e.g. "Help us improve Elastic...") should not print.
*/
@@ -73,7 +71,8 @@ discover-app .discover-table-footer {
position: fixed;
width: 100%;
height: 100%;
- top: 0; left: 0;
+ top: 0;
+ left: 0;
}
/**
diff --git a/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.ts b/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.ts
index 424e85327c22b..7f6bc9e5d9505 100644
--- a/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.ts
+++ b/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.ts
@@ -4,7 +4,6 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-
import path from 'path';
import { CustomPageSize } from 'pdfmake/interfaces';
import { LAYOUT_TYPES } from '../../../common/constants';
@@ -37,6 +36,7 @@ export class PreserveLayout extends Layout implements LayoutInstance {
}
public getCssOverridesPath() {
+ // TODO: Remove this path once we have migrated all plugins away from depending on this hiding page elements.
return path.join(__dirname, 'preserve_layout.css');
}
diff --git a/x-pack/plugins/reporting/server/lib/layouts/print.css b/x-pack/plugins/reporting/server/lib/layouts/print.css
deleted file mode 100644
index 7d38ebe81e4e8..0000000000000
--- a/x-pack/plugins/reporting/server/lib/layouts/print.css
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- ******
- ****** This is a collection of CSS overrides that make Kibana look better for
- ****** generating PDF reports with headless browser
- ******
- */
-
-/**
- * global
- */
-
-/* elements can hide themselves when shared */
-.hide-for-sharing {
- display: none !important;
-}
-
-/* hide unusable controls */
-kbn-top-nav,
-filter-bar,
-.kbnTopNavMenu__wrapper,
-::-webkit-scrollbar,
-.euiNavDrawer {
- display: none !important;
-}
-
-/**
- * Discover Tweaks
- */
-
-/* hide unusable controls */
-discover-app .dscTimechart,
-discover-app .dscSidebar__container,
-discover-app .dscCollapsibleSidebar__collapseButton,
-discover-app .discover-table-footer {
- display: none;
-}
-
-/**
- * The global banner (e.g. "Help us improve Elastic...") should not print.
- */
-
-#globalBannerList {
- display: none;
-}
-
-/**
- * Visualize Editor Tweaks
- */
-
-/* hide unusable controls
-* !important is required to override resizable panel inline display */
-.visEditor__content .visEditor--default > :not(.visEditor__visualization__wrapper) {
- display: none !important;
-}
-/** THIS IS FOR TSVB UNTIL REFACTOR **/
-.tvbEditorVisualization {
- position: static !important;
-}
-.visualize .tvbVisTimeSeries__legendToggle,
-.tvbEditor--hideForReporting {
- /* all non-content rows in interface */
- display: none;
-}
-/** END TSVB BAD BAD HACKS **/
-
-/* remove left padding from visualizations so that map lines up with .leaflet-container and
-* setting the position to be fixed and to take up the entire screen, because some zoom levels/viewports
-* are triggering the media breakpoints that cause the .visEditor__canvas to take up more room than the viewport */
-.visEditor .visEditor__canvas {
- padding-left: 0px;
- position: fixed;
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
-}
-
-/**
- * Visualization tweaks
- */
-
-/* hide unusable controls */
-.visualize .visLegend__toggle,
-.visualize .kbnAggTable__controls/* export raw, export formatted, etc. */,
-.visualize .leaflet-container .leaflet-top.leaflet-left/* tilemap controls */,
-.visualize paginate-controls {
- display: none;
-}
-
-/* Ensure the min-height of the small breakpoint isn't used */
-.vis-editor visualization {
- min-height: 0 !important;
-}
-
-/**
-* Dashboard tweaks
-*/
-
-.dashboardViewport .embPanel__header {
- /* hide the panel heading with the controls and title */
- display: none !important;
-}
-
-.dashboardViewport .euiPanel {
- /* Remove the border from the eui panel */
- border: none !important;
-}
-
-/**
- * 1. Reporting manually makes each visualization it wants to screenshot larger, so we need to hide
- * the visualizations in the other panels. We can only use properties that will be manually set in
- * reporting/export_types/printable_pdf/lib/screenshot.js or this will also hide the visualization
- * we want to capture.
- * 2. React grid item's transform affects the visualizations, even when they are using fixed positioning. Chrome seems
- * to handle this fine, but firefox moves the visualizations around.
- */
-.dashboardViewport .react-grid-item {
- height: 0 !important; /* 1. */
- width: 0 !important; /* 1. */
- transform: none !important; /* 2. */
- -webkit-transform: none !important; /* 2. */
-}
diff --git a/x-pack/plugins/reporting/server/lib/layouts/print_layout.ts b/x-pack/plugins/reporting/server/lib/layouts/print_layout.ts
index 0849f8850f91d..68226affb41e4 100644
--- a/x-pack/plugins/reporting/server/lib/layouts/print_layout.ts
+++ b/x-pack/plugins/reporting/server/lib/layouts/print_layout.ts
@@ -5,13 +5,8 @@
* 2.0.
*/
-import path from 'path';
import { PageOrientation, PredefinedPageSize } from 'pdfmake/interfaces';
-import { EvaluateFn, SerializableOrJSHandle } from 'puppeteer';
-import { LevelLogger } from '../';
import { DEFAULT_VIEWPORT, LAYOUT_TYPES } from '../../../common/constants';
-import { Size } from '../../../common/types';
-import { HeadlessChromiumDriver } from '../../browsers';
import { CaptureConfig } from '../../types';
import { getDefaultLayoutSelectors, LayoutInstance, LayoutSelectorDictionary } from './';
import { Layout } from './layout';
@@ -31,7 +26,7 @@ export class PrintLayout extends Layout implements LayoutInstance {
}
public getCssOverridesPath() {
- return path.join(__dirname, 'print.css');
+ return undefined;
}
public getBrowserViewport() {
@@ -49,40 +44,6 @@ export class PrintLayout extends Layout implements LayoutInstance {
height: this.viewport.height * itemsCount,
};
}
-
- public async positionElements(
- browser: HeadlessChromiumDriver,
- logger: LevelLogger
- ): Promise {
- logger.debug('positioning elements');
-
- const elementSize: Size = {
- width: this.viewport.width / this.captureConfig.zoom,
- height: this.viewport.height / this.captureConfig.zoom,
- };
- const evalOptions: { fn: EvaluateFn; args: SerializableOrJSHandle[] } = {
- fn: (selector: string, height: number, width: number) => {
- const visualizations = document.querySelectorAll(selector) as NodeListOf;
- const visualizationsLength = visualizations.length;
-
- for (let i = 0; i < visualizationsLength; i++) {
- const visualization = visualizations[i];
- const style = visualization.style;
- style.position = 'fixed';
- style.top = `${height * i}px`;
- style.left = '0';
- style.width = `${width}px`;
- style.height = `${height}px`;
- style.zIndex = '1';
- style.backgroundColor = 'inherit';
- }
- },
- args: [this.selectors.screenshot, elementSize.height, elementSize.width],
- };
-
- await browser.evaluate(evalOptions, { context: 'PositionElements' }, logger);
- }
-
public getPdfImageSize() {
return {
width: 500,
diff --git a/x-pack/plugins/reporting/server/lib/screenshots/observable_handler.ts b/x-pack/plugins/reporting/server/lib/screenshots/observable_handler.ts
index 1db313b091025..cdbddb8d89c89 100644
--- a/x-pack/plugins/reporting/server/lib/screenshots/observable_handler.ts
+++ b/x-pack/plugins/reporting/server/lib/screenshots/observable_handler.ts
@@ -76,6 +76,7 @@ export class ScreenshotObservableHandler {
index,
urlOrUrlLocatorTuple,
this.conditionalHeaders,
+ this.layout,
this.logger
)
).pipe(this.waitUntil(this.timeouts.openUrl));
diff --git a/x-pack/plugins/reporting/server/lib/screenshots/open_url.ts b/x-pack/plugins/reporting/server/lib/screenshots/open_url.ts
index 63a5e80289e3e..b26037aa917b8 100644
--- a/x-pack/plugins/reporting/server/lib/screenshots/open_url.ts
+++ b/x-pack/plugins/reporting/server/lib/screenshots/open_url.ts
@@ -10,6 +10,7 @@ import { LevelLogger, startTrace } from '../';
import { LocatorParams, UrlOrUrlLocatorTuple } from '../../../common/types';
import { HeadlessChromiumDriver } from '../../browsers';
import { ConditionalHeaders } from '../../export_types/common';
+import { Layout } from '../layouts';
import { DEFAULT_PAGELOAD_SELECTOR } from './constants';
export const openUrl = async (
@@ -18,6 +19,7 @@ export const openUrl = async (
index: number,
urlOrUrlLocatorTuple: UrlOrUrlLocatorTuple,
conditionalHeaders: ConditionalHeaders,
+ layout: undefined | Layout,
logger: LevelLogger
): Promise => {
// If we're moving to another page in the app, we'll want to wait for the app to tell us
@@ -36,7 +38,11 @@ export const openUrl = async (
}
try {
- await browser.open(url, { conditionalHeaders, waitForSelector, timeout, locator }, logger);
+ await browser.open(
+ url,
+ { conditionalHeaders, waitForSelector, timeout, locator, layout },
+ logger
+ );
} catch (err) {
logger.error(err);
throw new Error(