mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
# Backport This will backport the following commits from `main` to `8.15`: - [[Logs UI] Fix fly-out link to the legacy Uptime app (#186328)](https://github.com/elastic/kibana/pull/186328) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Felix Stürmer","email":"weltenwort@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-07-04T16:28:25Z","message":"[Logs UI] Fix fly-out link to the legacy Uptime app (#186328)","sha":"c3c4dca2896362b0c35419afaf4a56f92b48013b","branchLabelMapping":{"^v8.15.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Feature:Logs UI","backport:prev-minor","ci:project-deploy-observability","Team:obs-ux-logs","Team:obs-ux-management","apm:review","v8.15.0","v8.16.0"],"title":"[Logs UI] Fix fly-out link to the legacy Uptime app","number":186328,"url":"https://github.com/elastic/kibana/pull/186328","mergeCommit":{"message":"[Logs UI] Fix fly-out link to the legacy Uptime app (#186328)","sha":"c3c4dca2896362b0c35419afaf4a56f92b48013b"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.15.0","branchLabelMappingKey":"^v8.15.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/186328","number":186328,"mergeCommit":{"message":"[Logs UI] Fix fly-out link to the legacy Uptime app (#186328)","sha":"c3c4dca2896362b0c35419afaf4a56f92b48013b"}},{"branch":"8.16","label":"v8.16.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Felix Stürmer <weltenwort@users.noreply.github.com>
This commit is contained in:
parent
b10c5bca89
commit
046bccc2e8
9 changed files with 179 additions and 107 deletions
|
@ -6,7 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export * from './dataset_quality';
|
||||
export * from './logs_explorer';
|
||||
export * from './observability_logs_explorer';
|
||||
export * from './observability_onboarding';
|
||||
export * from './dataset_quality';
|
||||
export * from './uptime';
|
||||
|
|
23
packages/deeplinks/observability/locators/uptime.ts
Normal file
23
packages/deeplinks/observability/locators/uptime.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
import { SerializableRecord } from '@kbn/utility-types';
|
||||
|
||||
export const uptimeOverviewLocatorID = 'UPTIME_OVERVIEW_LOCATOR';
|
||||
|
||||
export interface UptimeOverviewLocatorInfraParams extends SerializableRecord {
|
||||
ip?: string;
|
||||
host?: string;
|
||||
container?: string;
|
||||
pod?: string;
|
||||
}
|
||||
|
||||
export interface UptimeOverviewLocatorParams extends SerializableRecord {
|
||||
dateRangeStart?: string;
|
||||
dateRangeEnd?: string;
|
||||
search?: string;
|
||||
}
|
|
@ -5,29 +5,55 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { subj as testSubject } from '@kbn/test-subj-selector';
|
||||
import React, { FC, PropsWithChildren } from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
// import { mount } from 'enzyme';
|
||||
import { LogEntryActionsMenu } from './log_entry_actions_menu';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
import {
|
||||
uptimeOverviewLocatorID,
|
||||
UptimeOverviewLocatorInfraParams,
|
||||
UptimeOverviewLocatorParams,
|
||||
} from '@kbn/deeplinks-observability';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { MockUrlService } from '@kbn/share-plugin/common/mocks';
|
||||
import { type UrlService } from '@kbn/share-plugin/common/url_service';
|
||||
import { mountWithIntl as mount } from '@kbn/test-jest-helpers';
|
||||
import { subj as testSubject } from '@kbn/test-subj-selector';
|
||||
import React, { FC } from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { LogEntryActionsMenu } from './log_entry_actions_menu';
|
||||
|
||||
const coreStartMock = coreMock.createStart();
|
||||
coreStartMock.application.getUrlForApp.mockImplementation((app, options) => {
|
||||
return `/test-basepath/s/test-space/app/${app}${options?.path}`;
|
||||
});
|
||||
|
||||
const ProviderWrapper: FC<PropsWithChildren<unknown>> = ({ children }) => {
|
||||
return <KibanaContextProvider services={{ ...coreStartMock }}>{children}</KibanaContextProvider>;
|
||||
const emptyUrlService = new MockUrlService();
|
||||
const urlServiceWithUptimeLocator = new MockUrlService();
|
||||
// we can't use the actual locator here because its import would create a
|
||||
// forbidden ts project reference cycle
|
||||
urlServiceWithUptimeLocator.locators.create<
|
||||
UptimeOverviewLocatorInfraParams | UptimeOverviewLocatorParams
|
||||
>({
|
||||
id: uptimeOverviewLocatorID,
|
||||
getLocation: async (params) => {
|
||||
return { app: 'uptime', path: '/overview', state: {} };
|
||||
},
|
||||
});
|
||||
|
||||
const ProviderWrapper: FC<{ urlService?: UrlService }> = ({
|
||||
children,
|
||||
urlService = emptyUrlService,
|
||||
}) => {
|
||||
return (
|
||||
<KibanaContextProvider services={{ ...coreStartMock, share: { url: urlService } }}>
|
||||
{children}
|
||||
</KibanaContextProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('LogEntryActionsMenu component', () => {
|
||||
const time = new Date().toISOString();
|
||||
describe('uptime link', () => {
|
||||
it('renders with a host ip filter when present in log entry', () => {
|
||||
|
||||
describe('uptime link with legacy uptime disabled', () => {
|
||||
it('renders as disabled even when a supported field is present', () => {
|
||||
const elementWrapper = mount(
|
||||
<ProviderWrapper>
|
||||
<LogEntryActionsMenu
|
||||
|
@ -52,14 +78,49 @@ describe('LogEntryActionsMenu component', () => {
|
|||
});
|
||||
elementWrapper.update();
|
||||
|
||||
expect(
|
||||
elementWrapper
|
||||
.find(`${testSubject('~uptimeLogEntryActionsMenuItem')}`)
|
||||
.first()
|
||||
.prop('disabled')
|
||||
).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('uptime link with legacy uptime enabled', () => {
|
||||
it('renders as enabled when a host ip is present in the log entry', () => {
|
||||
const elementWrapper = mount(
|
||||
<ProviderWrapper urlService={urlServiceWithUptimeLocator}>
|
||||
<LogEntryActionsMenu
|
||||
logEntry={{
|
||||
fields: [{ field: 'host.ip', value: ['HOST_IP'] }],
|
||||
id: 'ITEM_ID',
|
||||
index: 'INDEX',
|
||||
cursor: {
|
||||
time,
|
||||
tiebreaker: 0,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</ProviderWrapper>
|
||||
);
|
||||
|
||||
act(() => {
|
||||
elementWrapper
|
||||
.find(`button${testSubject('logEntryActionsMenuButton')}`)
|
||||
.last()
|
||||
.simulate('click');
|
||||
});
|
||||
elementWrapper.update();
|
||||
|
||||
expect(
|
||||
elementWrapper.find(`a${testSubject('~uptimeLogEntryActionsMenuItem')}`).prop('href')
|
||||
).toBe('/test-basepath/s/test-space/app/uptime#/?search=host.ip:HOST_IP');
|
||||
).toEqual(expect.any(String));
|
||||
});
|
||||
|
||||
it('renders with a container id filter when present in log entry', () => {
|
||||
it('renders as enabled when a container id is present in the log entry', () => {
|
||||
const elementWrapper = mount(
|
||||
<ProviderWrapper>
|
||||
<ProviderWrapper urlService={urlServiceWithUptimeLocator}>
|
||||
<LogEntryActionsMenu
|
||||
logEntry={{
|
||||
fields: [{ field: 'container.id', value: ['CONTAINER_ID'] }],
|
||||
|
@ -84,12 +145,12 @@ describe('LogEntryActionsMenu component', () => {
|
|||
|
||||
expect(
|
||||
elementWrapper.find(`a${testSubject('~uptimeLogEntryActionsMenuItem')}`).prop('href')
|
||||
).toBe('/test-basepath/s/test-space/app/uptime#/?search=container.id:CONTAINER_ID');
|
||||
).toEqual(expect.any(String));
|
||||
});
|
||||
|
||||
it('renders with a pod uid filter when present in log entry', () => {
|
||||
it('renders as enabled when a pod uid is present in the log entry', () => {
|
||||
const elementWrapper = mount(
|
||||
<ProviderWrapper>
|
||||
<ProviderWrapper urlService={urlServiceWithUptimeLocator}>
|
||||
<LogEntryActionsMenu
|
||||
logEntry={{
|
||||
fields: [{ field: 'kubernetes.pod.uid', value: ['POD_UID'] }],
|
||||
|
@ -114,48 +175,12 @@ describe('LogEntryActionsMenu component', () => {
|
|||
|
||||
expect(
|
||||
elementWrapper.find(`a${testSubject('~uptimeLogEntryActionsMenuItem')}`).prop('href')
|
||||
).toBe('/test-basepath/s/test-space/app/uptime#/?search=kubernetes.pod.uid:POD_UID');
|
||||
).toEqual(expect.any(String));
|
||||
});
|
||||
|
||||
it('renders with a disjunction of filters when multiple present in log entry', () => {
|
||||
it('renders as disabled when no supported field is present in the log entry', () => {
|
||||
const elementWrapper = mount(
|
||||
<ProviderWrapper>
|
||||
<LogEntryActionsMenu
|
||||
logEntry={{
|
||||
fields: [
|
||||
{ field: 'container.id', value: ['CONTAINER_ID'] },
|
||||
{ field: 'host.ip', value: ['HOST_IP'] },
|
||||
{ field: 'kubernetes.pod.uid', value: ['POD_UID'] },
|
||||
],
|
||||
id: 'ITEM_ID',
|
||||
index: 'INDEX',
|
||||
cursor: {
|
||||
time,
|
||||
tiebreaker: 0,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</ProviderWrapper>
|
||||
);
|
||||
|
||||
act(() => {
|
||||
elementWrapper
|
||||
.find(`button${testSubject('logEntryActionsMenuButton')}`)
|
||||
.last()
|
||||
.simulate('click');
|
||||
});
|
||||
elementWrapper.update();
|
||||
|
||||
expect(
|
||||
elementWrapper.find(`a${testSubject('~uptimeLogEntryActionsMenuItem')}`).prop('href')
|
||||
).toBe(
|
||||
'/test-basepath/s/test-space/app/uptime#/?search=container.id:CONTAINER_ID%20or%20host.ip:HOST_IP%20or%20kubernetes.pod.uid:POD_UID'
|
||||
);
|
||||
});
|
||||
|
||||
it('renders as disabled when no supported field is present in log entry', () => {
|
||||
const elementWrapper = mount(
|
||||
<ProviderWrapper>
|
||||
<ProviderWrapper urlService={urlServiceWithUptimeLocator}>
|
||||
<LogEntryActionsMenu
|
||||
logEntry={{
|
||||
fields: [],
|
||||
|
@ -180,7 +205,8 @@ describe('LogEntryActionsMenu component', () => {
|
|||
|
||||
expect(
|
||||
elementWrapper
|
||||
.find(`button${testSubject('~uptimeLogEntryActionsMenuItem')}`)
|
||||
.find(`${testSubject('~uptimeLogEntryActionsMenuItem')}`)
|
||||
.first()
|
||||
.prop('disabled')
|
||||
).toEqual(true);
|
||||
});
|
||||
|
|
|
@ -6,28 +6,36 @@
|
|||
*/
|
||||
|
||||
import { EuiButton, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui';
|
||||
import {
|
||||
uptimeOverviewLocatorID,
|
||||
type UptimeOverviewLocatorInfraParams,
|
||||
} from '@kbn/deeplinks-observability';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { LinkDescriptor, useLinkProps } from '@kbn/observability-shared-plugin/public';
|
||||
import { getRouterLinkProps } from '@kbn/router-utils';
|
||||
import { ILocatorClient } from '@kbn/share-plugin/common/url_service';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useLinkProps, LinkDescriptor } from '@kbn/observability-shared-plugin/public';
|
||||
import { useVisibilityState } from '../../../utils/use_visibility_state';
|
||||
import { LogEntry } from '../../../../common/search_strategies/log_entries/log_entry';
|
||||
|
||||
const UPTIME_FIELDS = ['container.id', 'host.ip', 'kubernetes.pod.uid'];
|
||||
import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
|
||||
import { useVisibilityState } from '../../../utils/use_visibility_state';
|
||||
|
||||
export interface LogEntryActionsMenuProps {
|
||||
logEntry: LogEntry;
|
||||
}
|
||||
|
||||
export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => {
|
||||
const {
|
||||
services: {
|
||||
share: {
|
||||
url: { locators },
|
||||
},
|
||||
},
|
||||
} = useKibanaContextForPlugin();
|
||||
const { hide, isVisible, toggle } = useVisibilityState(false);
|
||||
|
||||
const apmLinkDescriptor = useMemo(() => getAPMLink(logEntry), [logEntry]);
|
||||
const uptimeLinkDescriptor = useMemo(() => getUptimeLink(logEntry), [logEntry]);
|
||||
|
||||
const uptimeLinkProps = useLinkProps({
|
||||
app: 'uptime',
|
||||
...(uptimeLinkDescriptor ? uptimeLinkDescriptor : {}),
|
||||
});
|
||||
const uptimeLinkProps = getUptimeLink({ locators })(logEntry);
|
||||
|
||||
const apmLinkProps = useLinkProps({
|
||||
app: 'apm',
|
||||
|
@ -38,7 +46,7 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => {
|
|||
() => [
|
||||
<EuiContextMenuItem
|
||||
data-test-subj="logEntryActionsMenuItem uptimeLogEntryActionsMenuItem"
|
||||
disabled={!uptimeLinkDescriptor}
|
||||
disabled={!uptimeLinkProps}
|
||||
icon="uptimeApp"
|
||||
key="uptimeLink"
|
||||
{...uptimeLinkProps}
|
||||
|
@ -61,7 +69,7 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => {
|
|||
/>
|
||||
</EuiContextMenuItem>,
|
||||
],
|
||||
[uptimeLinkDescriptor, apmLinkDescriptor, apmLinkProps, uptimeLinkProps]
|
||||
[apmLinkDescriptor, apmLinkProps, uptimeLinkProps]
|
||||
);
|
||||
|
||||
const hasMenuItems = useMemo(() => menuItems.length > 0, [menuItems]);
|
||||
|
@ -92,25 +100,40 @@ export const LogEntryActionsMenu = ({ logEntry }: LogEntryActionsMenuProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
const getUptimeLink = (logEntry: LogEntry): LinkDescriptor | undefined => {
|
||||
const searchExpressions = logEntry.fields
|
||||
.filter(({ field, value }) => value != null && UPTIME_FIELDS.includes(field))
|
||||
.reduce<string[]>((acc, fieldItem) => {
|
||||
const { field, value } = fieldItem;
|
||||
return acc.concat(value.map((val) => `${field}:${val}`));
|
||||
}, []);
|
||||
const getUptimeLink =
|
||||
({ locators }: { locators: ILocatorClient }) =>
|
||||
(logEntry: LogEntry): ContextRouterLinkProps | undefined => {
|
||||
const uptimeLocator = locators.get<UptimeOverviewLocatorInfraParams>(uptimeOverviewLocatorID);
|
||||
|
||||
if (searchExpressions.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
app: 'uptime',
|
||||
hash: '/',
|
||||
search: {
|
||||
search: `${searchExpressions.join(' or ')}`,
|
||||
},
|
||||
if (!uptimeLocator) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const ipValue = logEntry.fields.find(({ field }) => field === 'host.ip')?.value?.[0];
|
||||
const containerValue = logEntry.fields.find(({ field }) => field === 'container.id')
|
||||
?.value?.[0];
|
||||
const podValue = logEntry.fields.find(({ field }) => field === 'kubernetes.pod.uid')
|
||||
?.value?.[0];
|
||||
const hostValue = logEntry.fields.find(({ field }) => field === 'host.name')?.value?.[0];
|
||||
|
||||
const uptimeLocatorParams: UptimeOverviewLocatorInfraParams = {
|
||||
...(typeof ipValue === 'string' && { ip: ipValue }),
|
||||
...(typeof containerValue === 'string' && { container: containerValue }),
|
||||
...(typeof podValue === 'string' && { pod: podValue }),
|
||||
...(typeof hostValue === 'string' && { host: hostValue }),
|
||||
};
|
||||
|
||||
if (Object.keys(uptimeLocatorParams).length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Coercing the return value to ContextRouterLinkProps because
|
||||
// EuiContextMenuItem defines a too broad type for onClick
|
||||
return getRouterLinkProps({
|
||||
href: uptimeLocator.getRedirectUrl(uptimeLocatorParams),
|
||||
onClick: () => uptimeLocator.navigate(uptimeLocatorParams),
|
||||
}) as ContextRouterLinkProps;
|
||||
};
|
||||
};
|
||||
|
||||
const getAPMLink = (logEntry: LogEntry): LinkDescriptor | undefined => {
|
||||
const traceId = logEntry.fields.find(
|
||||
|
@ -153,3 +176,8 @@ function getApmTraceUrl({
|
|||
}) {
|
||||
return `/link-to/trace/${traceId}?` + new URLSearchParams({ rangeFrom, rangeTo }).toString();
|
||||
}
|
||||
|
||||
export interface ContextRouterLinkProps {
|
||||
href: string | undefined;
|
||||
onClick: (event: React.MouseEvent) => void;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
|||
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
|
||||
import type { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public';
|
||||
import type { ObservabilityAIAssistantPublicStart } from '@kbn/observability-ai-assistant-plugin/public';
|
||||
import { SharePluginSetup } from '@kbn/share-plugin/public';
|
||||
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
|
||||
import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public';
|
||||
import type { UiActionsStart } from '@kbn/ui-actions-plugin/public';
|
||||
|
||||
import { LogsSharedLocators } from '../common/locators';
|
||||
import type { LogAIAssistantProps } from './components/log_ai_assistant/log_ai_assistant';
|
||||
|
@ -38,6 +38,7 @@ export interface LogsSharedClientStartDeps {
|
|||
dataViews: DataViewsPublicPluginStart;
|
||||
discoverShared: DiscoverSharedPublicStart;
|
||||
observabilityAIAssistant?: ObservabilityAIAssistantPublicStart;
|
||||
share: SharePluginStart;
|
||||
uiActions: UiActionsStart;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
"@kbn/search-types",
|
||||
"@kbn/discover-shared-plugin",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
"@kbn/test-jest-helpers"
|
||||
"@kbn/test-jest-helpers",
|
||||
"@kbn/router-utils",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export type { AsDuration, AsPercent, TimeUnitChar, TimeFormatter } from './utils/formatters';
|
||||
|
||||
export {
|
||||
|
@ -76,7 +75,7 @@ export const observabilityFeatureId = 'observability';
|
|||
|
||||
// Name of a locator created by the uptime plugin. Intended for use
|
||||
// by other plugins as well, so defined here to prevent cross-references.
|
||||
export const uptimeOverviewLocatorID = 'UPTIME_OVERVIEW_LOCATOR';
|
||||
export { uptimeOverviewLocatorID } from '@kbn/deeplinks-observability';
|
||||
export const syntheticsMonitorDetailLocatorID = 'SYNTHETICS_MONITOR_DETAIL_LOCATOR';
|
||||
export const syntheticsEditMonitorLocatorID = 'SYNTHETICS_EDIT_MONITOR_LOCATOR';
|
||||
export const syntheticsSettingsLocatorID = 'SYNTHETICS_SETTINGS';
|
||||
|
|
|
@ -5,26 +5,18 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/public';
|
||||
import {
|
||||
uptimeOverviewLocatorID,
|
||||
type UptimeOverviewLocatorInfraParams,
|
||||
type UptimeOverviewLocatorParams,
|
||||
} from '@kbn/deeplinks-observability';
|
||||
import type { LocatorDefinition } from '@kbn/share-plugin/common';
|
||||
import type { SerializableRecord } from '@kbn/utility-types';
|
||||
import { OVERVIEW_ROUTE } from '../../common/constants';
|
||||
|
||||
export type { UptimeOverviewLocatorInfraParams, UptimeOverviewLocatorParams };
|
||||
|
||||
const formatSearchKey = (key: string, value: string) => `${key}: "${value}"`;
|
||||
|
||||
export interface UptimeOverviewLocatorInfraParams extends SerializableRecord {
|
||||
ip?: string;
|
||||
host?: string;
|
||||
container?: string;
|
||||
pod?: string;
|
||||
}
|
||||
|
||||
export interface UptimeOverviewLocatorParams extends SerializableRecord {
|
||||
dateRangeStart?: string;
|
||||
dateRangeEnd?: string;
|
||||
search?: string;
|
||||
}
|
||||
|
||||
function isUptimeOverviewLocatorParams(
|
||||
args: UptimeOverviewLocatorInfraParams | UptimeOverviewLocatorParams
|
||||
): args is UptimeOverviewLocatorParams {
|
||||
|
|
|
@ -76,7 +76,8 @@
|
|||
"@kbn/repo-info",
|
||||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
"@kbn/react-kibana-mount"
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/deeplinks-observability"
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue