Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discover] [Log Explorer] Add tabs to Discover and Log Explorer #171467

Merged
merged 28 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3814b7d
[Discover] [Log Explorer] Add tabs to Discover and Log Explorer
davismcphee Nov 17, 2023
10555e0
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Nov 17, 2023
02262fb
Cleanup
davismcphee Nov 17, 2023
f50fd49
Update tab labels, fix tab link syncing, fix issue where page reloade…
davismcphee Nov 22, 2023
b1adebc
Create DiscoverCustomizationContext to store customization related pr…
davismcphee Nov 22, 2023
cc966e8
Improve click behaviour of Log Explorer tabs
davismcphee Nov 23, 2023
b5b0eb3
Fix types and Jest tests
davismcphee Nov 23, 2023
97758cb
Fix broken tests and add new tests
davismcphee Nov 23, 2023
97b86a6
Update Log Explorer Discover tabs functional tests
davismcphee Nov 24, 2023
2a6be15
Cleaup
davismcphee Nov 24, 2023
3b493a8
Fix types
davismcphee Nov 24, 2023
0605046
Allow showing the Discover nav bar in serverless when the no data scr…
davismcphee Nov 24, 2023
b4cb974
Fix broken Jest tests
davismcphee Nov 28, 2023
bf2f432
Convert discover_topnav_serverless tests to RTL
davismcphee Nov 28, 2023
329c676
Merge branch 'main' into discover-log-explorer-tabs
kibanamachine Nov 30, 2023
dd8e265
Merge branch 'main' into discover-log-explorer-tabs
davismcphee Nov 30, 2023
58a3953
Make customizationContext constant
davismcphee Nov 30, 2023
9e081b1
Memoize LogExplorerTabs params
davismcphee Nov 30, 2023
446d1b0
Merge branch 'main' into discover-log-explorer-tabs
davismcphee Dec 4, 2023
e7d57c2
Hide Discover top nav menu items while loading
davismcphee Dec 4, 2023
c477756
Comment out tabs state syncing code, and re-add the 'Open in Discover…
davismcphee Dec 4, 2023
d235bb3
Move 'Open in Discover' link, and remove Discover icon
davismcphee Dec 5, 2023
ae05ec7
Merge branch 'main' into discover-log-explorer-tabs
davismcphee Dec 5, 2023
9e64703
Merge branch 'main' into discover-log-explorer-tabs
davismcphee Dec 5, 2023
2e4b3cd
Merge branch 'main' into discover-log-explorer-tabs
davismcphee Dec 6, 2023
457641a
Delete all state syncing code from LogExplorerTabs
davismcphee Dec 6, 2023
3843a4c
Merge branch 'main' into discover-log-explorer-tabs
davismcphee Dec 7, 2023
dbb12eb
Fix broken types
davismcphee Dec 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/plugins/discover/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"savedObjectsTaggingOss",
"lens",
"noDataPage",
"globalSearch"
"globalSearch",
"serverless"
],
"requiredBundles": ["kibanaUtils", "kibanaReact", "unifiedSearch"],
"extraPublicDirs": ["common"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export function getDiscoverStateMock({
const container = getDiscoverStateContainer({
services: discoverServiceMock,
history,
customizationContext: {
displayMode: 'standalone',
showLogExplorerTabs: false,
},
});
container.savedSearchState.set(
savedSearch ? savedSearch : isTimeBased ? savedSearchMockWithTimeField : savedSearchMock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ import { Redirect, RouteProps } from 'react-router-dom';
import { Route } from '@kbn/shared-ux-router';
import { createSearchSessionMock } from '../__mocks__/search_session';
import { discoverServiceMock as mockDiscoverServices } from '../__mocks__/services';
import { CustomDiscoverRoutes, DiscoverRouter, DiscoverRoutes } from './discover_router';
import {
CustomDiscoverRoutes,
DiscoverRouter,
DiscoverRoutes,
DiscoverRoutesProps,
} from './discover_router';
import { DiscoverMainRoute } from './main';
import { SingleDocRoute } from './doc';
import { ContextAppRoute } from './context';
import { createProfileRegistry } from '../customizations/profile_registry';
import { addProfile } from '../../common/customizations';
import { NotFoundRoute } from './not_found';
import type { DiscoverCustomizationContext } from './types';

let mockProfile: string | undefined;

Expand All @@ -43,9 +49,15 @@ const gatherRoutes = (wrapper: ShallowWrapper) => {
});
};

const props = {
const customizationContext: DiscoverCustomizationContext = {
displayMode: 'standalone',
showLogExplorerTabs: false,
};

const props: DiscoverRoutesProps = {
isDev: false,
customizationCallbacks: [],
customizationContext,
};

describe('DiscoverRoutes', () => {
Expand Down Expand Up @@ -147,12 +159,17 @@ describe('CustomDiscoverRoutes', () => {
it('should show DiscoverRoutes for a valid profile', () => {
mockProfile = 'test';
const component = shallow(
<CustomDiscoverRoutes profileRegistry={profileRegistry} isDev={props.isDev} />
<CustomDiscoverRoutes
profileRegistry={profileRegistry}
customizationContext={customizationContext}
isDev={props.isDev}
/>
);
expect(component.find(DiscoverRoutes).getElement()).toMatchObject(
<DiscoverRoutes
prefix={addProfile('', mockProfile)}
customizationCallbacks={callbacks}
customizationContext={customizationContext}
isDev={props.isDev}
/>
);
Expand All @@ -161,7 +178,11 @@ describe('CustomDiscoverRoutes', () => {
it('should show NotFoundRoute for an invalid profile', () => {
mockProfile = 'invalid';
const component = shallow(
<CustomDiscoverRoutes profileRegistry={profileRegistry} isDev={props.isDev} />
<CustomDiscoverRoutes
profileRegistry={profileRegistry}
customizationContext={customizationContext}
isDev={props.isDev}
/>
);
expect(component.find(NotFoundRoute).getElement()).toMatchObject(<NotFoundRoute />);
});
Expand All @@ -178,6 +199,7 @@ describe('DiscoverRouter', () => {
services={mockDiscoverServices}
history={history}
profileRegistry={profileRegistry}
customizationContext={customizationContext}
isDev={props.isDev}
/>
);
Expand All @@ -186,13 +208,21 @@ describe('DiscoverRouter', () => {

it('should show DiscoverRoutes component for / route', () => {
expect(pathMap['/']).toMatchObject(
<DiscoverRoutes customizationCallbacks={callbacks} isDev={props.isDev} />
<DiscoverRoutes
customizationCallbacks={callbacks}
customizationContext={customizationContext}
isDev={props.isDev}
/>
);
});

it(`should show CustomDiscoverRoutes component for ${profilePath} route`, () => {
expect(pathMap[profilePath]).toMatchObject(
<CustomDiscoverRoutes profileRegistry={profileRegistry} isDev={props.isDev} />
<CustomDiscoverRoutes
profileRegistry={profileRegistry}
customizationContext={customizationContext}
isDev={props.isDev}
/>
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ import { ViewAlertRoute } from './view_alert';
import type { CustomizationCallback } from '../customizations';
import type { DiscoverProfileRegistry } from '../customizations/profile_registry';
import { addProfile } from '../../common/customizations';
import type { DiscoverCustomizationContext } from './types';

interface DiscoverRoutesProps {
export interface DiscoverRoutesProps {
prefix?: string;
customizationCallbacks: CustomizationCallback[];
customizationContext: DiscoverCustomizationContext;
isDev: boolean;
}

Expand Down Expand Up @@ -66,6 +68,7 @@ export const DiscoverRoutes = ({ prefix, ...mainRouteProps }: DiscoverRoutesProp

interface CustomDiscoverRoutesProps {
profileRegistry: DiscoverProfileRegistry;
customizationContext: DiscoverCustomizationContext;
isDev: boolean;
}

Expand All @@ -92,6 +95,7 @@ export const CustomDiscoverRoutes = ({ profileRegistry, ...props }: CustomDiscov
export interface DiscoverRouterProps {
services: DiscoverServices;
profileRegistry: DiscoverProfileRegistry;
customizationContext: DiscoverCustomizationContext;
history: History;
isDev: boolean;
}
Expand Down
11 changes: 10 additions & 1 deletion src/plugins/discover/public/application/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,23 @@ import { toMountPoint } from '@kbn/react-kibana-mount';
import { DiscoverRouter } from './discover_router';
import { DiscoverServices } from '../build_services';
import type { DiscoverProfileRegistry } from '../customizations/profile_registry';
import type { DiscoverCustomizationContext } from './types';

export interface RenderAppProps {
element: HTMLElement;
services: DiscoverServices;
profileRegistry: DiscoverProfileRegistry;
customizationContext: DiscoverCustomizationContext;
isDev: boolean;
}

export const renderApp = ({ element, services, profileRegistry, isDev }: RenderAppProps) => {
export const renderApp = ({
element,
services,
profileRegistry,
customizationContext,
isDev,
}: RenderAppProps) => {
const { history: getHistory, capabilities, chrome, data, core } = services;

const history = getHistory();
Expand All @@ -39,6 +47,7 @@ export const renderApp = ({ element, services, profileRegistry, isDev }: RenderA
<DiscoverRouter
services={services}
profileRegistry={profileRegistry}
customizationContext={customizationContext}
history={history}
isDev={isDev}
/>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { createHashHistory } from 'history';
import { SavedSearch } from '@kbn/saved-search-plugin/public';
import { buildDataTableRecordList } from '@kbn/discover-utils';
import { esHitsMock } from '@kbn/discover-utils/src/__mocks__';
import { FetchStatus } from '../../../../types';
import { DiscoverCustomizationContext, FetchStatus } from '../../../../types';
import {
AvailableFields$,
DataDocuments$,
Expand Down Expand Up @@ -124,11 +124,17 @@ function getSavedSearch(dataView: DataView) {
} as unknown as SavedSearch;
}

const customizationContext: DiscoverCustomizationContext = {
displayMode: 'standalone',
showLogExplorerTabs: false,
};

export function getDocumentsLayoutProps(dataView: DataView) {
const stateContainer = getDiscoverStateContainer({
history: createHashHistory(),
savedSearch: getSavedSearch(dataView),
services,
customizationContext,
});
stateContainer.appState.set({
columns: ['name', 'message', 'bytes'],
Expand All @@ -153,6 +159,7 @@ export const getPlainRecordLayoutProps = (dataView: DataView) => {
history: createHashHistory(),
savedSearch: getSavedSearch(dataView),
services,
customizationContext,
});
stateContainer.appState.set({
columns: ['name', 'message', 'bytes'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ discover-app {
.dscPage {
@include euiBreakpoint('m', 'l', 'xl') {
@include kibanaFullBodyHeight();

&.dscPage--serverless {
@include kibanaFullBodyHeight($euiSize * 3);
}
}

flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import { DiscoverStateContainer } from '../../services/discover_state';
import { VIEW_MODE } from '../../../../../common/constants';
import { useInternalStateSelector } from '../../services/discover_internal_state_container';
import { useAppStateSelector } from '../../services/discover_app_state_container';
import { useInspector } from '../../hooks/use_inspector';
import { useDiscoverServices } from '../../../../hooks/use_discover_services';
import { DiscoverNoResults } from '../no_results';
import { LoadingSpinner } from '../loading_spinner/loading_spinner';
Expand Down Expand Up @@ -73,8 +72,8 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) {
filterManager,
history,
spaces,
inspector,
docLinks,
serverless,
} = useDiscoverServices();
const { euiTheme } = useEuiTheme();
const pageBackgroundColor = useEuiBackgroundColor('plain');
Expand Down Expand Up @@ -118,11 +117,6 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) {
[dataState.fetchStatus, dataState.foundDocuments]
);

const onOpenInspector = useInspector({
inspector,
stateContainer,
});

const {
columns: currentColumns,
onAddColumn,
Expand Down Expand Up @@ -243,7 +237,7 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) {

return (
<EuiPage
className="dscPage"
className={classNames('dscPage', { 'dscPage--serverless': serverless })}
data-fetch-counter={fetchCounter.current}
css={css`
background-color: ${pageBackgroundColor};
Expand All @@ -266,12 +260,9 @@ export function DiscoverLayout({ stateContainer }: DiscoverLayoutProps) {
})}
</h1>
<TopNavMemoized
onOpenInspector={onOpenInspector}
query={query}
savedQuery={savedQuery}
stateContainer={stateContainer}
updateQuery={stateContainer.actions.onUpdateQuery}
isPlainRecord={isPlainRecord}
textBasedLanguageModeErrors={textBasedLanguageModeErrors}
textBasedLanguageModeWarning={textBasedLanguageModeWarning}
onFieldEdited={onFieldEdited}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,20 @@ import { mountWithIntl } from '@kbn/test-jest-helpers';
import { dataViewMock } from '@kbn/discover-utils/src/__mocks__';
import { DiscoverTopNav, DiscoverTopNavProps } from './discover_topnav';
import { TopNavMenu, TopNavMenuData } from '@kbn/navigation-plugin/public';
import { Query } from '@kbn/es-query';
import { setHeaderActionMenuMounter } from '../../../../kibana_services';
import { discoverServiceMock as mockDiscoverService } from '../../../../__mocks__/services';
import { getDiscoverStateMock } from '../../../../__mocks__/discover_state.mock';
import { DiscoverMainProvider } from '../../services/discover_state_provider';
import type { SearchBarCustomization, TopNavCustomization } from '../../../../customizations';
import type { DiscoverCustomizationId } from '../../../../customizations/customization_service';
import { useDiscoverCustomization } from '../../../../customizations';
import { useKibana } from '@kbn/kibana-react-plugin/public';

setHeaderActionMenuMounter(jest.fn());

jest.mock('@kbn/kibana-react-plugin/public', () => ({
...jest.requireActual('@kbn/kibana-react-plugin/public'),
useKibana: () => ({
services: mockDiscoverService,
}),
useKibana: jest.fn(),
}));

const MockCustomSearchBar: typeof mockDiscoverService.navigation.ui.AggregateQueryTopNavMenu =
Expand Down Expand Up @@ -77,15 +75,14 @@ function getProps(

return {
stateContainer,
query: {} as Query,
savedQuery: '',
updateQuery: jest.fn(),
onOpenInspector: jest.fn(),
onFieldEdited: jest.fn(),
isPlainRecord: false,
};
}

const mockUseKibana = useKibana as jest.Mock;

describe('Discover topnav component', () => {
beforeEach(() => {
mockTopNavCustomization.defaultMenu = undefined;
Expand All @@ -107,6 +104,10 @@ describe('Discover topnav component', () => {
throw new Error(`Unknown customization id: ${id}`);
}
});

mockUseKibana.mockReturnValue({
services: mockDiscoverService,
});
});

test('generated config of TopNavMenu config is correct when discover save permissions are assigned', () => {
Expand Down Expand Up @@ -280,4 +281,38 @@ describe('Discover topnav component', () => {
expect(topNav.prop('dataViewPickerComponentProps')).toBeUndefined();
});
});

describe('serverless', () => {
it('should render top nav when serverless plugin is not defined', () => {
const props = getProps();
const component = mountWithIntl(
<DiscoverMainProvider value={props.stateContainer}>
<DiscoverTopNav {...props} />
</DiscoverMainProvider>
);
const searchBar = component.find(mockDiscoverService.navigation.ui.AggregateQueryTopNavMenu);
expect(searchBar.prop('badges')).toBeDefined();
expect(searchBar.prop('config')).toBeDefined();
expect(searchBar.prop('setMenuMountPoint')).toBeDefined();
});

it('should not render top nav when serverless plugin is defined', () => {
mockUseKibana.mockReturnValue({
services: {
...mockDiscoverService,
serverless: true,
},
});
const props = getProps();
const component = mountWithIntl(
<DiscoverMainProvider value={props.stateContainer}>
<DiscoverTopNav {...props} />
</DiscoverMainProvider>
);
const searchBar = component.find(mockDiscoverService.navigation.ui.AggregateQueryTopNavMenu);
expect(searchBar.prop('badges')).toBeUndefined();
expect(searchBar.prop('config')).toBeUndefined();
expect(searchBar.prop('setMenuMountPoint')).toBeUndefined();
});
});
});
Loading