Skip to content

Commit 36cbbb9

Browse files
rStelmachkibanamachineyngrdyn
authored
[Dataset Quality] Indicate if failure store isn't enabled for data stream (#221644)
Added a tooltip and a link with documentation for Failed docs column when dataset does not have failure store enabled. https://github.com/user-attachments/assets/be65db9a-15c8-4087-b175-752b2fabab6e For now it awaits for the documentation PR to be merged : elastic/docs-content#1368 --------- Co-authored-by: kibanamachine <[email protected]> Co-authored-by: Yngrid Coello <[email protected]>
1 parent 853c4bd commit 36cbbb9

File tree

16 files changed

+264
-46
lines changed

16 files changed

+264
-46
lines changed

x-pack/platform/plugins/shared/dataset_quality/common/api_types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const dataStreamStatRt = rt.intersection([
3434
integration: rt.string,
3535
totalDocs: rt.number,
3636
creationDate: rt.number,
37+
hasFailureStore: rt.boolean,
3738
}),
3839
]);
3940

@@ -236,6 +237,7 @@ export const dataStreamSettingsRt = rt.partial({
236237
export type DataStreamSettings = rt.TypeOf<typeof dataStreamSettingsRt>;
237238

238239
export const dataStreamDetailsRt = rt.partial({
240+
hasFailureStore: rt.boolean,
239241
lastActivity: rt.number,
240242
degradedDocsCount: rt.number,
241243
failedDocsCount: rt.number,

x-pack/platform/plugins/shared/dataset_quality/common/data_streams_stats/data_stream_stat.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export class DataStreamStat {
3232
docsInTimeRange?: number;
3333
degradedDocs: QualityStat;
3434
failedDocs: QualityStat;
35+
hasFailureStore?: DataStreamStatType['hasFailureStore'];
3536

3637
private constructor(dataStreamStat: DataStreamStat) {
3738
this.rawName = dataStreamStat.rawName;
@@ -49,13 +50,15 @@ export class DataStreamStat {
4950
this.docsInTimeRange = dataStreamStat.docsInTimeRange;
5051
this.degradedDocs = dataStreamStat.degradedDocs;
5152
this.failedDocs = dataStreamStat.failedDocs;
53+
this.hasFailureStore = dataStreamStat.hasFailureStore;
5254
}
5355

5456
public static create(dataStreamStat: DataStreamStatType) {
5557
const { type, dataset, namespace } = indexNameToDataStreamParts(dataStreamStat.name);
5658

5759
const dataStreamStatProps = {
5860
rawName: dataStreamStat.name,
61+
hasFailureStore: dataStreamStat.hasFailureStore,
5962
type,
6063
name: dataset,
6164
title: dataset,
@@ -79,17 +82,20 @@ export class DataStreamStat {
7982
failedDocStat,
8083
datasetIntegrationMap,
8184
totalDocs,
85+
hasFailureStore,
8286
}: {
8387
datasetName: string;
8488
degradedDocStat: QualityStat;
8589
failedDocStat: QualityStat;
8690
datasetIntegrationMap: Record<string, { integration: Integration; title: string }>;
8791
totalDocs: number;
92+
hasFailureStore?: boolean;
8893
}) {
8994
const { type, dataset, namespace } = indexNameToDataStreamParts(datasetName);
9095

9196
const dataStreamStatProps = {
9297
rawName: datasetName,
98+
hasFailureStore,
9399
type,
94100
name: dataset,
95101
title: datasetIntegrationMap[dataset]?.title || dataset,

x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality/table/columns.tsx

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -355,29 +355,69 @@ export const getDatasetQualityTableColumns = ({
355355
),
356356
field: 'failedDocs.percentage',
357357
sortable: true,
358-
render: (_: any, dataStreamStat: DataStreamStat) => (
359-
<PrivilegesWarningIconWrapper
360-
title={`sizeBytes-${dataStreamStat.title}`}
361-
hasPrivileges={dataStreamStat.userPrivileges?.canReadFailureStore ?? true}
362-
>
363-
<QualityStatPercentageLink
364-
isLoading={loadingFailedStats}
365-
dataStreamStat={dataStreamStat}
366-
timeRange={timeRange}
367-
accessor="failedDocs"
368-
selector={FAILURE_STORE_SELECTOR}
369-
fewDocStatsTooltip={(failedDocsCount: number) =>
370-
i18n.translate('xpack.datasetQuality.fewFailedDocsTooltip', {
371-
defaultMessage: '{failedDocsCount} failed docs in this data set.',
372-
values: {
373-
failedDocsCount,
374-
},
375-
})
376-
}
377-
dataTestSubj="datasetQualityFailedDocsPercentageLink"
378-
/>
379-
</PrivilegesWarningIconWrapper>
380-
),
358+
render: (_: any, dataStreamStat: DataStreamStat) => {
359+
if (!dataStreamStat.hasFailureStore) {
360+
const FailureStoreHoverLink = () => {
361+
const [hovered, setHovered] = React.useState(false);
362+
const locator = urlService.locators.get('INDEX_MANAGEMENT_LOCATOR_ID');
363+
const params = {
364+
page: 'data_streams_details',
365+
dataStreamName: dataStreamStat.rawName,
366+
} as const;
367+
368+
return (
369+
<EuiToolTip
370+
content={i18n.translate('xpack.datasetQuality.failureStore.notEnabled', {
371+
defaultMessage:
372+
'Failure store is not enabled for this data stream. Enable failure store.',
373+
})}
374+
>
375+
<EuiLink
376+
href={locator?.getRedirectUrl(params)}
377+
target="_blank"
378+
external={false}
379+
data-test-subj="datasetQualitySetFailureStoreLink"
380+
onMouseEnter={() => setHovered(true)}
381+
onMouseLeave={() => setHovered(false)}
382+
css={{ fontWeight: 'normal' }}
383+
>
384+
{hovered
385+
? i18n.translate('xpack.datasetQuality.failureStore.enable', {
386+
defaultMessage: 'Set failure store',
387+
})
388+
: i18n.translate('xpack.datasetQuality.failureStore.notAvailable', {
389+
defaultMessage: 'N/A',
390+
})}
391+
</EuiLink>
392+
</EuiToolTip>
393+
);
394+
};
395+
return <FailureStoreHoverLink />;
396+
}
397+
return (
398+
<PrivilegesWarningIconWrapper
399+
title={`sizeBytes-${dataStreamStat.title}`}
400+
hasPrivileges={dataStreamStat.userPrivileges?.canReadFailureStore ?? true}
401+
>
402+
<QualityStatPercentageLink
403+
isLoading={loadingFailedStats}
404+
dataStreamStat={dataStreamStat}
405+
timeRange={timeRange}
406+
accessor="failedDocs"
407+
selector={FAILURE_STORE_SELECTOR}
408+
fewDocStatsTooltip={(failedDocsCount: number) =>
409+
i18n.translate('xpack.datasetQuality.fewFailedDocsTooltip', {
410+
defaultMessage: '{failedDocsCount} failed docs in this data set.',
411+
values: {
412+
failedDocsCount,
413+
},
414+
})
415+
}
416+
dataTestSubj="datasetQualityFailedDocsPercentageLink"
417+
/>
418+
</PrivilegesWarningIconWrapper>
419+
);
420+
},
381421
width: '140px',
382422
},
383423
]

x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality/table/table.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export const Table = () => {
7575
</EuiFlexGroup>
7676
</EuiFlexGroup>
7777
<EuiSpacer size="s" />
78-
<EuiHorizontalRule margin="none" style={{ height: 2 }} />
78+
<EuiHorizontalRule margin="none" css={{ height: 2 }} />
7979
<EuiBasicTable
8080
tableLayout="auto"
8181
sorting={sort}

x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality_details/overview/document_trends/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const degradedDocsTooltip = (
6060
// Allow for lazy loading
6161
// eslint-disable-next-line import/no-default-export
6262
export default function DocumentTrends({ lastReloadTime }: { lastReloadTime: number }) {
63-
const { timeRange, updateTimeRange, docsTrendChart, canUserReadFailureStore } =
63+
const { timeRange, updateTimeRange, docsTrendChart, canShowFailureStoreInfo } =
6464
useDatasetQualityDetailsState();
6565
const {
6666
dataView,
@@ -81,7 +81,7 @@ export default function DocumentTrends({ lastReloadTime }: { lastReloadTime: num
8181
[updateTimeRange, timeRange.refresh]
8282
);
8383

84-
const accordionTitle = !canUserReadFailureStore ? (
84+
const accordionTitle = !canShowFailureStoreInfo ? (
8585
<EuiFlexItem
8686
css={css`
8787
flex-direction: row;
@@ -127,7 +127,7 @@ export default function DocumentTrends({ lastReloadTime }: { lastReloadTime: num
127127
<EuiSpacer size="m" />
128128
<EuiFlexGroup justifyContent="flexEnd" gutterSize="s">
129129
<EuiFlexItem>
130-
{canUserReadFailureStore && (
130+
{canShowFailureStoreInfo && (
131131
<EuiButtonGroup
132132
data-test-subj="datasetQualityDetailsChartTypeButtonGroup"
133133
legend={i18n.translate('xpack.datasetQuality.details.chartTypeLegend', {

x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality_details/overview/index.tsx

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77

88
import React, { useCallback, useState } from 'react';
99
import { dynamic } from '@kbn/shared-ux-utility';
10-
import { EuiFlexItem, EuiSpacer, OnRefreshProps } from '@elastic/eui';
10+
import { EuiCallOut, EuiFlexItem, EuiLink, EuiSpacer, OnRefreshProps } from '@elastic/eui';
11+
import { i18n } from '@kbn/i18n';
1112
import { useDatasetQualityDetailsState } from '../../../hooks';
1213
import { AggregationNotSupported } from './aggregation_not_supported';
1314
import { QualityIssues } from './quality_issues';
1415
import { FailureStoreWarning } from '../../failure_store/failure_store_warning';
16+
import { useKibanaContextForPlugin } from '../../../utils/use_kibana';
1517

1618
const OverviewHeader = dynamic(() => import('./header'));
1719
const Summary = dynamic(() => import('./summary'));
@@ -22,9 +24,20 @@ export function Overview() {
2224
dataStream,
2325
isNonAggregatable,
2426
canUserReadFailureStore,
27+
hasFailureStore,
2528
updateTimeRange,
2629
loadingState: { dataStreamSettingsLoading },
2730
} = useDatasetQualityDetailsState();
31+
32+
const {
33+
services: {
34+
share: { url: urlService },
35+
},
36+
} = useKibanaContextForPlugin();
37+
38+
const locator = urlService.locators.get('INDEX_MANAGEMENT_LOCATOR_ID');
39+
const locatorParams = { page: 'data_streams_details', dataStreamName: dataStream } as const;
40+
2841
const [lastReloadTime, setLastReloadTime] = useState<number>(Date.now());
2942

3043
const handleRefresh = useCallback(
@@ -39,6 +52,31 @@ export function Overview() {
3952
{isNonAggregatable && <AggregationNotSupported dataStream={dataStream} />}
4053
<OverviewHeader handleRefresh={handleRefresh} />
4154
<EuiSpacer size="m" />
55+
{!dataStreamSettingsLoading && !hasFailureStore && canUserReadFailureStore && (
56+
<div style={{ marginBottom: 16 }}>
57+
<EuiCallOut
58+
color="warning"
59+
title={
60+
<>
61+
{i18n.translate('xpack.datasetQuality.noFailureStoreTitle', {
62+
defaultMessage: 'Failure store is not enabled for this data stream. ',
63+
})}
64+
<EuiLink
65+
href={locator?.getRedirectUrl(locatorParams)}
66+
target="_blank"
67+
external={false}
68+
css={{ textDecoration: 'underline' }}
69+
>
70+
{i18n.translate('xpack.datasetQuality.enableFailureStore', {
71+
defaultMessage: 'Enable failure store',
72+
})}
73+
</EuiLink>
74+
</>
75+
}
76+
/>
77+
</div>
78+
)}
79+
4280
{!dataStreamSettingsLoading && !canUserReadFailureStore && (
4381
<EuiFlexItem>
4482
<FailureStoreWarning />

x-pack/platform/plugins/shared/dataset_quality/public/components/dataset_quality_details/overview/summary/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const failedDocsColumnTooltip = (
4848
// Allow for lazy loading
4949
// eslint-disable-next-line import/no-default-export
5050
export default function Summary() {
51-
const { canUserReadFailureStore } = useDatasetQualityDetailsState();
51+
const { canShowFailureStoreInfo } = useDatasetQualityDetailsState();
5252
const {
5353
isSummaryPanelLoading,
5454
totalDocsCount,
@@ -103,7 +103,7 @@ export default function Summary() {
103103
isLoading={isSummaryPanelLoading}
104104
tooltip={degradedDocsTooltip}
105105
/>
106-
{canUserReadFailureStore && (
106+
{canShowFailureStoreInfo && (
107107
<PanelIndicator
108108
label={overviewPanelDatasetQualityIndicatorFailedDocs}
109109
value={totalFailedDocsCount}

x-pack/platform/plugins/shared/dataset_quality/public/hooks/use_dataset_quality_details_state.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ export const useDatasetQualityDetailsState = () => {
160160
[service]
161161
);
162162

163+
const hasFailureStore = Boolean(dataStreamDetails?.hasFailureStore);
164+
const canShowFailureStoreInfo = canUserReadFailureStore && hasFailureStore;
165+
163166
return {
164167
service,
165168
telemetryClient,
@@ -182,6 +185,8 @@ export const useDatasetQualityDetailsState = () => {
182185
canUserAccessDashboards,
183186
canUserViewIntegrations,
184187
canUserReadFailureStore,
188+
hasFailureStore,
189+
canShowFailureStoreInfo,
185190
expandedQualityIssue,
186191
isQualityIssueFlyoutOpen,
187192
};

0 commit comments

Comments
 (0)