[Reporting/Image] Fix report generation when image panel is in the end of the layout (#153846)

## Summary

Fix https://github.com/elastic/kibana/issues/153673

Images are lazy by default. This prevented reports from completing
because an image was never loaded if the image was not in the viewport .
The fix is to make image loading eagerly when in screenshot mode.
This commit is contained in:
Anton Dosov 2023-03-30 15:15:19 +02:00 committed by GitHub
parent d6c5c8210b
commit 04b2d316b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 4 deletions

View file

@ -13,7 +13,8 @@
"uiActions"
],
"optionalPlugins": [
"security"
"security",
"screenshotMode",
],
"requiredBundles": [
"kibanaUtils",

View file

@ -31,6 +31,7 @@ export class ImageEmbeddable extends Embeddable<ImageEmbeddableInput> {
executeTriggerActions: (triggerId: string, context: ImageClickContext) => void;
hasTriggerActions: (triggerId: string, context: ImageClickContext) => Promise<boolean>;
};
isScreenshotMode: () => boolean;
},
initialInput: ImageEmbeddableInput,
parent?: IContainer
@ -88,6 +89,7 @@ export class ImageEmbeddable extends Embeddable<ImageEmbeddableInput> {
<ImageViewer
className="imageEmbeddableImage"
imageConfig={input.imageConfig}
isScreenshotMode={this.deps.isScreenshotMode()}
onLoad={() => {
this.renderComplete.dispatchComplete();
}}

View file

@ -35,6 +35,7 @@ export interface ImageEmbeddableFactoryDeps {
theme: ThemeServiceStart;
getUser: () => Promise<AuthenticatedUser | undefined>;
uiActions: UiActionsStart;
isScreenshotMode: () => boolean;
};
}
@ -68,6 +69,7 @@ export class ImageEmbeddableFactoryDefinition
.catch(() => [])
.then((actions) => actions.length > 0),
},
isScreenshotMode: () => this.deps.start().isScreenshotMode(),
},
initialInput,
parent

View file

@ -18,7 +18,7 @@ beforeEach(() => {
validateUrl.mockImplementation(() => ({ isValid: true }));
});
const DefaultImageViewer = (props: { imageConfig: ImageConfig }) => {
const DefaultImageViewer = (props: { imageConfig: ImageConfig; isScreenshotMode?: boolean }) => {
return (
<ImageViewerContext.Provider
value={{
@ -26,7 +26,7 @@ const DefaultImageViewer = (props: { imageConfig: ImageConfig }) => {
validateUrl,
}}
>
<ImageViewer imageConfig={props.imageConfig} />
<ImageViewer imageConfig={props.imageConfig} isScreenshotMode={props.isScreenshotMode} />
</ImageViewerContext.Provider>
);
};
@ -75,3 +75,32 @@ test('should display an image by file id', () => {
expect(getByAltText(`alt text`)).toBeVisible();
expect(getByAltText(`alt text`)).toHaveAttribute('src', 'https://elastic.co/imageId');
});
test('image is lazy by default', () => {
const { getByAltText } = render(
<DefaultImageViewer
imageConfig={{
src: { type: 'url', url: 'https://elastic.co/image' },
sizing: { objectFit: 'fill' },
altText: 'alt text',
}}
/>
);
expect(getByAltText(`alt text`)).toHaveAttribute('loading', 'lazy');
});
test('image is eager when in screenshotting mode', () => {
const { getByAltText } = render(
<DefaultImageViewer
imageConfig={{
src: { type: 'url', url: 'https://elastic.co/image' },
sizing: { objectFit: 'fill' },
altText: 'alt text',
}}
isScreenshotMode={true}
/>
);
expect(getByAltText(`alt text`)).toHaveAttribute('loading', 'eager');
});

View file

@ -36,6 +36,7 @@ export interface ImageViewerProps {
onLoad?: () => void;
onClick?: () => void;
containerCSS?: SerializedStyles;
isScreenshotMode?: boolean;
}
export function ImageViewer({
@ -47,6 +48,7 @@ export function ImageViewer({
onClick,
className,
containerCSS,
isScreenshotMode,
}: ImageViewerProps) {
const { euiTheme } = useEuiTheme();
const { getImageDownloadHref, validateUrl } = useImageViewerContext();
@ -96,6 +98,7 @@ export function ImageViewer({
})
: undefined
}
loading={isScreenshotMode ? 'eager' : 'lazy'}
style={{
width: '100%',
height: '100%',

View file

@ -12,6 +12,10 @@ import { createStartServicesGetter } from '@kbn/kibana-utils-plugin/public';
import { FilesSetup, FilesStart } from '@kbn/files-plugin/public';
import { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public';
import { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public';
import {
ScreenshotModePluginSetup,
ScreenshotModePluginStart,
} from '@kbn/screenshot-mode-plugin/public';
import { IMAGE_EMBEDDABLE_TYPE, ImageEmbeddableFactoryDefinition } from './image_embeddable';
import { imageClickTrigger } from './actions';
@ -20,6 +24,7 @@ export interface SetupDependencies {
files: FilesSetup;
security?: SecurityPluginSetup;
uiActions: UiActionsSetup;
screenshotMode?: ScreenshotModePluginSetup;
}
export interface StartDependencies {
@ -27,6 +32,7 @@ export interface StartDependencies {
files: FilesStart;
security?: SecurityPluginStart;
uiActions: UiActionsStart;
screenshotMode?: ScreenshotModePluginStart;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@ -56,6 +62,7 @@ export class ImageEmbeddablePlugin
return security ? await security.authc.getCurrentUser() : undefined;
},
uiActions: start().plugins.uiActions,
isScreenshotMode: () => plugins.screenshotMode?.isScreenshotMode() ?? false,
}),
})
);

View file

@ -20,7 +20,8 @@
"@kbn/i18n",
"@kbn/core-http-browser",
"@kbn/shared-ux-file-image",
"@kbn/ui-actions-plugin"
"@kbn/ui-actions-plugin",
"@kbn/screenshot-mode-plugin"
],
"exclude": [
"target/**/*",