Skip to content

Commit

Permalink
[Index Management] Add Overview tab (elastic#164628)
Browse files Browse the repository at this point in the history
  • Loading branch information
alisonelizabeth authored Sep 8, 2023
1 parent ac86737 commit 4c2f702
Show file tree
Hide file tree
Showing 27 changed files with 610 additions and 40 deletions.
2 changes: 1 addition & 1 deletion packages/kbn-search-api-panels/components/code_box.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.serverlessSearchCodeBoxPanel {
.codeBoxPanel {
border-top: $euiBorderThin $euiColorLightShade;
}
2 changes: 1 addition & 1 deletion packages/kbn-search-api-panels/components/code_box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const CodeBox: React.FC<CodeBoxProps> = ({

return (
<EuiThemeProvider colorMode="dark">
<EuiPanel paddingSize="xs" className="serverlessSearchCodeBlockControlsPanel">
<EuiPanel paddingSize="xs" className="codeBoxPanel" data-test-subj="codeBlockControlsPanel">
<EuiFlexGroup alignItems="center">
<EuiFlexItem>
<EuiThemeProvider colorMode="light">
Expand Down
22 changes: 13 additions & 9 deletions packages/kbn-search-api-panels/components/install_client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,19 @@ export const InstallClientPanel: React.FC<InstallClientProps> = ({
defaultMessage:
'Elastic builds and maintains clients in several popular languages and our community has contributed many more. Install your favorite language client to get started.',
})}
links={[
{
href: language.docLink,
label: i18n.translate('searchApiPanels.welcomeBanner.installClient.clientDocLink', {
defaultMessage: '{languageName} client documentation',
values: { languageName: language.name },
}),
},
]}
links={
language.docLink
? [
{
href: language.docLink,
label: i18n.translate('searchApiPanels.welcomeBanner.installClient.clientDocLink', {
defaultMessage: '{languageName} client documentation',
values: { languageName: language.name },
}),
},
]
: []
}
title={i18n.translate('searchApiPanels.welcomeBanner.installClient.title', {
defaultMessage: 'Install a client',
})}
Expand Down
12 changes: 8 additions & 4 deletions packages/kbn-search-api-panels/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@ export const WelcomeBanner: React.FC<WelcomeBannerProps> = ({
<EuiFlexItem grow={false}>
<EuiTitle size="xxxs">
<h2>
{i18n.translate('searchApiPanels.welcomeBanner.header.greeting.title', {
defaultMessage: 'Hi {name}!',
values: { name: user?.full_name || user.username },
})}
{user
? i18n.translate('searchApiPanels.welcomeBanner.header.greeting.customTitle', {
defaultMessage: 'Hi {name}!',
values: { name: user.full_name || user.username },
})
: i18n.translate('searchApiPanels.welcomeBanner.header.greeting.defaultTitle', {
defaultMessage: 'Hi!',
})}
</h2>
</EuiTitle>
</EuiFlexItem>
Expand Down
6 changes: 6 additions & 0 deletions packages/kbn-search-api-panels/languages/console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import { LanguageDefinition } from '../types';

const INDEX_NAME_PLACEHOLDER = 'index_name';

export const consoleDefinition: Partial<LanguageDefinition> = {
buildSearchQuery: `POST /books/_search?pretty
{
Expand All @@ -30,4 +32,8 @@ export const consoleDefinition: Partial<LanguageDefinition> = {
{"name": "Brave New World", "author": "Aldous Huxley", "release_date": "1932-06-01", "page_count": 268}
{ "index" : { "_index" : "books" } }
{"name": "The Handmaid's Tale", "author": "Margaret Atwood", "release_date": "1985-06-01", "page_count": 311}`,
ingestDataIndex: ({ indexName }) => `POST _bulk?pretty
{ "index" : { "_index" : "${indexName ?? INDEX_NAME_PLACEHOLDER}" } }
{"name": "foo", "title": "bar"}
`,
};
20 changes: 10 additions & 10 deletions packages/kbn-search-api-panels/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,22 @@ export interface LanguageDefinitionSnippetArguments {

type CodeSnippet = string | ((args: LanguageDefinitionSnippetArguments) => string);
export interface LanguageDefinition {
name: string;
id: Languages;
iconType: string;
docLink?: string;
configureClient?: CodeSnippet;
ingestData?: CodeSnippet;
ingestDataIndex?: CodeSnippet;
installClient?: string;
buildSearchQuery?: CodeSnippet;
testConnection?: CodeSnippet;
advancedConfig?: string;
apiReference?: string;
basicConfig?: string;
configureClient: CodeSnippet;
docLink: string;
github?: {
link: string;
label: string;
};
iconType: string;
id: Languages;
ingestData: CodeSnippet;
ingestDataIndex: CodeSnippet;
installClient: string;
languageStyling?: string;
name: string;
buildSearchQuery: CodeSnippet;
testConnection: CodeSnippet;
}
37 changes: 37 additions & 0 deletions packages/kbn-search-api-panels/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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 { consoleDefinition } from './languages/console';
import { getConsoleRequest } from './utils';

describe('utils', () => {
describe('getConsoleRequest()', () => {
test('accepts string values', () => {
const consoleRequest = getConsoleRequest('ingestData');
expect(consoleRequest).toEqual(consoleDefinition.ingestData);
});

test('accepts function values', () => {
const consoleRequest = getConsoleRequest('ingestDataIndex', {
url: 'https://your_deployment_url',
apiKey: 'yourApiKey',
indexName: 'test-index',
});
expect(consoleRequest).toContain(`POST _bulk?pretty
{ \"index\" : { \"_index\" : \"test-index\" } }
{\"name\": \"foo\", \"title\": \"bar\"}`);
});

test('returns undefined if language definition is undefined', () => {
// @ts-ignore TS should not allow an invalid language definition
// We add @ts-ignore here to test the safeguard
const consoleRequest = getConsoleRequest('nonExistentRequest');
expect(consoleRequest).toEqual(undefined);
});
});
});
24 changes: 20 additions & 4 deletions packages/kbn-search-api-panels/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,23 @@ export const getLanguageDefinitionCodeSnippet = (
}
};

export const getConsoleRequest = (code: keyof LanguageDefinition): string | undefined =>
code in consoleDefinition && typeof consoleDefinition[code] === 'string'
? (consoleDefinition[code] as string)
: undefined;
export const getConsoleRequest = (
code: keyof LanguageDefinition,
args?: LanguageDefinitionSnippetArguments
): string | undefined => {
if (code in consoleDefinition) {
const codeType = consoleDefinition[code];

switch (typeof codeType) {
case 'string':
return codeType as string;
case 'function':
if (args) {
return codeType(args) as string;
}
return undefined;
default:
return undefined;
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ import {
uiSettingsServiceMock,
themeServiceMock,
executionContextServiceMock,
applicationServiceMock,
fatalErrorsServiceMock,
httpServiceMock,
} from '@kbn/core/public/mocks';
import { GlobalFlyout } from '@kbn/es-ui-shared-plugin/public';
import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/server/mocks';
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';

import { sharePluginMock } from '@kbn/share-plugin/public/mocks';
import { settingsServiceMock } from '@kbn/core-ui-settings-browser-mocks';
import { MAJOR_VERSION } from '../../../common';
import { AppContextProvider } from '../../../public/application/app_context';
Expand Down Expand Up @@ -52,15 +56,23 @@ setUiMetricService(services.uiMetricService);
const appDependencies = {
services,
core: {
getUrlForApp: () => {},
getUrlForApp: applicationServiceMock.createStartContract().getUrlForApp,
executionContext: executionContextServiceMock.createStartContract(),
http: httpServiceMock.createSetupContract(),
application: applicationServiceMock.createStartContract(),
fatalErrors: fatalErrorsServiceMock.createSetupContract(),
},
plugins: {
usageCollection: usageCollectionPluginMock.createSetupContract(),
isFleetEnabled: false,
share: sharePluginMock.createStartContract(),
},
plugins: {},
// Default stateful configuration
config: {
enableLegacyTemplates: true,
enableIndexActions: true,
enableIndexStats: true,
enableIndexDetailsPage: false,
},
} as any;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ export interface IndexDetailsPageTestBed extends TestBed {
indexStatsTabExists: () => boolean;
isWarningDisplayed: () => boolean;
};
overview: {
indexStatsContentExists: () => boolean;
indexDetailsContentExists: () => boolean;
addDocCodeBlockExists: () => boolean;
};
};
}

Expand Down Expand Up @@ -116,6 +121,18 @@ export const setup = async (
return find('indexDetailsContent').text();
};

const overview = {
indexStatsContentExists: () => {
return exists('overviewTabIndexStats');
},
indexDetailsContentExists: () => {
return exists('overviewTabIndexDetails');
},
addDocCodeBlockExists: () => {
return exists('codeBlockControlsPanel');
},
};

const mappings = {
getCodeBlockContent: () => {
return find('indexDetailsMappingsCodeBlock').text();
Expand Down Expand Up @@ -258,6 +275,7 @@ export const setup = async (
getActiveTabContent,
mappings,
settings,
overview,
clickBackToIndicesButton,
discoverLinkExists,
contextMenu,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,24 @@ describe('<IndexDetailsPage />', () => {
expect(header).toEqual(testIndexName);
});

it('defaults to overview tab', () => {
const tabContent = testBed.actions.getActiveTabContent();
expect(tabContent).toEqual('Overview');
describe('Overview tab', () => {
it('renders index details', () => {
expect(testBed.actions.overview.indexDetailsContentExists()).toBe(true);
expect(testBed.actions.overview.indexStatsContentExists()).toBe(true);
expect(testBed.actions.overview.addDocCodeBlockExists()).toBe(true);
});

it('hides index stats from detail panels if enableIndexStats===false', async () => {
await act(async () => {
testBed = await setup(httpSetup, {
config: { enableIndexStats: false },
});
});
testBed.component.update();

expect(testBed.actions.overview.indexDetailsContentExists()).toBe(true);
expect(testBed.actions.overview.indexStatsContentExists()).toBe(false);
});
});

it('documents tab', async () => {
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/index_management/kibana.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"optionalPlugins": [
"security",
"usageCollection",
"fleet"
"fleet",
"cloud"
],
"requiredBundles": [
"kibanaReact",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import {
DocLinksStart,
IUiSettingsClient,
ExecutionContextStart,
HttpSetup,
} from '@kbn/core/public';
import { SharePluginStart } from '@kbn/share-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';

import type { SettingsStart } from '@kbn/core-ui-settings-browser';
import type { CloudSetup } from '@kbn/cloud-plugin/public';
import { ExtensionsService } from '../services';
import { UiMetricService, NotificationService, HttpService } from './services';

Expand All @@ -33,10 +35,13 @@ export interface AppDependencies {
getUrlForApp: ApplicationStart['getUrlForApp'];
executionContext: ExecutionContextStart;
application: ApplicationStart;
http: HttpSetup;
};
plugins: {
usageCollection: UsageCollectionSetup;
isFleetEnabled: boolean;
share: SharePluginStart;
cloud?: CloudSetup;
};
services: {
uiMetricService: UiMetricService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { CoreSetup, CoreStart } from '@kbn/core/public';
import { ManagementAppMountParams } from '@kbn/management-plugin/public';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';

import { CloudSetup } from '@kbn/cloud-plugin/public';
import { UIM_APP_NAME } from '../../common/constants';
import { PLUGIN } from '../../common/constants/plugin';
import { ExtensionsService } from '../services';
Expand Down Expand Up @@ -57,6 +58,7 @@ export async function mountManagementSection({
enableLegacyTemplates = true,
enableIndexDetailsPage = false,
enableIndexStats = true,
cloud,
}: {
coreSetup: CoreSetup<StartDependencies>;
usageCollection: UsageCollectionSetup;
Expand All @@ -68,6 +70,7 @@ export async function mountManagementSection({
enableLegacyTemplates?: boolean;
enableIndexDetailsPage?: boolean;
enableIndexStats?: boolean;
cloud?: CloudSetup;
}) {
const { element, setBreadcrumbs, history, theme$ } = params;
const [core, startDependencies] = await coreSetup.getStartServices();
Expand All @@ -79,6 +82,7 @@ export async function mountManagementSection({
uiSettings,
executionContext,
settings,
http,
} = core;

const { url } = startDependencies.share;
Expand All @@ -98,10 +102,13 @@ export async function mountManagementSection({
getUrlForApp: application.getUrlForApp,
executionContext,
application,
http,
},
plugins: {
usageCollection,
isFleetEnabled,
share: startDependencies.share,
cloud,
},
services: {
httpService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { DetailsPageError } from './details_page_error';
import { ManageIndexButton } from './manage_index_button';
import { DetailsPageStats } from './details_page_stats';
import { DetailsPageMappings } from './details_page_mappings';
import { DetailsPageOverview } from './details_page_overview';
import { DetailsPageSettings } from './details_page_settings';

export enum IndexDetailsSection {
Expand Down Expand Up @@ -189,7 +190,7 @@ export const DetailsPage: React.FunctionComponent<
<Routes>
<Route
path={`/${Section.Indices}/${indexName}/${IndexDetailsSection.Overview}`}
render={() => <div>Overview</div>}
render={() => <DetailsPageOverview indexDetails={index} />}
/>
<Route
path={`/${Section.Indices}/${indexName}/${IndexDetailsSection.Documents}`}
Expand Down
Loading

0 comments on commit 4c2f702

Please sign in to comment.