Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/elastic/kibana into move-st…
Browse files Browse the repository at this point in the history
…ructure-basic-detection_engine:wq
  • Loading branch information
WafaaNasr committed Nov 21, 2023
2 parents aca34ad + e79ca5e commit f229f3b
Show file tree
Hide file tree
Showing 95 changed files with 2,645 additions and 1,347 deletions.
6 changes: 3 additions & 3 deletions .buildkite/pull_requests.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@
"repoName": "kibana",
"pipelineSlug": "kibana-kme-test",

"enabled": true,
"enabled": false,
"allow_org_users": true,
"allowed_repo_permissions": ["admin", "write"],
"allowed_list": ["barlowm", "renovate[bot]"],
"set_commit_status": true,
"commit_status_context": "kibana-ci-test",
"commit_status_context": "kibana-ci",
"build_on_commit": true,
"build_on_comment": false,
"build_on_comment": true,
"trigger_comment_regex": "^(?:(?:buildkite\\W+)?(?:build|test)\\W+(?:this|it))",
"always_trigger_comment_regex": "^(?:(?:buildkite\\W+)?(?:build|test)\\W+(?:this|it))",
"skip_ci_labels": [],
Expand Down
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ x-pack/packages/ml/route_utils @elastic/ml-ui
x-pack/packages/ml/runtime_field_utils @elastic/ml-ui
x-pack/packages/ml/string_hash @elastic/ml-ui
x-pack/packages/ml/trained_models_utils @elastic/ml-ui
x-pack/packages/ml/ui_actions @elastic/ml-ui
x-pack/packages/ml/url_state @elastic/ml-ui
packages/kbn-monaco @elastic/appex-sharedux
x-pack/plugins/monitoring_collection @elastic/obs-ux-infra_services-team
Expand Down
3 changes: 1 addition & 2 deletions docs/user/plugins.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ Use it to create, edit and embed visualizations, and also to search inside an em

* https://github.com/sw-jung/kibana_markdown_doc_view[Markdown Doc View] (sw-jung) - A plugin for custom doc view using markdown+handlebars template.
* https://github.com/datasweet-fr/kibana-datasweet-formula[Datasweet Formula] (datasweet) - enables calculated metric on any standard Kibana visualization.
* https://github.com/pjhampton/kibana-prometheus-exporter[Prometheus Exporter] - exports the Kibana metrics in the prometheus format

NOTE: To add your plugin to this page, open a {kib-repo}tree/{branch}/docs/plugins/known-plugins.asciidoc[pull request].

Expand Down Expand Up @@ -183,4 +182,4 @@ you must specify the path to that configuration file each time you use the `bin/
0:: Success
64:: Unknown command or incorrect option parameter
74:: I/O error
70:: Other error
70:: Other error
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@
"@kbn/ml-runtime-field-utils": "link:x-pack/packages/ml/runtime_field_utils",
"@kbn/ml-string-hash": "link:x-pack/packages/ml/string_hash",
"@kbn/ml-trained-models-utils": "link:x-pack/packages/ml/trained_models_utils",
"@kbn/ml-ui-actions": "link:x-pack/packages/ml/ui_actions",
"@kbn/ml-url-state": "link:x-pack/packages/ml/url_state",
"@kbn/monaco": "link:packages/kbn-monaco",
"@kbn/monitoring-collection-plugin": "link:x-pack/plugins/monitoring_collection",
Expand Down Expand Up @@ -1469,7 +1470,7 @@
"blob-polyfill": "^7.0.20220408",
"callsites": "^3.1.0",
"chance": "1.0.18",
"chromedriver": "^119.0.0",
"chromedriver": "^119.0.1",
"clean-webpack-plugin": "^3.0.0",
"cli-table3": "^0.6.1",
"copy-webpack-plugin": "^6.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Side Public License, v 1.
*/

import * as RxJS from 'rxjs';
import type { FullStoryApi } from './types';

export const fullStoryApiMock: jest.Mocked<FullStoryApi> = {
Expand All @@ -22,3 +23,10 @@ jest.doMock('./load_snippet', () => {
loadSnippet: () => fullStoryApiMock,
};
});

jest.doMock('rxjs', () => {
return {
...RxJS,
debounceTime: () => RxJS.identity,
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ describe('FullStoryShipper', () => {
);
});

afterEach(() => {
fullstoryShipper.shutdown();
});

describe('extendContext', () => {
describe('FS.identify', () => {
test('calls `identify` when the userId is provided', () => {
Expand Down Expand Up @@ -119,6 +123,21 @@ describe('FullStoryShipper', () => {
labels: { serverless_str: 'test' },
});
});

test('emits once only if nothing changes', () => {
const context = {
userId: 'test-user-id',
version: '1.2.3',
cloudId: 'test-es-org-id',
labels: { serverless: 'test' },
foo: 'bar',
};
fullstoryShipper.extendContext(context);
fullstoryShipper.extendContext(context);
expect(fullStoryApiMock.setVars).toHaveBeenCalledTimes(1);
fullstoryShipper.extendContext(context);
expect(fullStoryApiMock.setVars).toHaveBeenCalledTimes(1);
});
});
});

Expand Down
148 changes: 95 additions & 53 deletions packages/analytics/shippers/fullstory/src/fullstory_shipper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
Event,
IShipper,
} from '@kbn/analytics-client';
import { Subject, distinct, debounceTime, map, filter, Subscription } from 'rxjs';
import { get, has } from 'lodash';
import { set } from '@kbn/safer-lodash-set';
import type { FullStoryApi } from './types';
Expand Down Expand Up @@ -55,8 +56,18 @@ export interface FullStoryShipperConfig extends FullStorySnippetConfig {
* If this setting is provided, it'll only send the event types specified in this list.
*/
eventTypesAllowlist?: string[];
pageVarsDebounceTimeMs?: number;
}

interface FullStoryUserVars {
userId?: string;
isElasticCloudUser?: boolean;
cloudIsElasticStaffOwned?: boolean;
cloudTrialEndDate?: string;
}

type FullStoryPageContext = Pick<EventContext, typeof PAGE_VARS_KEYS[number]>;

/**
* FullStory shipper.
*/
Expand All @@ -67,6 +78,9 @@ export class FullStoryShipper implements IShipper {
private readonly fullStoryApi: FullStoryApi;
private lastUserId: string | undefined;
private readonly eventTypesAllowlist?: string[];
private readonly pageContext$ = new Subject<EventContext>();
private readonly userContext$ = new Subject<FullStoryUserVars>();
private readonly subscriptions = new Subscription();

/**
* Creates a new instance of the FullStoryShipper.
Expand All @@ -77,9 +91,54 @@ export class FullStoryShipper implements IShipper {
config: FullStoryShipperConfig,
private readonly initContext: AnalyticsClientInitContext
) {
const { eventTypesAllowlist, ...snippetConfig } = config;
const { eventTypesAllowlist, pageVarsDebounceTimeMs = 500, ...snippetConfig } = config;
this.fullStoryApi = loadSnippet(snippetConfig);
this.eventTypesAllowlist = eventTypesAllowlist;

this.subscriptions.add(
this.userContext$
.pipe(
distinct(({ userId, isElasticCloudUser, cloudIsElasticStaffOwned, cloudTrialEndDate }) =>
[userId, isElasticCloudUser, cloudIsElasticStaffOwned, cloudTrialEndDate].join('-')
)
)
.subscribe((userVars) => this.updateUserVars(userVars))
);

this.subscriptions.add(
this.pageContext$
.pipe(
map((newContext) => {
// Cherry-picking fields because FS limits the number of fields that can be sent.
// > Note: You can capture up to 20 unique page properties (exclusive of pageName) for any given page
// > and up to 500 unique page properties across all pages.
// https://help.fullstory.com/hc/en-us/articles/1500004101581-FS-setVars-API-Sending-custom-page-data-to-FullStory
return PAGE_VARS_KEYS.reduce((acc, key) => {
if (has(newContext, key)) {
set(acc, key, get(newContext, key));
}
return acc;
}, {} as Partial<FullStoryPageContext> & Record<string, unknown>);
}),
filter((pageVars) => Object.keys(pageVars).length > 0),
// Wait for anything to actually change.
distinct((pageVars) => {
const sortedKeys = Object.keys(pageVars).sort();
return sortedKeys.map((key) => pageVars[key]).join('-');
}),
// We need some debounce time to ensure everything is updated before calling FS because some properties cannot be changed twice for the same URL.
debounceTime(pageVarsDebounceTimeMs)
)
.subscribe((pageVars) => {
this.initContext.logger.debug(
`Calling FS.setVars with context ${JSON.stringify(pageVars)}`
);
this.fullStoryApi.setVars('page', {
...formatPayload(pageVars),
...(pageVars.version ? getParsedVersion(pageVars.version) : {}),
});
})
);
}

/**
Expand All @@ -89,57 +148,11 @@ export class FullStoryShipper implements IShipper {
public extendContext(newContext: EventContext): void {
this.initContext.logger.debug(`Received context ${JSON.stringify(newContext)}`);

// FullStory requires different APIs for different type of contexts.
const {
userId,
isElasticCloudUser,
cloudIsElasticStaffOwned,
cloudTrialEndDate,
...nonUserContext
} = newContext;

// Call it only when the userId changes
if (userId && userId !== this.lastUserId) {
this.initContext.logger.debug(`Calling FS.identify with userId ${userId}`);
// We need to call the API for every new userId (restarting the session).
this.fullStoryApi.identify(userId);
this.lastUserId = userId;
}

// User-level context
if (
typeof isElasticCloudUser === 'boolean' ||
typeof cloudIsElasticStaffOwned === 'boolean' ||
cloudTrialEndDate
) {
const userVars = {
isElasticCloudUser,
cloudIsElasticStaffOwned,
cloudTrialEndDate,
};
this.initContext.logger.debug(`Calling FS.setUserVars with ${JSON.stringify(userVars)}`);
this.fullStoryApi.setUserVars(formatPayload(userVars));
}

// Cherry-picking fields because FS limits the number of fields that can be sent.
// > Note: You can capture up to 20 unique page properties (exclusive of pageName) for any given page
// > and up to 500 unique page properties across all pages.
// https://help.fullstory.com/hc/en-us/articles/1500004101581-FS-setVars-API-Sending-custom-page-data-to-FullStory
const pageVars = PAGE_VARS_KEYS.reduce((acc, key) => {
if (has(nonUserContext, key)) {
set(acc, key, get(nonUserContext, key));
}
return acc;
}, {} as Partial<Pick<EventContext, typeof PAGE_VARS_KEYS[number]>> & Record<string, unknown>);

// FullStory requires different APIs for different type of contexts:
// User-level context.
this.userContext$.next(newContext);
// Event-level context. At the moment, only the scope `page` is supported by FullStory for webapps.
if (Object.keys(pageVars).length) {
this.initContext.logger.debug(`Calling FS.setVars with context ${JSON.stringify(pageVars)}`);
this.fullStoryApi.setVars('page', {
...formatPayload(pageVars),
...(pageVars.version ? getParsedVersion(pageVars.version) : {}),
});
}
this.pageContext$.next(newContext);
}

/**
Expand Down Expand Up @@ -184,9 +197,38 @@ export class FullStoryShipper implements IShipper {

/**
* Shuts down the shipper.
* It doesn't really do anything inside because this shipper doesn't hold any internal queues.
*/
public shutdown() {
// No need to do anything here for now.
this.subscriptions.unsubscribe();
}

private updateUserVars({
userId,
isElasticCloudUser,
cloudIsElasticStaffOwned,
cloudTrialEndDate,
}: FullStoryUserVars) {
// Call it only when the userId changes
if (userId && userId !== this.lastUserId) {
this.initContext.logger.debug(`Calling FS.identify with userId ${userId}`);
// We need to call the API for every new userId (restarting the session).
this.fullStoryApi.identify(userId);
this.lastUserId = userId;
}

// User-level context
if (
typeof isElasticCloudUser === 'boolean' ||
typeof cloudIsElasticStaffOwned === 'boolean' ||
cloudTrialEndDate
) {
const userVars = {
isElasticCloudUser,
cloudIsElasticStaffOwned,
cloudTrialEndDate,
};
this.initContext.logger.debug(`Calling FS.setUserVars with ${JSON.stringify(userVars)}`);
this.fullStoryApi.setUserVars(formatPayload(userVars));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ function buildRootCrumb({
i18n.translate('core.ui.primaryNav.cloud.projectLabel', {
defaultMessage: 'Project',
}),
// increase the max-width of the root breadcrumb to not truncate too soon
style: { maxWidth: '320px' },
popoverContent: (
<EuiContextMenuPanel
size="s"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ describe('breadcrumbs', () => {
"popoverProps": Object {
"panelPaddingSize": "none",
},
"style": Object {
"maxWidth": "320px",
},
"text": "Project",
},
Object {
Expand Down Expand Up @@ -176,6 +179,9 @@ describe('breadcrumbs', () => {
"popoverProps": Object {
"panelPaddingSize": "none",
},
"style": Object {
"maxWidth": "320px",
},
"text": "Project",
},
Object {
Expand Down Expand Up @@ -232,6 +238,9 @@ describe('breadcrumbs', () => {
"popoverProps": Object {
"panelPaddingSize": "none",
},
"style": Object {
"maxWidth": "320px",
},
"text": "Project",
},
Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,18 @@ export function Breadcrumbs({ breadcrumbs$ }: Props) {
};
});

return <EuiBreadcrumbs breadcrumbs={crumbs} max={10} data-test-subj="breadcrumbs" />;
return (
<EuiBreadcrumbs
breadcrumbs={crumbs}
data-test-subj="breadcrumbs"
// reduce number of visible breadcrumbs due to increased max-width of the root breadcrumbs
responsive={{
xs: 1,
s: 2,
m: 3,
l: 4,
xl: 7,
}}
/>
);
}
Loading

0 comments on commit f229f3b

Please sign in to comment.