Skip to content

Commit

Permalink
Merge branch 'main' into eui-v76.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Mar 14, 2023
2 parents fb004ab + 0343c63 commit c6e73d4
Show file tree
Hide file tree
Showing 30 changed files with 383 additions and 194 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,7 @@
"@types/redux-logger": "^3.0.8",
"@types/resolve": "^1.20.1",
"@types/seedrandom": ">=2.0.0 <4.0.0",
"@types/selenium-webdriver": "^4.1.12",
"@types/selenium-webdriver": "^4.1.13",
"@types/semver": "^7",
"@types/set-value": "^2.0.0",
"@types/sharp": "^0.30.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
'data.search.sessions.management.refreshTimeout (duration)',
'data.search.sessions.maxUpdateRetries (number)',
'data.search.sessions.notTouchedTimeout (duration)',
'enterpriseSearch.canDeployEntSearch (boolean)',
'enterpriseSearch.host (string)',
'home.disableWelcomeScreen (boolean)',
'map.emsFileApiUrl (string)',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ export const DEFAULT_INITIAL_APP_DATA = {
hasSearchEnginesAccess: false,
hasWorkplaceSearchAccess: true,
},
features: {
hasConnectors: true,
hasDefaultIngestPipeline: true,
hasNativeConnectors: true,
hasSearchApplications: false,
hasWebCrawler: true,
},
appSearch: {
accountId: 'some-id-string',
onboardingComplete: true,
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/enterprise_search/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { i18n } from '@kbn/i18n';

import { ProductFeatures } from './types';
import { IngestPipelineParams } from './types/connectors';

export const ENTERPRISE_SEARCH_OVERVIEW_PLUGIN = {
Expand Down Expand Up @@ -161,3 +162,11 @@ export enum INGESTION_METHOD_IDS {
crawler = 'crawler',
native_connector = 'native_connector',
}

export const DEFAULT_PRODUCT_FEATURES: ProductFeatures = {
hasConnectors: true,
hasDefaultIngestPipeline: true,
hasNativeConnectors: true,
hasSearchApplications: false,
hasWebCrawler: true,
};
14 changes: 14 additions & 0 deletions x-pack/plugins/enterprise_search/common/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface InitialAppData {
appSearch?: AppSearchAccount;
configuredLimits?: ConfiguredLimits;
enterpriseSearchVersion?: string;
features?: ProductFeatures;
kibanaVersion?: string;
readOnlyMode?: boolean;
searchOAuth?: SearchOAuth;
Expand All @@ -36,6 +37,14 @@ export interface ProductAccess {
hasWorkplaceSearchAccess: boolean;
}

export interface ProductFeatures {
hasConnectors: boolean;
hasDefaultIngestPipeline: boolean;
hasNativeConnectors: boolean;
hasSearchApplications: boolean;
hasWebCrawler: boolean;
}

export interface SearchOAuth {
clientId: string;
redirectUrl: string;
Expand All @@ -52,5 +61,10 @@ export interface Meta {
page: MetaPage;
}

export interface ClientConfigType {
canDeployEntSearch: boolean;
host?: string;
}

export type { ElasticsearchIndexWithPrivileges } from './indices';
export type { KibanaDeps } from './kibana_deps';
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export const mockKibanaValues = {
hasSearchEnginesAccess: false,
hasWorkplaceSearchAccess: true,
},
productFeatures: {
hasNativeConnectors: true,
hasSearchApplications: false,
hasWebCrawler: true,
},
uiSettings: uiSettingsServiceMock.createStartContract(),
security: securityMock.createStart(),
setBreadcrumbs: jest.fn(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import React, { useState } from 'react';

import { useLocation } from 'react-router-dom';

import { useValues } from 'kea';

import {
EuiBadge,
EuiFlexGroup,
Expand All @@ -22,7 +24,9 @@ import { i18n } from '@kbn/i18n';

import { INGESTION_METHOD_IDS } from '../../../../../common/constants';

import { ProductFeatures } from '../../../../../common/types';
import { BETA_LABEL } from '../../../shared/constants/labels';
import { KibanaLogic } from '../../../shared/kibana/kibana_logic';
import { parseQueryParams } from '../../../shared/query_params';
import { EuiLinkTo } from '../../../shared/react_router_helpers';

Expand All @@ -41,8 +45,8 @@ const betaBadge = (
</EuiBadge>
);

const METHOD_BUTTON_GROUP_OPTIONS: ButtonGroupOption[] = [
{
const METHOD_BUTTON_GROUP_OPTIONS: Record<INGESTION_METHOD_IDS, ButtonGroupOption> = {
[INGESTION_METHOD_IDS.crawler]: {
description: i18n.translate(
'xpack.enterpriseSearch.content.newIndex.buttonGroup.crawler.description',
{
Expand All @@ -58,7 +62,7 @@ const METHOD_BUTTON_GROUP_OPTIONS: ButtonGroupOption[] = [
defaultMessage: 'Use the web crawler',
}),
},
{
[INGESTION_METHOD_IDS.native_connector]: {
badge: betaBadge,
description: i18n.translate(
'xpack.enterpriseSearch.content.newIndex.buttonGroup.nativeConnector.description',
Expand All @@ -82,7 +86,7 @@ const METHOD_BUTTON_GROUP_OPTIONS: ButtonGroupOption[] = [
}
),
},
{
[INGESTION_METHOD_IDS.api]: {
description: i18n.translate(
'xpack.enterpriseSearch.content.newIndex.buttonGroup.api.description',
{
Expand All @@ -98,7 +102,7 @@ const METHOD_BUTTON_GROUP_OPTIONS: ButtonGroupOption[] = [
defaultMessage: 'Use the API',
}),
},
{
[INGESTION_METHOD_IDS.connector]: {
badge: betaBadge,
description: i18n.translate(
'xpack.enterpriseSearch.content.newIndex.buttonGroup.connector.description',
Expand All @@ -116,15 +120,32 @@ const METHOD_BUTTON_GROUP_OPTIONS: ButtonGroupOption[] = [
defaultMessage: 'Build a connector',
}),
},
];
};

const getAvailableMethodOptions = (productFeatures: ProductFeatures): ButtonGroupOption[] => {
return [
...(productFeatures.hasWebCrawler
? [METHOD_BUTTON_GROUP_OPTIONS[INGESTION_METHOD_IDS.crawler]]
: []),
...(productFeatures.hasNativeConnectors
? [METHOD_BUTTON_GROUP_OPTIONS[INGESTION_METHOD_IDS.native_connector]]
: []),
METHOD_BUTTON_GROUP_OPTIONS[INGESTION_METHOD_IDS.api],
...(productFeatures.hasConnectors
? [METHOD_BUTTON_GROUP_OPTIONS[INGESTION_METHOD_IDS.connector]]
: []),
];
};

export const NewIndex: React.FC = () => {
const { search } = useLocation();
const { capabilities, productFeatures } = useValues(KibanaLogic);
const { method: methodParam } = parseQueryParams(search);
const availableIngestionMethodOptions = getAvailableMethodOptions(productFeatures);

const initialSelectedMethod =
METHOD_BUTTON_GROUP_OPTIONS.find((option) => option.id === methodParam) ??
METHOD_BUTTON_GROUP_OPTIONS[0];
availableIngestionMethodOptions.find((option) => option.id === methodParam) ??
availableIngestionMethodOptions[0];

const [selectedMethod, setSelectedMethod] = useState<ButtonGroupOption>(initialSelectedMethod);

Expand Down Expand Up @@ -168,16 +189,20 @@ export const NewIndex: React.FC = () => {
</EuiText>
<EuiSpacer size="m" />
<ButtonGroup
options={METHOD_BUTTON_GROUP_OPTIONS}
options={availableIngestionMethodOptions}
selected={selectedMethod}
onChange={setSelectedMethod}
/>
<EuiSpacer size="xxl" />
<EuiLinkTo to="/app/integrations" shouldNotCreateHref>
{i18n.translate('xpack.enterpriseSearch.content.newIndex.viewIntegrationsLink', {
defaultMessage: 'View additional integrations',
})}
</EuiLinkTo>
{capabilities.navLinks.integrations && (
<>
<EuiSpacer size="xxl" />
<EuiLinkTo to="/app/integrations" shouldNotCreateHref>
{i18n.translate('xpack.enterpriseSearch.content.newIndex.viewIntegrationsLink', {
defaultMessage: 'View additional integrations',
})}
</EuiLinkTo>
</>
)}
</EuiPanel>
</EuiFlexItem>
<EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { flashIndexCreatedToast } from './new_index_created_toast';
import { NewSearchIndexLogic, NewSearchIndexValues } from './new_search_index_logic';

jest.mock('./new_index_created_toast', () => ({ flashIndexCreatedToast: jest.fn() }));
jest.mock('../../../shared/kibana/kibana_logic', () => ({
KibanaLogic: { values: { productAccess: { hasAppSearchAccess: true } } },
}));

const DEFAULT_VALUES: NewSearchIndexValues = {
data: undefined as any,
Expand All @@ -35,14 +38,12 @@ describe('NewSearchIndexLogic', () => {
});

it('has expected default values', () => {
mount();
expect(NewSearchIndexLogic.values).toEqual(DEFAULT_VALUES);
});

describe('actions', () => {
describe('setLanguageSelectValue', () => {
it('sets language to the provided value', () => {
mount();
NewSearchIndexLogic.actions.setLanguageSelectValue('en');
expect(NewSearchIndexLogic.values).toEqual({
...DEFAULT_VALUES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { kea, MakeLogicType } from 'kea';

import { Actions } from '../../../shared/api_logic/create_api_logic';
import { KibanaLogic } from '../../../shared/kibana/kibana_logic';
import {
AddConnectorApiLogic,
AddConnectorApiLogicArgs,
Expand Down Expand Up @@ -84,12 +85,15 @@ export const NewSearchIndexLogic = kea<MakeLogicType<NewSearchIndexValues, NewSe
},
listeners: ({ actions, values }) => ({
apiIndexCreated: () => {
if (!KibanaLogic.values.productAccess.hasAppSearchAccess) return;
flashIndexCreatedToast();
},
connectorIndexCreated: () => {
if (!KibanaLogic.values.productAccess.hasAppSearchAccess) return;
flashIndexCreatedToast();
},
crawlerIndexCreated: () => {
if (!KibanaLogic.values.productAccess.hasAppSearchAccess) return;
flashIndexCreatedToast();
},
setRawName: async (_, breakpoint) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,27 @@ import { SyncsContextMenu } from './syncs_context_menu';

describe('Header Actions', () => {
it('renders api index', () => {
expect(getHeaderActions(apiIndex)).toEqual([
expect(getHeaderActions(apiIndex, true)).toEqual([
<SearchEnginesPopover indexName="api" ingestionMethod="api" isHiddenIndex={false} />,
]);
expect(getHeaderActions(apiIndex, false)).toEqual([]);
});
it('renders connector index', () => {
expect(getHeaderActions(connectorIndex)).toEqual([
expect(getHeaderActions(connectorIndex, true)).toEqual([
<SyncsContextMenu />,
<SearchEnginesPopover
indexName="connector"
ingestionMethod="connector"
isHiddenIndex={false}
/>,
]);
expect(getHeaderActions(connectorIndex, false)).toEqual([<SyncsContextMenu />]);
});
it('renders crawler index', () => {
expect(getHeaderActions(crawlerIndex)).toEqual([
expect(getHeaderActions(crawlerIndex, true)).toEqual([
<CrawlerStatusIndicator />,
<SearchEnginesPopover indexName="crawler" ingestionMethod="crawler" isHiddenIndex={false} />,
]);
expect(getHeaderActions(crawlerIndex, false)).toEqual([<CrawlerStatusIndicator />]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,22 @@ import { SearchEnginesPopover } from './search_engines_popover';
import { SyncsContextMenu } from './syncs_context_menu';

// Used to populate rightSideItems of an EuiPageTemplate, which is rendered right-to-left
export const getHeaderActions = (indexData?: ElasticsearchIndexWithIngestion) => {
export const getHeaderActions = (
indexData: ElasticsearchIndexWithIngestion | undefined,
hasAppSearchAccess: boolean
) => {
const ingestionMethod = getIngestionMethod(indexData);
return [
...(isCrawlerIndex(indexData) && indexData.connector ? [<CrawlerStatusIndicator />] : []),
...(isConnectorIndex(indexData) ? [<SyncsContextMenu />] : []),
<SearchEnginesPopover
indexName={indexData?.name}
ingestionMethod={ingestionMethod}
isHiddenIndex={indexData?.hidden}
/>,
...(hasAppSearchAccess
? [
<SearchEnginesPopover
indexName={indexData?.name}
ingestionMethod={ingestionMethod}
isHiddenIndex={indexData?.hidden}
/>,
]
: []),
];
};
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const ManageKeysPopover: React.FC = () => {
size="s"
items={[
<EuiContextMenuItem
key="viewApiKeys"
data-telemetry-id={`entSearchContent-${ingestionMethod}-overview-generateApiKeys-viewApiKeys`}
icon="eye"
onClick={() =>
Expand All @@ -64,6 +65,7 @@ export const ManageKeysPopover: React.FC = () => {
</EuiText>
</EuiContextMenuItem>,
<EuiContextMenuItem
key="createNewApiKey"
data-telemetry-id={`entSearchContent-${ingestionMethod}-overview-generateApiKeys-createNewApiKey`}
icon="plusInCircle"
onClick={openGenerateModal}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ export const SearchIndex: React.FC = () => {
* This needs to be checked for any of the 3 registered search guideIds
* Putting it here guarantees that if a user is viewing an index with data, it'll be marked as complete
*/
const { guidedOnboarding } = useValues(KibanaLogic);
const {
guidedOnboarding,
productAccess: { hasAppSearchAccess },
productFeatures: { hasDefaultIngestPipeline },
} = useValues(KibanaLogic);
const isAppGuideActive = useObservable(
guidedOnboarding.guidedOnboardingApi!.isGuideStepActive$('appSearch', 'add_data')
);
Expand Down Expand Up @@ -199,7 +203,7 @@ export const SearchIndex: React.FC = () => {
...ALL_INDICES_TABS,
...(isConnectorIndex(index) ? CONNECTOR_TABS : []),
...(isCrawlerIndex(index) ? CRAWLER_TABS : []),
PIPELINES_TAB,
...(hasDefaultIngestPipeline ? [PIPELINES_TAB] : []),
];

const selectedTab = tabs.find((tab) => tab.id === tabId);
Expand All @@ -222,7 +226,7 @@ export const SearchIndex: React.FC = () => {
isLoading={isInitialLoading}
pageHeader={{
pageTitle: indexName,
rightSideItems: getHeaderActions(index),
rightSideItems: getHeaderActions(index, hasAppSearchAccess),
}}
>
{isCrawlerIndex(index) && !index.connector ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Status } from '../../../../../common/types/api';

import { IngestPipelineParams } from '../../../../../common/types/connectors';
import { Actions } from '../../../shared/api_logic/create_api_logic';
import { KibanaLogic } from '../../../shared/kibana';

import {
FetchDefaultPipelineApiLogic,
Expand Down Expand Up @@ -70,6 +71,7 @@ export const SettingsLogic = kea<MakeLogicType<PipelinesValues, PipelinesActions
},
events: ({ actions }) => ({
afterMount: () => {
if (KibanaLogic.values.productFeatures.hasDefaultIngestPipeline === false) return;
actions.fetchDefaultPipeline(undefined);
},
}),
Expand Down
Loading

0 comments on commit c6e73d4

Please sign in to comment.