Skip to content

Commit

Permalink
Merge branch 'main' into ELS-180
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Aug 21, 2023
2 parents 4e84f2e + 5f310f7 commit 8406317
Show file tree
Hide file tree
Showing 89 changed files with 597 additions and 659 deletions.
3 changes: 2 additions & 1 deletion .backportrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"repoName": "kibana",
"targetBranchChoices": [
"main",
"8.10",
"8.9",
"8.8",
"8.7",
Expand Down Expand Up @@ -46,7 +47,7 @@
"backport"
],
"branchLabelMapping": {
"^v8.10.0$": "main",
"^v8.11.0$": "main",
"^v(\\d+).(\\d+).\\d+$": "$1.$2"
},
"autoMerge": true,
Expand Down
2 changes: 0 additions & 2 deletions docs/CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ Review important information about the {kib} 8.x releases.
[[release-notes-8.9.1]]
== {kib} 8.9.1

coming::[8.9.1]

Review the following information about the {kib} 8.9.1 release.

[float]
Expand Down
8 changes: 8 additions & 0 deletions docs/user/ml/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,11 @@ point type selector to filter the results by specific types of change points.

[role="screenshot"]
image::user/ml/images/ml-change-point-detection-selected.png[Selected change points]


You can attach change point charts to a dashboard or a case by using the context
menu. If the split field is selected, you can either select specific charts
(partitions) or set the maximum number of top change points to plot. It's
possible to preserve the applied time range or use the time bound from the page
date picker. You can also add or edit change point charts directly from the
**Dashboard** app.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ export type TrustedAppConditionEntryField =
| 'process.hash.*'
| 'process.executable.caseless'
| 'process.Ext.code_signature';
export type BlocklistConditionEntryField = 'file.hash.*' | 'file.path' | 'file.Ext.code_signature';
export type BlocklistConditionEntryField =
| 'file.hash.*'
| 'file.path'
| 'file.Ext.code_signature'
| 'file.path.caseless';
export type AllConditionEntryFields =
| TrustedAppConditionEntryField
| BlocklistConditionEntryField
Expand Down
2 changes: 1 addition & 1 deletion src/dev/precommit_hook/casing_check_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const IGNORE_FILE_GLOBS = [
'x-pack/plugins/cases/docs/**/*',
'x-pack/plugins/monitoring/public/lib/jquery_flot/**/*',
'x-pack/plugins/fleet/cypress/packages/*.zip',
'x-pack/plugins/apm/ftr_e2e/cypress/e2e/power_user/diagnostics/apm-diagnostics-*.json',
'**/apm-diagnostics-*.json',
'**/.*',
'**/__mocks__/**/*',
'x-pack/docs/**/*',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@ import {
import { CoreStart } from '@kbn/core/public';
import { coreMock } from '@kbn/core/public/mocks';
import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks';
import { ErrorEmbeddable, IContainer, isErrorEmbeddable } from '@kbn/embeddable-plugin/public';
import {
ErrorEmbeddable,
IContainer,
isErrorEmbeddable,
ReferenceOrValueEmbeddable,
} from '@kbn/embeddable-plugin/public';

import { DashboardPanelState } from '../../common';
import { ClonePanelAction } from './clone_panel_action';
import { pluginServices } from '../services/plugin_services';
import { buildMockDashboard, getSampleDashboardPanel } from '../mocks';
import { DashboardContainer } from '../dashboard_container/embeddable/dashboard_container';

let container: DashboardContainer;
let byRefOrValEmbeddable: ContactCardEmbeddable;
let genericEmbeddable: ContactCardEmbeddable;
let byRefOrValEmbeddable: ContactCardEmbeddable & ReferenceOrValueEmbeddable;
let coreStart: CoreStart;
beforeEach(async () => {
coreStart = coreMock.createStart();
Expand Down Expand Up @@ -58,20 +62,22 @@ beforeEach(async () => {
>(CONTACT_CARD_EMBEDDABLE, {
firstName: 'RefOrValEmbeddable',
});
const genericContactCardEmbeddable = await container.addNewEmbeddable<

const nonRefOrValueContactCard = await container.addNewEmbeddable<
ContactCardEmbeddableInput,
ContactCardEmbeddableOutput,
ContactCardEmbeddable
>(CONTACT_CARD_EMBEDDABLE, {
firstName: 'NotRefOrValEmbeddable',
firstName: 'Not a refOrValEmbeddable',
});

if (
isErrorEmbeddable(refOrValContactCardEmbeddable) ||
isErrorEmbeddable(genericContactCardEmbeddable)
isErrorEmbeddable(nonRefOrValueContactCard)
) {
throw new Error('Failed to create embeddables');
} else {
genericEmbeddable = nonRefOrValueContactCard;
byRefOrValEmbeddable = embeddablePluginMock.mockRefOrValEmbeddable<
ContactCardEmbeddable,
ContactCardEmbeddableInput
Expand All @@ -80,14 +86,14 @@ beforeEach(async () => {
savedObjectId: 'testSavedObjectId',
id: refOrValContactCardEmbeddable.id,
},
mockedByValueInput: { firstName: 'Kibanana', id: refOrValContactCardEmbeddable.id },
mockedByValueInput: { firstName: 'RefOrValEmbeddable', id: refOrValContactCardEmbeddable.id },
});
genericEmbeddable = genericContactCardEmbeddable;
jest.spyOn(byRefOrValEmbeddable, 'getInputAsValueType');
}
});

test('Clone is incompatible with Error Embeddables', async () => {
const action = new ClonePanelAction(coreStart.savedObjects);
const action = new ClonePanelAction();
const errorEmbeddable = new ErrorEmbeddable('Wow what an awful error', { id: ' 404' }, container);
expect(await action.isCompatible({ embeddable: errorEmbeddable })).toBe(false);
});
Expand All @@ -96,134 +102,65 @@ test('Clone adds a new embeddable', async () => {
const dashboard = byRefOrValEmbeddable.getRoot() as IContainer;
const originalPanelCount = Object.keys(dashboard.getInput().panels).length;
const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels));
const action = new ClonePanelAction(coreStart.savedObjects);
const action = new ClonePanelAction();
await action.execute({ embeddable: byRefOrValEmbeddable });

expect(Object.keys(container.getInput().panels).length).toEqual(originalPanelCount + 1);
const newPanelId = Object.keys(container.getInput().panels).find(
(key) => !originalPanelKeySet.has(key)
);
expect(newPanelId).toBeDefined();
const newPanel = container.getInput().panels[newPanelId!];
expect(newPanel.type).toEqual('placeholder');
// let the placeholder load
await dashboard.untilEmbeddableLoaded(newPanelId!);
await new Promise((r) => process.nextTick(r)); // Allow the current loop of the event loop to run to completion
// now wait for the full embeddable to replace it
const loadedPanel = await dashboard.untilEmbeddableLoaded(newPanelId!);
expect(loadedPanel.type).toEqual(byRefOrValEmbeddable.type);
expect(newPanel.type).toEqual(byRefOrValEmbeddable.type);
});

test('Clones a RefOrVal embeddable by value', async () => {
const dashboard = byRefOrValEmbeddable.getRoot() as IContainer;
const panel = dashboard.getInput().panels[byRefOrValEmbeddable.id] as DashboardPanelState;
const action = new ClonePanelAction(coreStart.savedObjects);
// @ts-ignore
const newPanel = await action.cloneEmbeddable(panel, byRefOrValEmbeddable);
expect(coreStart.savedObjects.client.get).toHaveBeenCalledTimes(0);
expect(coreStart.savedObjects.client.find).toHaveBeenCalledTimes(0);
expect(coreStart.savedObjects.client.create).toHaveBeenCalledTimes(0);
expect(newPanel.type).toEqual(byRefOrValEmbeddable.type);
});
const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels));
const action = new ClonePanelAction();
await action.execute({ embeddable: byRefOrValEmbeddable });
const newPanelId = Object.keys(container.getInput().panels).find(
(key) => !originalPanelKeySet.has(key)
);

test('Clones a non-RefOrVal embeddable by value if the panel does not have a savedObjectId', async () => {
const dashboard = genericEmbeddable.getRoot() as IContainer;
const panel = dashboard.getInput().panels[genericEmbeddable.id] as DashboardPanelState;
const action = new ClonePanelAction(coreStart.savedObjects);
// @ts-ignore
const newPanelWithoutId = await action.cloneEmbeddable(panel, genericEmbeddable);
expect(coreStart.savedObjects.client.get).toHaveBeenCalledTimes(0);
expect(coreStart.savedObjects.client.find).toHaveBeenCalledTimes(0);
expect(coreStart.savedObjects.client.create).toHaveBeenCalledTimes(0);
expect(newPanelWithoutId.type).toEqual(genericEmbeddable.type);
});
const originalFirstName = (
container.getInput().panels[byRefOrValEmbeddable.id].explicitInput as ContactCardEmbeddableInput
).firstName;

test('Clones a non-RefOrVal embeddable by reference if the panel has a savedObjectId', async () => {
const dashboard = genericEmbeddable.getRoot() as IContainer;
const panel = dashboard.getInput().panels[genericEmbeddable.id] as DashboardPanelState;
panel.explicitInput.savedObjectId = 'holySavedObjectBatman';
const action = new ClonePanelAction(coreStart.savedObjects);
// @ts-ignore
const newPanel = await action.cloneEmbeddable(panel, genericEmbeddable);
expect(coreStart.savedObjects.client.get).toHaveBeenCalledTimes(1);
expect(coreStart.savedObjects.client.find).toHaveBeenCalledTimes(1);
expect(coreStart.savedObjects.client.create).toHaveBeenCalledTimes(1);
expect(newPanel.type).toEqual(genericEmbeddable.type);
const newFirstName = (
container.getInput().panels[newPanelId!].explicitInput as ContactCardEmbeddableInput
).firstName;

expect(byRefOrValEmbeddable.getInputAsValueType).toHaveBeenCalled();

expect(originalFirstName).toEqual(newFirstName);
expect(container.getInput().panels[newPanelId!].type).toEqual(byRefOrValEmbeddable.type);
});

test('Gets a unique title from the saved objects library', async () => {
test('Clones a non RefOrVal embeddable by value', async () => {
const dashboard = genericEmbeddable.getRoot() as IContainer;
const panel = dashboard.getInput().panels[genericEmbeddable.id] as DashboardPanelState;
panel.explicitInput.savedObjectId = 'holySavedObjectBatman';
coreStart.savedObjects.client.find = jest.fn().mockImplementation(({ search }) => {
if (search === '"testFirstClone"') {
return {
savedObjects: [
{
attributes: { title: 'testFirstClone' },
get: jest.fn().mockReturnValue('testFirstClone'),
},
],
total: 1,
};
} else if (search === '"testBeforePageLimit"') {
return {
savedObjects: [
{
attributes: { title: 'testBeforePageLimit (copy 9)' },
get: jest.fn().mockReturnValue('testBeforePageLimit (copy 9)'),
},
],
total: 10,
};
} else if (search === '"testMaxLogic"') {
return {
savedObjects: [
{
attributes: { title: 'testMaxLogic (copy 10000)' },
get: jest.fn().mockReturnValue('testMaxLogic (copy 10000)'),
},
],
total: 2,
};
} else if (search === '"testAfterPageLimit"') {
return { total: 11 };
}
});

const action = new ClonePanelAction(coreStart.savedObjects);
// @ts-ignore
expect(await action.getCloneTitle(genericEmbeddable, 'testFirstClone')).toEqual(
'testFirstClone (copy)'
);
// @ts-ignore
expect(await action.getCloneTitle(genericEmbeddable, 'testBeforePageLimit')).toEqual(
'testBeforePageLimit (copy 10)'
);
// @ts-ignore
expect(await action.getCloneTitle(genericEmbeddable, 'testBeforePageLimit (copy 9)')).toEqual(
'testBeforePageLimit (copy 10)'
);
// @ts-ignore
expect(await action.getCloneTitle(genericEmbeddable, 'testMaxLogic')).toEqual(
'testMaxLogic (copy 10001)'
);
// @ts-ignore
expect(await action.getCloneTitle(genericEmbeddable, 'testAfterPageLimit')).toEqual(
'testAfterPageLimit (copy 11)'
);
// @ts-ignore
expect(await action.getCloneTitle(genericEmbeddable, 'testAfterPageLimit (copy 10)')).toEqual(
'testAfterPageLimit (copy 11)'
);
// @ts-ignore
expect(await action.getCloneTitle(genericEmbeddable, 'testAfterPageLimit (copy 10000)')).toEqual(
'testAfterPageLimit (copy 11)'
const originalPanelKeySet = new Set(Object.keys(dashboard.getInput().panels));
const action = new ClonePanelAction();
await action.execute({ embeddable: genericEmbeddable });
const newPanelId = Object.keys(container.getInput().panels).find(
(key) => !originalPanelKeySet.has(key)
);

const originalFirstName = (
container.getInput().panels[genericEmbeddable.id].explicitInput as ContactCardEmbeddableInput
).firstName;

const newFirstName = (
container.getInput().panels[newPanelId!].explicitInput as ContactCardEmbeddableInput
).firstName;

expect(originalFirstName).toEqual(newFirstName);
expect(container.getInput().panels[newPanelId!].type).toEqual(genericEmbeddable.type);
});

test('Gets a unique title from the dashboard', async () => {
const dashboard = genericEmbeddable.getRoot() as DashboardContainer;
const action = new ClonePanelAction(coreStart.savedObjects);
const dashboard = byRefOrValEmbeddable.getRoot() as DashboardContainer;
const action = new ClonePanelAction();

// @ts-ignore
expect(await action.getCloneTitle(byRefOrValEmbeddable, '')).toEqual('');
Expand Down
Loading

0 comments on commit 8406317

Please sign in to comment.