From 97e1206299d176e81c003c1c3e6a4898e1adb1b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Mon, 27 May 2024 16:56:52 +0200 Subject: [PATCH] [Search] Add sync status to connector page (#184024) ## Summary Adds Sync status to connector page. Adds a marker for content/access control sync buttons when last sync failed. Changes logic to show error message to make sure access control errors aren't lost. Fixes incomplete connector query to show correct counts on list. Screenshot 2024-05-22 at 16 01 27 Screenshot 2024-05-22 at 16 03 12 ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../connector_detail/connector_stats.tsx | 6 +-- .../connector_detail/connector_view_logic.ts | 6 ++- .../components/connector_detail/overview.tsx | 5 ++- .../components/connectors/connector_stats.tsx | 1 + .../connectors/connectors_table.tsx | 8 +--- .../search_index/index_view_logic.ts | 6 ++- .../components/search_index/overview.tsx | 18 +++++++-- .../search_index/sync_jobs/sync_jobs.tsx | 12 +++++- .../utils/connector_status_helpers.ts | 37 +++++++++++++------ .../server/utils/get_sync_jobs_queries.ts | 24 +++++------- 10 files changed, 79 insertions(+), 44 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_stats.tsx index 095844b4e04d4..d8725141eb5e3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_stats.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_stats.tsx @@ -122,10 +122,8 @@ export const ConnectorStats: React.FC = ({ connector, index - - {connectorStatusToText(connector?.status, !!connector?.index_name)} + + {connectorStatusToText(connector)} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_view_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_view_logic.ts index f7d6f30ee7d54..42d881300ac5d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_view_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_view_logic.ts @@ -158,7 +158,11 @@ export const ConnectorViewLogic = kea [selectors.connector], (connector) => connector?.id], error: [ () => [selectors.connector], - (connector: Connector | undefined) => connector?.error || connector?.last_sync_error || null, + (connector: Connector | undefined) => + connector?.error || + connector?.last_sync_error || + connector?.last_access_control_sync_error || + null, ], indexName: [ () => [selectors.connector], diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx index a97f7b8c862fd..1931f0f945505 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx @@ -186,7 +186,10 @@ export const ConnectorDetailOverview: React.FC = () => { {connector && connector.service_type !== ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE && ( <> - + )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connector_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connector_stats.tsx index 8b2ad4490a1a6..db76e97ec719e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connector_stats.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connector_stats.tsx @@ -213,6 +213,7 @@ export const ConnectorStats: React.FC = ({ isCrawler }) => {}} onClickAriaLabel={getSyncJobErrorsLabel(errorCount, isCrawler)} + color={errorCount > 0 ? 'danger' : 'default'} > {getSyncJobErrorsLabel(errorCount, isCrawler)} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors_table.tsx index daf3f59eef45e..82f258487f39e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors_table.tsx @@ -135,12 +135,8 @@ export const ConnectorsTable: React.FC = ({ } ), render: (connector: ConnectorViewItem) => { - const label = connectorStatusToText(connector.status, !!connector.index_name); - return ( - - {label} - - ); + const label = connectorStatusToText(connector); + return {label}; }, truncateText: true, width: '15%', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts index 57f6d8f11bfce..597757e83534a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/index_view_logic.ts @@ -264,7 +264,11 @@ export const IndexViewLogic = kea [selectors.connector], - (connector: Connector | undefined) => connector?.error || connector?.last_sync_error || null, + (connector: Connector | undefined) => + connector?.error || + connector?.last_sync_error || + connector?.last_access_control_sync_error || + null, ], hasAdvancedFilteringFeature: [ () => [selectors.connector], diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/overview.tsx index b280d3fbf36b7..f8ccf71026e83 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/overview.tsx @@ -81,7 +81,11 @@ export const SearchIndexOverview: React.FC = () => { defaultMessage="Convert it to a {link}, to be self-managed on your own infrastructure. Native connectors are available only in your Elastic Cloud deployment." values={{ link: ( - + {i18n.translate( 'xpack.enterpriseSearch.content.searchIndex.nativeCloudCallout.connectorClient', { defaultMessage: 'connector client' } @@ -93,7 +97,12 @@ export const SearchIndexOverview: React.FC = () => {

- showModal()}> + showModal()} + > {i18n.translate( 'xpack.enterpriseSearch.content.indices.searchIndex.convertConnector.buttonLabel', { defaultMessage: 'Convert connector' } @@ -126,7 +135,10 @@ export const SearchIndexOverview: React.FC = () => { {isConnectorIndex(indexData) && ( <> - + )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs/sync_jobs.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs/sync_jobs.tsx index 2013d601df4aa..49f4959100736 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs/sync_jobs.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs/sync_jobs.tsx @@ -21,7 +21,15 @@ import { IndexViewLogic } from '../index_view_logic'; import { SyncJobsViewLogic } from './sync_jobs_view_logic'; -export const SyncJobs: React.FC = () => { +export interface SyncJobsProps { + errorOnAccessSync?: boolean; + errorOnContentSync?: boolean; +} + +export const SyncJobs: React.FC = ({ + errorOnAccessSync = false, + errorOnContentSync = false, +}) => { const { hasDocumentLevelSecurityFeature } = useValues(IndexViewLogic); const { productFeatures } = useValues(KibanaLogic); const shouldShowAccessSyncs = @@ -74,6 +82,7 @@ export const SyncJobs: React.FC = () => { 'xpack.enterpriseSearch.content.syncJobs.lastSync.tableSelector.content.label', { defaultMessage: 'Content syncs' } ), + ...(errorOnContentSync ? { iconSide: 'right', iconType: 'warning' } : {}), }, { @@ -82,6 +91,7 @@ export const SyncJobs: React.FC = () => { 'xpack.enterpriseSearch.content.syncJobs.lastSync.tableSelector.accessControl.label', { defaultMessage: 'Access control syncs' } ), + ...(errorOnAccessSync ? { iconSide: 'right', iconType: 'warning' } : {}), }, ]} /> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/connector_status_helpers.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/connector_status_helpers.ts index ef8e84177eae1..587539498c786 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/connector_status_helpers.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/utils/connector_status_helpers.ts @@ -6,17 +6,16 @@ */ import { i18n } from '@kbn/i18n'; -import { ConnectorStatus } from '@kbn/search-connectors'; +import { Connector, ConnectorStatus, SyncStatus } from '@kbn/search-connectors'; const incompleteText = i18n.translate( 'xpack.enterpriseSearch.content.searchIndices.ingestionStatus.incomplete.label', { defaultMessage: 'Incomplete' } ); -export function connectorStatusToText( - connectorStatus: ConnectorStatus, - hasIndexName: boolean -): string { +export function connectorStatusToText(connector: Connector): string { + const hasIndexName = !!connector.index_name; + const connectorStatus = connector.status; if ( connectorStatus === ConnectorStatus.CREATED || connectorStatus === ConnectorStatus.NEEDS_CONFIGURATION @@ -26,6 +25,16 @@ export function connectorStatusToText( { defaultMessage: 'Needs Configuration' } ); } + if ( + connector.error === SyncStatus.ERROR || + connector.last_sync_error !== null || + connector.last_access_control_sync_error !== null + ) { + return i18n.translate( + 'xpack.enterpriseSearch.content.searchIndices.connectorStatus.syncFailure.label', + { defaultMessage: 'Sync Failure' } + ); + } if (connectorStatus === ConnectorStatus.ERROR) { return i18n.translate( 'xpack.enterpriseSearch.content.searchIndices.connectorStatus.connectorFailure.label', @@ -51,18 +60,22 @@ export function connectorStatusToText( return incompleteText; } -export function connectorStatusToColor( - connectorStatus: ConnectorStatus, - hasIndexName: boolean -): 'warning' | 'danger' | 'success' { +export function connectorStatusToColor(connector: Connector): 'warning' | 'danger' | 'success' { + const hasIndexName = !!connector.index_name; + const connectorStatus = connector.status; if (!hasIndexName) { return 'warning'; } + if ( + connectorStatus === ConnectorStatus.ERROR || + connector.error === SyncStatus.ERROR || + connector.last_sync_error !== null || + connector.last_access_control_sync_error !== null + ) { + return 'danger'; + } if (connectorStatus === ConnectorStatus.CONNECTED) { return 'success'; } - if (connectorStatus === ConnectorStatus.ERROR) { - return 'danger'; - } return 'warning'; } diff --git a/x-pack/plugins/enterprise_search/server/utils/get_sync_jobs_queries.ts b/x-pack/plugins/enterprise_search/server/utils/get_sync_jobs_queries.ts index 5fe2e9b17eff7..ff6eeee4db472 100644 --- a/x-pack/plugins/enterprise_search/server/utils/get_sync_jobs_queries.ts +++ b/x-pack/plugins/enterprise_search/server/utils/get_sync_jobs_queries.ts @@ -331,24 +331,18 @@ export const getIncompleteCountQuery = (isCrawler?: boolean) => { } return { bool: { - should: [ - { - bool: { - must_not: { - terms: { - status: [ConnectorStatus.CONNECTED, ConnectorStatus.ERROR], - }, - }, - }, + must_not: { + terms: { + status: [ConnectorStatus.CONNECTED, ConnectorStatus.ERROR], }, - { - range: { - last_seen: { - lt: moment().subtract(30, 'minutes').toISOString(), - }, + }, + must: { + range: { + last_seen: { + lt: moment().subtract(30, 'minutes').toISOString(), }, }, - ], + }, filter: [ { bool: {