[App Search] Added an EntryPointsTable (#108316)

This commit is contained in:
Jason Stoltzfus 2021-08-12 12:39:58 -04:00 committed by GitHub
parent caaa76feab
commit 4d7fd0a0ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 679 additions and 4 deletions

View file

@ -0,0 +1,119 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { shallow } from 'enzyme';
import { EuiFieldText } from '@elastic/eui';
import { GenericEndpointInlineEditableTable } from '../../../../shared/tables/generic_endpoint_inline_editable_table';
import { mountWithIntl } from '../../../../test_helpers';
import { EntryPointsTable } from './entry_points_table';
describe('EntryPointsTable', () => {
const engineName = 'my-engine';
const entryPoints = [
{ id: '1', value: '/whatever' },
{ id: '2', value: '/foo' },
];
const domain = {
createdOn: '2018-01-01T00:00:00.000Z',
documentCount: 10,
id: '6113e1407a2f2e6f42489794',
url: 'https://www.elastic.co',
crawlRules: [],
entryPoints,
sitemaps: [],
};
beforeEach(() => {
jest.clearAllMocks();
});
it('renders', () => {
const wrapper = shallow(
<EntryPointsTable domain={domain} engineName={engineName} items={domain.entryPoints} />
);
expect(wrapper.find(GenericEndpointInlineEditableTable).exists()).toBe(true);
});
describe('the first and only column in the table', () => {
it('shows the value of an entry point', () => {
const entryPoint = { id: '1', value: '/whatever' };
const wrapper = shallow(
<EntryPointsTable domain={domain} engineName={engineName} items={domain.entryPoints} />
);
const columns = wrapper.find(GenericEndpointInlineEditableTable).prop('columns');
const column = shallow(<div>{columns[0].render(entryPoint)}</div>);
expect(column.html()).toContain('/whatever');
});
it('can show the value of an entry point as editable', () => {
const entryPoint = { id: '1', value: '/whatever' };
const onChange = jest.fn();
const wrapper = shallow(
<EntryPointsTable domain={domain} engineName={engineName} items={domain.entryPoints} />
);
const columns = wrapper.find(GenericEndpointInlineEditableTable).prop('columns');
const column = shallow(
<div>
{columns[0].editingRender(entryPoint, onChange, { isInvalid: false, isLoading: false })}
</div>
);
const textField = column.find(EuiFieldText);
expect(textField.props()).toEqual(
expect.objectContaining({
value: '/whatever',
disabled: false, // It would be disabled if isLoading is true
isInvalid: false,
prepend: 'https://www.elastic.co',
})
);
textField.simulate('change', { target: { value: '/foo' } });
expect(onChange).toHaveBeenCalledWith('/foo');
});
});
describe('routes', () => {
it('can calculate an update and delete route correctly', () => {
const wrapper = shallow(
<EntryPointsTable domain={domain} engineName={engineName} items={domain.entryPoints} />
);
const table = wrapper.find(GenericEndpointInlineEditableTable);
const entryPoint = { id: '1', value: '/whatever' };
expect(table.prop('deleteRoute')(entryPoint)).toEqual(
'/api/app_search/engines/my-engine/crawler/domains/6113e1407a2f2e6f42489794/entry_points/1'
);
expect(table.prop('updateRoute')(entryPoint)).toEqual(
'/api/app_search/engines/my-engine/crawler/domains/6113e1407a2f2e6f42489794/entry_points/1'
);
});
});
it('shows a no items message whem there are no entry points to show', () => {
const wrapper = shallow(
<EntryPointsTable domain={domain} engineName={engineName} items={domain.entryPoints} />
);
const editNewItems = jest.fn();
const table = wrapper.find(GenericEndpointInlineEditableTable);
const message = mountWithIntl(<div>{table.prop('noItemsMessage')!(editNewItems)}</div>);
expect(message.html()).toContain('There are no existing entry points.');
});
});

View file

@ -0,0 +1,150 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { useActions } from 'kea';
import { EuiFieldText, EuiLink, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { GenericEndpointInlineEditableTable } from '../../../../shared/tables/generic_endpoint_inline_editable_table';
import { InlineEditableTableColumn } from '../../../../shared/tables/inline_editable_table/types';
import { ItemWithAnID } from '../../../../shared/tables/types';
import { DOCS_PREFIX } from '../../../routes';
import { CrawlerDomain, EntryPoint } from '../types';
import { EntryPointsTableLogic } from './entry_points_table_logic';
interface EntryPointsTableProps {
domain: CrawlerDomain;
engineName: string;
items: EntryPoint[];
}
export const EntryPointsTable: React.FC<EntryPointsTableProps> = ({
domain,
engineName,
items,
}) => {
const { onAdd, onDelete, onUpdate } = useActions(EntryPointsTableLogic);
const field = 'value';
const columns: Array<InlineEditableTableColumn<ItemWithAnID>> = [
{
editingRender: (entryPoint, onChange, { isInvalid, isLoading }) => (
<EuiFieldText
fullWidth
value={(entryPoint as EntryPoint)[field]}
onChange={(e) => onChange(e.target.value)}
disabled={isLoading}
isInvalid={isInvalid}
prepend={domain.url}
/>
),
render: (entryPoint) => (
<EuiText size="s">
{domain.url}
{(entryPoint as EntryPoint)[field]}
</EuiText>
),
name: i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.urlTableHead',
{ defaultMessage: 'URL' }
),
field,
},
];
const entryPointsRoute = `/api/app_search/engines/${engineName}/crawler/domains/${domain.id}/entry_points`;
const getEntryPointRoute = (entryPoint: EntryPoint) =>
`/api/app_search/engines/${engineName}/crawler/domains/${domain.id}/entry_points/${entryPoint.id}`;
return (
<GenericEndpointInlineEditableTable
addButtonText={i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.addButtonLabel',
{ defaultMessage: 'Add entry point' }
)}
columns={columns}
description={
<p>
{i18n.translate('xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.description', {
defaultMessage:
'Include the most important URLs for your website here. Entry point URLs will be the first pages to be indexed and processed for links to other pages.',
})}{' '}
<EuiLink
href={`${DOCS_PREFIX}/crawl-web-content.html#crawl-web-content-manage-entry-points`}
target="_blank"
external
>
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.learnMoreLinkText',
{ defaultMessage: 'Learn more about entry points.' }
)}
</EuiLink>
</p>
}
instanceId="EntryPointsTable"
items={items}
lastItemWarning={i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.lastItemMessage',
{ defaultMessage: 'The crawler requires at least one entry point.' }
)}
// Since canRemoveLastItem is false, the only time noItemsMessage would be displayed is if the last entry point was deleted via the API.
noItemsMessage={(editNewItem) => (
<>
<EuiSpacer />
<EuiTitle size="m">
<h4>
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.emptyMessageTitle',
{
defaultMessage: 'There are no existing entry points.',
}
)}
</h4>
</EuiTitle>
<EuiSpacer />
<EuiText>
<FormattedMessage
id="xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.emptyMessageDescription"
defaultMessage="{link} to specify an entry point
for the crawler"
values={{
link: (
<EuiLink onClick={editNewItem}>
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.emptyMessageLinkText',
{ defaultMessage: 'Add an entry point' }
)}
</EuiLink>
),
}}
/>
</EuiText>
<EuiSpacer />
</>
)}
addRoute={entryPointsRoute}
canRemoveLastItem={false}
deleteRoute={getEntryPointRoute}
updateRoute={getEntryPointRoute}
dataProperty="entry_points"
onAdd={onAdd}
onDelete={onDelete}
onUpdate={onUpdate}
title={i18n.translate('xpack.enterpriseSearch.appSearch.crawler.entryPointsTable.title', {
defaultMessage: 'Entry points',
})}
disableReordering
/>
);
};

View file

@ -0,0 +1,77 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
jest.mock('../crawler_single_domain_logic', () => ({
CrawlerSingleDomainLogic: {
actions: {
updateEntryPoints: jest.fn(),
},
},
}));
import { LogicMounter, mockFlashMessageHelpers } from '../../../../__mocks__/kea_logic';
import { CrawlerSingleDomainLogic } from '../crawler_single_domain_logic';
import { EntryPointsTableLogic } from './entry_points_table_logic';
describe('EntryPointsTableLogic', () => {
const { mount } = new LogicMounter(EntryPointsTableLogic);
const { clearFlashMessages, flashSuccessToast } = mockFlashMessageHelpers;
beforeEach(() => {
jest.clearAllMocks();
});
describe('listeners', () => {
describe('onAdd', () => {
it('should update the entry points for the current domain, and clear flash messages', () => {
const entryThatWasAdded = { id: '2', value: 'bar' };
const updatedEntries = [
{ id: '1', value: 'foo' },
{ id: '2', value: 'bar' },
];
mount();
EntryPointsTableLogic.actions.onAdd(entryThatWasAdded, updatedEntries);
expect(CrawlerSingleDomainLogic.actions.updateEntryPoints).toHaveBeenCalledWith(
updatedEntries
);
expect(clearFlashMessages).toHaveBeenCalled();
});
});
describe('onDelete', () => {
it('should update the entry points for the current domain, clear flash messages, and show a success toast', () => {
const entryThatWasDeleted = { id: '2', value: 'bar' };
const updatedEntries = [{ id: '1', value: 'foo' }];
mount();
EntryPointsTableLogic.actions.onDelete(entryThatWasDeleted, updatedEntries);
expect(CrawlerSingleDomainLogic.actions.updateEntryPoints).toHaveBeenCalledWith(
updatedEntries
);
expect(clearFlashMessages).toHaveBeenCalled();
expect(flashSuccessToast).toHaveBeenCalled();
});
});
describe('onUpdate', () => {
it('should update the entry points for the current domain, clear flash messages, and show a success toast', () => {
const entryThatWasUpdated = { id: '2', value: 'baz' };
const updatedEntries = [
{ id: '1', value: 'foo' },
{ id: '2', value: 'baz' },
];
mount();
EntryPointsTableLogic.actions.onUpdate(entryThatWasUpdated, updatedEntries);
expect(CrawlerSingleDomainLogic.actions.updateEntryPoints).toHaveBeenCalledWith(
updatedEntries
);
expect(clearFlashMessages).toHaveBeenCalled();
});
});
});
});

View file

@ -0,0 +1,59 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { kea, MakeLogicType } from 'kea';
import { clearFlashMessages, flashSuccessToast } from '../../../../shared/flash_messages';
import { CrawlerSingleDomainLogic } from '../crawler_single_domain_logic';
import { EntryPoint } from '../types';
interface EntryPointsTableValues {
dataLoading: boolean;
}
interface EntryPointsTableActions {
onAdd(
entryPoint: EntryPoint,
entryPoints: EntryPoint[]
): { entryPoint: EntryPoint; entryPoints: EntryPoint[] };
onDelete(
entryPoint: EntryPoint,
entryPoints: EntryPoint[]
): { entryPoint: EntryPoint; entryPoints: EntryPoint[] };
onUpdate(
entryPoint: EntryPoint,
entryPoints: EntryPoint[]
): { entryPoint: EntryPoint; entryPoints: EntryPoint[] };
}
export const EntryPointsTableLogic = kea<
MakeLogicType<EntryPointsTableValues, EntryPointsTableActions>
>({
path: ['enterprise_search', 'app_search', 'crawler', 'entry_points_table'],
actions: () => ({
onAdd: (entryPoint, entryPoints) => ({ entryPoint, entryPoints }),
onDelete: (entryPoint, entryPoints) => ({ entryPoint, entryPoints }),
onUpdate: (entryPoint, entryPoints) => ({ entryPoint, entryPoints }),
}),
listeners: () => ({
onAdd: ({ entryPoints }) => {
CrawlerSingleDomainLogic.actions.updateEntryPoints(entryPoints);
clearFlashMessages();
},
onDelete: ({ entryPoint, entryPoints }) => {
CrawlerSingleDomainLogic.actions.updateEntryPoints(entryPoints);
clearFlashMessages();
flashSuccessToast(`Entry point "${entryPoint.value}" was removed.`);
},
onUpdate: ({ entryPoints }) => {
CrawlerSingleDomainLogic.actions.updateEntryPoints(entryPoints);
clearFlashMessages();
},
}),
});

View file

@ -11,22 +11,24 @@ import { useParams } from 'react-router-dom';
import { useActions, useValues } from 'kea';
import { EuiCode, EuiSpacer, EuiTitle } from '@elastic/eui';
import { EuiCode, EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { getEngineBreadcrumbs } from '../engine';
import { EngineLogic, getEngineBreadcrumbs } from '../engine';
import { AppSearchPageTemplate } from '../layout';
import { CrawlerStatusBanner } from './components/crawler_status_banner';
import { CrawlerStatusIndicator } from './components/crawler_status_indicator/crawler_status_indicator';
import { DeleteDomainPanel } from './components/delete_domain_panel';
import { EntryPointsTable } from './components/entry_points_table';
import { ManageCrawlsPopover } from './components/manage_crawls_popover/manage_crawls_popover';
import { CRAWLER_TITLE } from './constants';
import { CrawlerSingleDomainLogic } from './crawler_single_domain_logic';
export const CrawlerSingleDomain: React.FC = () => {
const { domainId } = useParams() as { domainId: string };
const { engineName } = EngineLogic.values;
const { dataLoading, domain } = useValues(CrawlerSingleDomainLogic);
@ -51,6 +53,14 @@ export const CrawlerSingleDomain: React.FC = () => {
>
<CrawlerStatusBanner />
<EuiSpacer size="l" />
{domain && (
<>
<EuiPanel paddingSize="l" hasBorder>
<EntryPointsTable domain={domain} engineName={engineName} items={domain.entryPoints} />
</EuiPanel>
<EuiSpacer size="xl" />
</>
)}
<EuiTitle size="s">
<h2>
{i18n.translate(

View file

@ -51,6 +51,36 @@ describe('CrawlerSingleDomainLogic', () => {
expect(CrawlerSingleDomainLogic.values.domain).toEqual(domain);
});
});
describe('updateEntryPoints', () => {
beforeEach(() => {
mount({
domain: {
id: '507f1f77bcf86cd799439011',
entryPoints: [],
},
});
CrawlerSingleDomainLogic.actions.updateEntryPoints([
{
id: '1234',
value: '/',
},
]);
});
it('should update the entry points on the domain', () => {
expect(CrawlerSingleDomainLogic.values.domain).toEqual({
id: '507f1f77bcf86cd799439011',
entryPoints: [
{
id: '1234',
value: '/',
},
],
});
});
});
});
describe('listeners', () => {

View file

@ -14,7 +14,7 @@ import { KibanaLogic } from '../../../shared/kibana';
import { ENGINE_CRAWLER_PATH } from '../../routes';
import { EngineLogic, generateEnginePath } from '../engine';
import { CrawlerDomain } from './types';
import { CrawlerDomain, EntryPoint } from './types';
import { crawlerDomainServerToClient, getDeleteDomainSuccessMessage } from './utils';
export interface CrawlerSingleDomainValues {
@ -26,6 +26,7 @@ interface CrawlerSingleDomainActions {
deleteDomain(domain: CrawlerDomain): { domain: CrawlerDomain };
fetchDomainData(domainId: string): { domainId: string };
onReceiveDomainData(domain: CrawlerDomain): { domain: CrawlerDomain };
updateEntryPoints(entryPoints: EntryPoint[]): { entryPoints: EntryPoint[] };
}
export const CrawlerSingleDomainLogic = kea<
@ -36,6 +37,7 @@ export const CrawlerSingleDomainLogic = kea<
deleteDomain: (domain) => ({ domain }),
fetchDomainData: (domainId) => ({ domainId }),
onReceiveDomainData: (domain) => ({ domain }),
updateEntryPoints: (entryPoints) => ({ entryPoints }),
},
reducers: {
dataLoading: [
@ -48,6 +50,8 @@ export const CrawlerSingleDomainLogic = kea<
null,
{
onReceiveDomainData: (_, { domain }) => domain,
updateEntryPoints: (currentDomain, { entryPoints }) =>
({ ...currentDomain, entryPoints } as CrawlerDomain),
},
],
},

View file

@ -32,6 +32,7 @@ export interface GenericEndpointInlineEditableTableProps
onDelete(item: ItemWithAnID, items: ItemWithAnID[]): void;
onUpdate(item: ItemWithAnID, items: ItemWithAnID[]): void;
onReorder?(items: ItemWithAnID[]): void;
disableReordering?: boolean;
}
export const GenericEndpointInlineEditableTable = ({

View file

@ -0,0 +1,8 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
export { GenericEndpointInlineEditableTable } from './generic_endpoint_inline_editable_table';

View file

@ -33,6 +33,7 @@ export interface InlineEditableTableProps<Item extends ItemWithAnID> {
canRemoveLastItem?: boolean;
className?: string;
description?: React.ReactNode;
disableReordering?: boolean;
isLoading?: boolean;
lastItemWarning?: string;
noItemsMessage?: (editNewItem: () => void) => React.ReactNode;
@ -170,6 +171,7 @@ export const InlineEditableTableContents = <Item extends ItemWithAnID>({
noItemsMessage={noItemsMessage(editNewItem)}
onReorder={reorderItems}
disableDragging={isEditing}
{...rest}
/>
</>
);

View file

@ -6,6 +6,6 @@
*/
export type ItemWithAnID = {
id: number | null;
id: number | string | null;
created_at?: string;
} & object;

View file

@ -0,0 +1,134 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { mockDependencies, mockRequestHandler, MockRouter } from '../../__mocks__';
import { registerCrawlerEntryPointRoutes } from './crawler_entry_points';
describe('crawler entry point routes', () => {
describe('POST /api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points', () => {
let mockRouter: MockRouter;
beforeEach(() => {
jest.clearAllMocks();
mockRouter = new MockRouter({
method: 'post',
path: '/api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points',
});
registerCrawlerEntryPointRoutes({
...mockDependencies,
router: mockRouter.router,
});
});
it('creates a request to enterprise search', () => {
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
path: '/api/as/v0/engines/:engineName/crawler/domains/:domainId/entry_points',
params: {
respond_with: 'index',
},
});
});
it('validates correctly with required params', () => {
const request = {
params: { engineName: 'some-engine', domainId: '1234' },
body: {
value: 'test',
},
};
mockRouter.shouldValidate(request);
});
it('fails otherwise', () => {
const request = { params: {}, body: {} };
mockRouter.shouldThrow(request);
});
});
describe('PUT /api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points/{entryPointId}', () => {
let mockRouter: MockRouter;
beforeEach(() => {
jest.clearAllMocks();
mockRouter = new MockRouter({
method: 'put',
path:
'/api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points/{entryPointId}',
});
registerCrawlerEntryPointRoutes({
...mockDependencies,
router: mockRouter.router,
});
});
it('creates a request to enterprise search', () => {
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
path: '/api/as/v0/engines/:engineName/crawler/domains/:domainId/entry_points/:entryPointId',
params: {
respond_with: 'index',
},
});
});
it('validates correctly with required params', () => {
const request = {
params: { engineName: 'some-engine', domainId: '1234', entryPointId: '5678' },
body: {
value: 'test',
},
};
mockRouter.shouldValidate(request);
});
it('fails otherwise', () => {
const request = { params: {}, body: {} };
mockRouter.shouldThrow(request);
});
});
describe('DELETE /api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points/{entryPointId}', () => {
let mockRouter: MockRouter;
beforeEach(() => {
jest.clearAllMocks();
mockRouter = new MockRouter({
method: 'delete',
path:
'/api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points/{entryPointId}',
});
registerCrawlerEntryPointRoutes({
...mockDependencies,
router: mockRouter.router,
});
});
it('creates a request to enterprise search', () => {
expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
path: '/api/as/v0/engines/:engineName/crawler/domains/:domainId/entry_points/:entryPointId',
params: {
respond_with: 'index',
},
});
});
it('validates correctly with required params', () => {
const request = {
params: { engineName: 'some-engine', domainId: '1234', entryPointId: '5678' },
};
mockRouter.shouldValidate(request);
});
it('fails otherwise', () => {
const request = { params: {} };
mockRouter.shouldThrow(request);
});
});
});

View file

@ -0,0 +1,79 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { schema } from '@kbn/config-schema';
import { RouteDependencies } from '../../plugin';
export function registerCrawlerEntryPointRoutes({
router,
enterpriseSearchRequestHandler,
}: RouteDependencies) {
router.post(
{
path: '/api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points',
validate: {
params: schema.object({
engineName: schema.string(),
domainId: schema.string(),
}),
body: schema.object({
value: schema.string(),
}),
},
},
enterpriseSearchRequestHandler.createRequest({
path: '/api/as/v0/engines/:engineName/crawler/domains/:domainId/entry_points',
params: {
respond_with: 'index',
},
})
);
router.put(
{
path:
'/api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points/{entryPointId}',
validate: {
params: schema.object({
engineName: schema.string(),
domainId: schema.string(),
entryPointId: schema.string(),
}),
body: schema.object({
value: schema.string(),
}),
},
},
enterpriseSearchRequestHandler.createRequest({
path: '/api/as/v0/engines/:engineName/crawler/domains/:domainId/entry_points/:entryPointId',
params: {
respond_with: 'index',
},
})
);
router.delete(
{
path:
'/api/app_search/engines/{engineName}/crawler/domains/{domainId}/entry_points/{entryPointId}',
validate: {
params: schema.object({
engineName: schema.string(),
domainId: schema.string(),
entryPointId: schema.string(),
}),
},
},
enterpriseSearchRequestHandler.createRequest({
path: '/api/as/v0/engines/:engineName/crawler/domains/:domainId/entry_points/:entryPointId',
params: {
respond_with: 'index',
},
})
);
}

View file

@ -10,6 +10,7 @@ import { RouteDependencies } from '../../plugin';
import { registerAnalyticsRoutes } from './analytics';
import { registerApiLogsRoutes } from './api_logs';
import { registerCrawlerRoutes } from './crawler';
import { registerCrawlerEntryPointRoutes } from './crawler_entry_points';
import { registerCredentialsRoutes } from './credentials';
import { registerCurationsRoutes } from './curations';
import { registerDocumentsRoutes, registerDocumentRoutes } from './documents';
@ -44,4 +45,5 @@ export const registerAppSearchRoutes = (dependencies: RouteDependencies) => {
registerApiLogsRoutes(dependencies);
registerOnboardingRoutes(dependencies);
registerCrawlerRoutes(dependencies);
registerCrawlerEntryPointRoutes(dependencies);
};