mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Dataset quality] UI improvements to failed flyout errors table (#208511)
Closes https://github.com/elastic/observability-design/issues/365. ## Summary This PR aims to improve failure store errors table in the flyout. The following acceptance criteria items were resolved ### Dataset quality page - [x] Show upfront 200-208 characters in `message` column. - [x] Provide link to Discover, filtered by error.type, in `type` column. 🎥 Demo https://github.com/user-attachments/assets/f318a54e-88d0-4801-af28-14e93a03e39d
This commit is contained in:
parent
70b860b9ec
commit
242e319a9c
4 changed files with 120 additions and 7 deletions
|
@ -7,8 +7,10 @@
|
|||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiBadge, EuiBasicTableColumn, EuiCode, EuiIcon, EuiToolTip } from '@elastic/eui';
|
||||
import { EuiBasicTableColumn, EuiIcon, EuiToolTip } from '@elastic/eui';
|
||||
import { FailedDocsError } from '../../../../../common/api_types';
|
||||
import { ErrorStacktraceLink } from './error_stacktrace_link';
|
||||
import { ErrorMessage } from './error_message';
|
||||
|
||||
const contentColumnName = i18n.translate(
|
||||
'xpack.datasetQuality.details.qualityIssue.failedDocs.erros.contentLabel',
|
||||
|
@ -36,7 +38,7 @@ export const getFailedDocsErrorsColumns = (): Array<EuiBasicTableColumn<FailedDo
|
|||
name: contentColumnName,
|
||||
field: 'message',
|
||||
render: (_, { message }) => {
|
||||
return <EuiCode language="js">{message}</EuiCode>;
|
||||
return <ErrorMessage errorMessage={message} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -50,11 +52,7 @@ export const getFailedDocsErrorsColumns = (): Array<EuiBasicTableColumn<FailedDo
|
|||
),
|
||||
field: 'type',
|
||||
render: (_, { type }) => {
|
||||
return (
|
||||
<EuiBadge color="hollow">
|
||||
<strong>{type}</strong>
|
||||
</EuiBadge>
|
||||
);
|
||||
return <ErrorStacktraceLink errorType={type} />;
|
||||
},
|
||||
sortable: true,
|
||||
},
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 { EuiCode, EuiFlexGroup } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
|
||||
const readMore = i18n.translate(
|
||||
'xpack.datasetQuality.details.qualityIssue.failedDocs.erros.message.readMore',
|
||||
{
|
||||
defaultMessage: 'Read more',
|
||||
}
|
||||
);
|
||||
|
||||
const readLess = i18n.translate(
|
||||
'xpack.datasetQuality.details.qualityIssue.failedDocs.erros.message.readLess',
|
||||
{
|
||||
defaultMessage: 'Read less',
|
||||
}
|
||||
);
|
||||
|
||||
const MAX_CHAR_LENGTH = 200;
|
||||
|
||||
const readMoreMessageContent = (message: string) => {
|
||||
return `${message.slice(0, MAX_CHAR_LENGTH)}...`;
|
||||
};
|
||||
|
||||
export const ErrorMessage = ({ errorMessage }: { errorMessage: string }) => {
|
||||
const showReadMoreOrLess = errorMessage.length > MAX_CHAR_LENGTH;
|
||||
const [message, setMessage] = React.useState(
|
||||
showReadMoreOrLess ? readMoreMessageContent(errorMessage) : errorMessage
|
||||
);
|
||||
|
||||
const handleReadMore = () => {
|
||||
setMessage((prev) => {
|
||||
return prev.length === errorMessage.length
|
||||
? readMoreMessageContent(errorMessage)
|
||||
: errorMessage;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiFlexGroup direction="column" gutterSize="none">
|
||||
<EuiCode language="js" style={{ fontWeight: 'normal' }}>
|
||||
{message}
|
||||
</EuiCode>
|
||||
{showReadMoreOrLess && (
|
||||
<EuiCode>
|
||||
<button onClick={handleReadMore} style={{ fontWeight: 'bold' }}>
|
||||
{message.length === errorMessage.length ? readLess : readMore}
|
||||
</button>
|
||||
</EuiCode>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 { EuiBadge, EuiLink } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { NavigationSource } from '../../../../services/telemetry';
|
||||
import { FAILURE_STORE_SELECTOR } from '../../../../../common/constants';
|
||||
import {
|
||||
useDatasetDetailsRedirectLinkTelemetry,
|
||||
useDatasetQualityDetailsState,
|
||||
useRedirectLink,
|
||||
} from '../../../../hooks';
|
||||
|
||||
export const ErrorStacktraceLink = ({
|
||||
errorType,
|
||||
children,
|
||||
}: {
|
||||
errorType: string;
|
||||
children?: React.ReactNode;
|
||||
}) => {
|
||||
const { datasetDetails, timeRange } = useDatasetQualityDetailsState();
|
||||
const query = { language: 'kuery', query: `error.type: "${errorType}"` };
|
||||
const { sendTelemetry } = useDatasetDetailsRedirectLinkTelemetry({
|
||||
query,
|
||||
navigationSource: NavigationSource.FailedDocsFlyoutErrorsTable,
|
||||
});
|
||||
|
||||
const { linkProps } = useRedirectLink({
|
||||
dataStreamStat: datasetDetails,
|
||||
query,
|
||||
sendTelemetry,
|
||||
timeRangeConfig: timeRange,
|
||||
selector: FAILURE_STORE_SELECTOR,
|
||||
});
|
||||
|
||||
return (
|
||||
<EuiBadge color="hollow">
|
||||
<strong>{errorType}</strong>
|
||||
<EuiLink
|
||||
external
|
||||
{...linkProps}
|
||||
color="primary"
|
||||
data-test-subj={`datasetQualityTableDetailsLink-${datasetDetails.name}`}
|
||||
target="_blank"
|
||||
>
|
||||
{children}
|
||||
</EuiLink>
|
||||
</EuiBadge>
|
||||
);
|
||||
};
|
|
@ -38,6 +38,7 @@ export enum NavigationSource {
|
|||
Table = 'table',
|
||||
ActionMenu = 'action_menu',
|
||||
DegradedFieldFlyoutHeader = 'degraded_field_flyout_header',
|
||||
FailedDocsFlyoutErrorsTable = 'failed_docs_flyout_errors_table',
|
||||
}
|
||||
|
||||
export interface WithTrackingId {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue