Skip to content

Commit

Permalink
Merge branch 'main' into feature/130438
Browse files Browse the repository at this point in the history
  • Loading branch information
dej611 committed Mar 30, 2023
2 parents 82c18f1 + 4f13816 commit 719afe2
Show file tree
Hide file tree
Showing 207 changed files with 4,113 additions and 1,483 deletions.
6 changes: 6 additions & 0 deletions .buildkite/pipelines/artifacts_trigger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
steps:
- command: .buildkite/scripts/steps/artifacts/trigger.sh
label: Trigger artifacts build
agents:
queue: kibana-default
timeout_in_minutes: 10
7 changes: 7 additions & 0 deletions .buildkite/scripts/steps/artifacts/env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,16 @@ else
WORKFLOW="snapshot"
fi

ARTIFACTS_SUBDOMAIN="artifacts-$WORKFLOW"
ARTIFACTS_MANIFEST_FQDN="https://$ARTIFACTS_SUBDOMAIN.elastic.co"
KIBANA_MANIFEST_LATEST="$ARTIFACTS_MANIFEST_FQDN/kibana/latest/$FULL_VERSION.json"
BEATS_MANIFEST_LATEST="$ARTIFACTS_MANIFEST_FQDN/beats/latest/$FULL_VERSION.json"

export VERSION_QUALIFIER
export BASE_VERSION
export QUALIFIER_VERSION
export FULL_VERSION
export BUILD_ARGS
export WORKFLOW
export KIBANA_MANIFEST_LATEST
export BEATS_MANIFEST_LATEST
5 changes: 2 additions & 3 deletions .buildkite/scripts/steps/artifacts/publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,12 @@ if [[ "$BUILDKITE_BRANCH" == "$KIBANA_BASE_BRANCH" ]]; then
--dependency "beats:$BEATS_MANIFEST_URL" \
--artifact-set main

ARTIFACTS_SUBDOMAIN="artifacts-$WORKFLOW"
ARTIFACTS_SUMMARY=$(curl -s "https://$ARTIFACTS_SUBDOMAIN.elastic.co/kibana/latest/$FULL_VERSION.json" | jq -re '.summary_url')
KIBANA_SUMMARY=$(curl -s "$KIBANA_MANIFEST_LATEST" | jq -re '.summary_url')

cat << EOF | buildkite-agent annotate --style "info" --context artifacts-summary
### Artifacts Summary
$ARTIFACTS_SUMMARY
$KIBANA_SUMMARY
EOF

else
Expand Down
20 changes: 20 additions & 0 deletions .buildkite/scripts/steps/artifacts/trigger.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

set -euo pipefail

source .buildkite/scripts/steps/artifacts/env.sh

BEATS_MANIFEST_LATEST_URL=$(curl "$BEATS_MANIFEST_LATEST" | jq -r '.manifest_url')
KIBANA_MANIFEST_URL=$(curl "$KIBANA_MANIFEST_LATEST" | jq -r '.manifest_url')
KIBANA_BEATS_MANIFEST_URL=$(curl $KIBANA_MANIFEST_URL | jq -r '.projects.kibana.dependencies[] | select(.prefix == "beats") | .build_uri')

echo "--- Trigger artifact builds"
if [ "$BEATS_MANIFEST_LATEST_URL" = "$KIBANA_BEATS_MANIFEST_URL" ]; then
echo "Kibana has the latest version of beats, skipping trigger"
else
# Staging builds are not necessary on main
if [[ "$BUILDKITE_BRANCH" != "main" ]]; then
ts-node .buildkite/scripts/steps/trigger_pipeline.ts kibana-artifacts-staging "$BUILDKITE_BRANCH"
fi
ts-node .buildkite/scripts/steps/trigger_pipeline.ts kibana-artifacts-snapshot "$BUILDKITE_BRANCH"
fi
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,6 @@
"react-tiny-virtual-list": "^2.2.0",
"react-use": "^15.3.8",
"react-virtualized": "^9.22.3",
"react-vis": "^1.8.1",
"react-visibility-sensor": "^5.1.1",
"recompose": "^0.30.0",
"reduce-reducers": "^1.0.4",
Expand Down Expand Up @@ -1252,7 +1251,6 @@
"@types/react-syntax-highlighter": "^15.4.0",
"@types/react-test-renderer": "^17.0.2",
"@types/react-virtualized": "^9.21.21",
"@types/react-vis": "^1.11.9",
"@types/recompose": "^0.30.10",
"@types/redux-actions": "^2.6.1",
"@types/redux-logger": "^3.0.8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,4 @@
* Side Public License, v 1.
*/

// TODO: https://github.com/elastic/kibana/issues/110891
/* eslint-disable @kbn/eslint/no_export_all */

export * from './constants';
export { EXPRESSION_NAME, ScaleOptions, Orientation } from './constants';
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { discoverServiceMock } from '../__mocks__/services';
import { SavedSearchEmbeddable, SearchEmbeddableConfig } from './saved_search_embeddable';
import { render } from 'react-dom';
import { createSearchSourceMock } from '@kbn/data-plugin/public/mocks';
import { of, throwError } from 'rxjs';
import { Observable, of, throwError } from 'rxjs';
import { ReactWrapper } from 'enzyme';
import { SHOW_FIELD_STATISTICS } from '../../common';
import { IUiSettingsClient } from '@kbn/core-ui-settings-browser';
Expand Down Expand Up @@ -57,11 +57,12 @@ describe('saved search embeddable', () => {
let viewModeMockValue: VIEW_MODE = VIEW_MODE.DOCUMENT_LEVEL;

const createEmbeddable = (searchMock?: jest.Mock, customTitle?: string) => {
const searchSource = createSearchSourceMock({ index: dataViewMock }, undefined, searchMock);
const savedSearchMock = {
id: 'mock-id',
title: 'saved search',
sort: [['message', 'asc']] as Array<[string, string]>,
searchSource: createSearchSourceMock({ index: dataViewMock }, undefined, searchMock),
searchSource,
viewMode: viewModeMockValue,
};

Expand Down Expand Up @@ -102,7 +103,7 @@ describe('saved search embeddable', () => {
(input) => (input.lastReloadRequestTime = Date.now())
);

return { embeddable, searchInput };
return { embeddable, searchInput, searchSource };
};

beforeEach(() => {
Expand Down Expand Up @@ -304,6 +305,7 @@ describe('saved search embeddable', () => {
expect(embeddable.reload).toHaveBeenCalledTimes(1);
expect(search).toHaveBeenCalledTimes(1);
});

it('should not reload and fetch when a input title matches the saved search title', async () => {
const search = jest.fn().mockReturnValue(getSearchResponse(1));
const { embeddable } = createEmbeddable(search);
Expand All @@ -316,4 +318,30 @@ describe('saved search embeddable', () => {
expect(embeddable.reload).toHaveBeenCalledTimes(0);
expect(search).toHaveBeenCalledTimes(1);
});

it('should correctly handle aborted requests', async () => {
const { embeddable, searchSource } = createEmbeddable();
await waitOneTick();
const updateOutput = jest.spyOn(embeddable, 'updateOutput');
const abortSignals: AbortSignal[] = [];
jest.spyOn(searchSource, 'fetch$').mockImplementation(
(options) =>
new Observable(() => {
if (options?.abortSignal) {
abortSignals.push(options.abortSignal);
}
throw new Error('Search failed');
})
);
embeddable.reload();
embeddable.reload();
await waitOneTick();
expect(updateOutput).toHaveBeenCalledTimes(3);
expect(abortSignals[0].aborted).toBe(true);
expect(abortSignals[1].aborted).toBe(false);
embeddable.reload();
await waitOneTick();
expect(updateOutput).toHaveBeenCalledTimes(5);
expect(abortSignals[2].aborted).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,11 @@ export class SavedSearchEmbeddable

const { searchSource } = this.savedSearch;

const prevAbortController = this.abortController;
// Abort any in-progress requests
if (this.abortController) this.abortController.abort();
this.abortController = new AbortController();

const currentAbortController = new AbortController();
this.abortController = currentAbortController;

updateSearchSource(
searchSource,
Expand Down Expand Up @@ -253,7 +254,7 @@ export class SavedSearchEmbeddable
// Request document data
const { rawResponse: resp } = await lastValueFrom(
searchSource.fetch$({
abortSignal: this.abortController.signal,
abortSignal: currentAbortController.signal,
sessionId: searchSessionId,
inspector: {
adapter: this.inspectorAdapters.requests,
Expand All @@ -280,7 +281,7 @@ export class SavedSearchEmbeddable
this.searchProps!.totalHitCount = resp.hits.total as number;
this.searchProps!.isLoading = false;
} catch (error) {
const cancelled = !!prevAbortController?.signal.aborted;
const cancelled = !!currentAbortController?.signal.aborted;
if (!this.destroyed && !cancelled) {
this.updateOutput({
...this.getOutput(),
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/image_embeddable/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"uiActions"
],
"optionalPlugins": [
"security"
"security",
"screenshotMode",
],
"requiredBundles": [
"kibanaUtils",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -88,6 +89,7 @@ export class ImageEmbeddable extends Embeddable<ImageEmbeddableInput> {
<ImageViewer
className="imageEmbeddableImage"
imageConfig={input.imageConfig}
isScreenshotMode={this.deps.isScreenshotMode()}
onLoad={() => {
this.renderComplete.dispatchComplete();
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface ImageEmbeddableFactoryDeps {
theme: ThemeServiceStart;
getUser: () => Promise<AuthenticatedUser | undefined>;
uiActions: UiActionsStart;
isScreenshotMode: () => boolean;
};
}

Expand Down Expand Up @@ -68,6 +69,7 @@ export class ImageEmbeddableFactoryDefinition
.catch(() => [])
.then((actions) => actions.length > 0),
},
isScreenshotMode: () => this.deps.start().isScreenshotMode(),
},
initialInput,
parent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ beforeEach(() => {
validateUrl.mockImplementation(() => ({ isValid: true }));
});

const DefaultImageViewer = (props: { imageConfig: ImageConfig }) => {
const DefaultImageViewer = (props: { imageConfig: ImageConfig; isScreenshotMode?: boolean }) => {
return (
<ImageViewerContext.Provider
value={{
getImageDownloadHref: (fileId: string) => `https://elastic.co/${fileId}`,
validateUrl,
}}
>
<ImageViewer imageConfig={props.imageConfig} />
<ImageViewer imageConfig={props.imageConfig} isScreenshotMode={props.isScreenshotMode} />
</ImageViewerContext.Provider>
);
};
Expand Down Expand Up @@ -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');
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface ImageViewerProps {
onLoad?: () => void;
onClick?: () => void;
containerCSS?: SerializedStyles;
isScreenshotMode?: boolean;
}

export function ImageViewer({
Expand All @@ -47,6 +48,7 @@ export function ImageViewer({
onClick,
className,
containerCSS,
isScreenshotMode,
}: ImageViewerProps) {
const { euiTheme } = useEuiTheme();
const { getImageDownloadHref, validateUrl } = useImageViewerContext();
Expand Down Expand Up @@ -96,6 +98,7 @@ export function ImageViewer({
})
: undefined
}
loading={isScreenshotMode ? 'eager' : 'lazy'}
style={{
width: '100%',
height: '100%',
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/image_embeddable/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -20,13 +24,15 @@ export interface SetupDependencies {
files: FilesSetup;
security?: SecurityPluginSetup;
uiActions: UiActionsSetup;
screenshotMode?: ScreenshotModePluginSetup;
}

export interface StartDependencies {
embeddable: EmbeddableStart;
files: FilesStart;
security?: SecurityPluginStart;
uiActions: UiActionsStart;
screenshotMode?: ScreenshotModePluginStart;
}

// eslint-disable-next-line @typescript-eslint/no-empty-interface
Expand Down Expand Up @@ -56,6 +62,7 @@ export class ImageEmbeddablePlugin
return security ? await security.authc.getCurrentUser() : undefined;
},
uiActions: start().plugins.uiActions,
isScreenshotMode: () => plugins.screenshotMode?.isScreenshotMode() ?? false,
}),
})
);
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/image_embeddable/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/**/*",
Expand Down
24 changes: 18 additions & 6 deletions src/plugins/vis_default_editor/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,33 @@
* Side Public License, v 1.
*/

// TODO: https://github.com/elastic/kibana/issues/110891
/* eslint-disable @kbn/eslint/no_export_all */

import { PluginInitializerContext } from '@kbn/core/public';
import { DefaultEditorController } from './default_editor_controller';
import { VisDefaultEditorPlugin } from './plugin';

export { DefaultEditorController };
export { useValidation } from './components/controls/utils';
export { PalettePicker } from './components/controls/palette_picker';
export * from './components/options';
export {
SwitchOption,
TextInputOption,
RangeOption,
SelectOption,
ColorSchemaOptions,
PercentageModeOption,
NumberInputOption,
RequiredNumberInputOption,
LongLegendOptions,
LegendSizeSettings,
ColorRanges,
BasicOptions,
type SetColorRangeValue,
type SetColorSchemaOptionsValue,
} from './components/options';
export type { RangeValues } from './components/controls/ranges';
export { RangesParamEditor } from './components/controls/ranges';
export * from './editor_size';
export * from './utils';
export { groupAndSortBy } from './utils';
export { DefaultEditorSize } from './editor_size';

export const plugin = (context: PluginInitializerContext) => {
return new VisDefaultEditorPlugin();
Expand Down
Loading

0 comments on commit 719afe2

Please sign in to comment.