Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15477,7 +15477,6 @@
"xpack.datasetQuality.details.updateFieldLimitFailed": "Nous n'avons pas pu mettre à jour la limite du champ.",
"xpack.datasetQuality.details.viewDashboardsActionText": "Afficher les tableaux de bord",
"xpack.datasetQuality.editPipeline.strong.Label": "2.",
"xpack.datasetQuality.emptyState.noPrivileges.message": "Vous ne disposez pas des autorisations requises pour voir les données de logs. Assurez-vous d'avoir les autorisations requises pour voir {datasetPattern}.",
"xpack.datasetQuality.emptyState.noPrivileges.title": "Impossible de charger les ensembles de données",
"xpack.datasetQuality.failedDocsColumnName": "Documents échoués (%)",
"xpack.datasetQuality.failedDocsColumnTooltip": "Le pourcentage de documents envoyés au stockage d'échec à cause d'un problème durant l'ingestion.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15495,7 +15495,6 @@
"xpack.datasetQuality.details.updateFieldLimitFailed": "フィールド上限を更新できませんでした。",
"xpack.datasetQuality.details.viewDashboardsActionText": "ダッシュボードを表示",
"xpack.datasetQuality.editPipeline.strong.Label": "2.",
"xpack.datasetQuality.emptyState.noPrivileges.message": "ログデータを表示するために必要な権限がありません。{datasetPattern}を表示するための十分な権限があることを確認してください。",
"xpack.datasetQuality.emptyState.noPrivileges.title": "データセットを読み込めませんでした",
"xpack.datasetQuality.failedDocsColumnName": "失敗したドキュメント(%)",
"xpack.datasetQuality.failedDocsColumnTooltip": "インジェスト時の問題により失敗ストアに送信されたドキュメントの割合。",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15491,7 +15491,6 @@
"xpack.datasetQuality.details.updateFieldLimitFailed": "无法更新字段限制。",
"xpack.datasetQuality.details.viewDashboardsActionText": "查看仪表板",
"xpack.datasetQuality.editPipeline.strong.Label": "2.",
"xpack.datasetQuality.emptyState.noPrivileges.message": "您没有查看日志数据所需的权限。请确保您具有足够的权限,可以查看 {datasetPattern}。",
"xpack.datasetQuality.emptyState.noPrivileges.title": "无法加载数据集",
"xpack.datasetQuality.failedDocsColumnName": "失败的文档 (%)",
"xpack.datasetQuality.failedDocsColumnTooltip": "集成期间由于出现问题发送到失败存储的文档百分比。",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,29 @@ const userPrivilegesRt = rt.type({
canReadFailureStore: rt.boolean,
});

const datasetUserPrivilegesRt = rt.intersection([
userPrivilegesRt,
rt.type({
canRead: rt.boolean,
canViewIntegrations: rt.boolean,
}),
]);
const datasetPrivilegeRt = rt.record(
rt.string,
rt.intersection([
userPrivilegesRt,
rt.type({
canRead: rt.boolean,
}),
])
);

const datasetUserPrivilegesRt = rt.type({
datasetsPrivilages: datasetPrivilegeRt,
canViewIntegrations: rt.boolean,
});

export type DatasetUserPrivileges = rt.TypeOf<typeof datasetUserPrivilegesRt>;
export type DatasetTypesPrivileges = rt.TypeOf<typeof datasetPrivilegeRt>;

export const getDataStreamsTypesPrivilegesResponseRt = rt.exact(
rt.type({
datasetTypesPrivileges: datasetPrivilegeRt,
})
);

export const dataStreamStatRt = rt.intersection([
rt.type({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

import { APIClientRequestParamsOf, APIReturnType } from '../rest';

export type GetDataStreamsTypesPrivilegesParams =
APIClientRequestParamsOf<`GET /internal/dataset_quality/data_streams/types_privileges`>['params'];
export type GetDataStreamsTypesPrivilegesQuery = GetDataStreamsTypesPrivilegesParams['query'];
export type GetDataStreamsTypesPrivilegesResponse =
APIReturnType<`GET /internal/dataset_quality/data_streams/types_privileges`>;

export type GetDataStreamsStatsParams =
APIClientRequestParamsOf<`GET /internal/dataset_quality/data_streams/stats`>['params'];
export type GetDataStreamsStatsQuery = GetDataStreamsStatsParams['query'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,18 @@
*/

import React from 'react';
import { EuiEmptyPrompt, EuiCode } from '@elastic/eui';
import { EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';

import { DEFAULT_LOGS_DATA_VIEW } from '../../../../common/constants';
import { useEmptyState } from '../../../hooks/use_empty_state';
import { useDatasetQualityState } from '../../../hooks/use_dataset_quality_state';

// Allow for lazy loading
// eslint-disable-next-line import/no-default-export
export default function EmptyStateWrapper({ children }: { children: React.ReactNode }) {
const { canReadDataset } = useEmptyState();
const { canUserMonitorAnyDataset, statsLoading } = useDatasetQualityState();

if (!canReadDataset) {
if (!statsLoading && !canUserMonitorAnyDataset) {
return (
<EuiEmptyPrompt
iconType="warning"
Expand All @@ -34,10 +33,7 @@ export default function EmptyStateWrapper({ children }: { children: React.ReactN
<p data-test-subj="datasetQualityNoPrivilegesEmptyState">
<FormattedMessage
id="xpack.datasetQuality.emptyState.noPrivileges.message"
defaultMessage="You don't have the required privileges to view logs data. Make sure you have sufficient privileges to view {datasetPattern}."
values={{
datasetPattern: <EuiCode>{DEFAULT_LOGS_DATA_VIEW}</EuiCode>,
}}
defaultMessage="You don't have the required privileges to view data sets data. Make sure you have sufficient privileges to view data sets."
/>
{/* TODO: Learn more link to docs */}
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ export default function Filters() {
integrations={integrations}
onIntegrationsChange={onIntegrationsChange}
/>
{isDatasetQualityAllSignalsAvailable && (
{isDatasetQualityAllSignalsAvailable && types.length > 1 && (
<Selector
data-test-subj="datasetQualityFilterType"
dataTestSubj="datasetQualityFilterTypeSelectable"
label={typesLabel}
searchPlaceholder={typesSearchPlaceholder}
noneMatchingMessage={typesNoneMatching}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { DEGRADED_DOCS_RULE_TYPE_ID } from '@kbn/rule-data-utils';
import { default as React, useMemo, useState } from 'react';
import { KNOWN_TYPES } from '../../../common/constants';
import { createAlertText, datasetQualityAppTitle } from '../../../common/translations';
import { AlertFlyout } from '../../alerts/alert_flyout';
import { getAlertingCapabilities } from '../../alerts/get_alerting_capabilities';
Expand All @@ -29,10 +28,11 @@ export default function Header() {
const [ruleType, setRuleType] = useState<typeof DEGRADED_DOCS_RULE_TYPE_ID | null>(null);

const { isAlertingAvailable } = getAlertingCapabilities(alerting, capabilities);
const { isDatasetQualityAllSignalsAvailable } = useDatasetQualityFilters();
const { isDatasetQualityAllSignalsAvailable, authorizedDatasetTypes } =
useDatasetQualityFilters();
const validTypes = useMemo(
() => (isDatasetQualityAllSignalsAvailable ? KNOWN_TYPES : [DEFAULT_DATASET_TYPE]),
[isDatasetQualityAllSignalsAvailable]
() => (isDatasetQualityAllSignalsAvailable ? authorizedDatasetTypes : [DEFAULT_DATASET_TYPE]),
[isDatasetQualityAllSignalsAvailable, authorizedDatasetTypes]
);

return (
Expand Down Expand Up @@ -79,7 +79,7 @@ export default function Header() {
/>
}
rightSideItems={
isAlertingAvailable
isAlertingAvailable && validTypes.length
? [
<>
<EuiButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ const datasetQualityColumnTooltip = (

export const getDatasetQualityTableColumns = ({
fieldFormats,
canUserMonitorDataset,
canUserMonitorAnyDataset,
canUserMonitorAnyDataStream,
loadingDataStreamStats,
loadingDocStats,
Expand All @@ -182,7 +182,7 @@ export const getDatasetQualityTableColumns = ({
canReadFailureStore,
}: {
fieldFormats: FieldFormatsStart;
canUserMonitorDataset: boolean;
canUserMonitorAnyDataset: boolean;
canUserMonitorAnyDataStream: boolean;
loadingDataStreamStats: boolean;
loadingDocStats: boolean;
Expand Down Expand Up @@ -247,7 +247,7 @@ export const getDatasetQualityTableColumns = ({
),
width: '160px',
},
...(canUserMonitorDataset && canUserMonitorAnyDataStream
...(canUserMonitorAnyDataset && canUserMonitorAnyDataStream
? [
{
name: (
Expand Down Expand Up @@ -417,7 +417,7 @@ export const getDatasetQualityTableColumns = ({
},
]
: []),
...(canUserMonitorDataset && canUserMonitorAnyDataStream
...(canUserMonitorAnyDataset && canUserMonitorAnyDataStream
? [
{
name: (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const Table = () => {
resultsCount,
showInactiveDatasets,
showFullDatasetNames,
canUserMonitorDataset,
canUserMonitorAnyDataset,
canUserMonitorAnyDataStream,
toggleInactiveDatasets,
toggleFullDatasetNames,
Expand All @@ -63,7 +63,7 @@ export const Table = () => {
tooltipText={fullDatasetNameDescription}
onToggle={toggleFullDatasetNames}
/>
{canUserMonitorDataset && canUserMonitorAnyDataStream && (
{canUserMonitorAnyDataset && canUserMonitorAnyDataStream && (
<DescriptiveSwitch
testSubject="datasetQualityInactiveDatasetsSwitch"
label={inactiveDatasetsLabel}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ const nonAggregatableWarningDescription = (nonAggregatableDatasets: string[]) =>
// eslint-disable-next-line import/no-default-export
export default function Warnings() {
const { loading, nonAggregatableDatasets } = useDatasetQualityWarnings();
const { statsLoading, canUserReadFailureStore } = useDatasetQualityState();
const { statsLoading, canUserReadFailureStore, canUserReadAnyDataset, canUserMonitorAnyDataset } =
useDatasetQualityState();

const canAccessAnyDataset = canUserReadAnyDataset || canUserMonitorAnyDataset;

return (
<EuiFlexGroup data-test-subj="datasetQualityWarningsContainer" gutterSize="s" wrap>
Expand All @@ -95,7 +98,7 @@ export default function Warnings() {
</EuiCallOut>
</EuiFlexItem>
)}
{!statsLoading && !canUserReadFailureStore && (
{!statsLoading && !canUserReadFailureStore && canAccessAnyDataset && (
<EuiFlexItem>
<FailureStoreWarning />
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export const useDatasetQualityDetailsState = () => {
);

const canUserReadFailureStore = Boolean(
dataStreamSettings?.datasetUserPrivileges?.canReadFailureStore
dataStreamSettings?.datasetUserPrivileges?.datasetsPrivilages?.[dataStream]?.canReadFailureStore
);

const dataStreamDetails = useSelector(service, (state) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { OnRefreshChangeProps } from '@elastic/eui';
import { useSelector } from '@xstate/react';
import { useCallback, useMemo } from 'react';
import { DEFAULT_DATASET_TYPE, KNOWN_TYPES } from '../../common/constants';
import { DEFAULT_DATASET_TYPE } from '../../common/constants';
import { DataStreamType, QualityIndicators } from '../../common/types';
import { Integration } from '../../common/data_streams_stats/integration';
import { useDatasetQualityContext } from '../components/dataset_quality/context';
Expand All @@ -23,8 +23,14 @@ export const useDatasetQualityFilters = () => {
const isLoading = useSelector(
service,
(state) =>
state.matches('integrations.fetching') &&
(state.matches('stats.datasets.fetching') || state.matches('stats.degradedDocs.fetching'))
state.matches('initializing') ||
(state.matches('main.integrations.fetching') &&
(state.matches('main.stats.datasets.fetching') ||
state.matches('main.stats.degradedDocs.fetching')))
);

const authorizedDatasetTypes = useSelector(service, (state) =>
!state.matches('initializing') ? state.context.authorizedDatasetTypes : []
);

const {
Expand Down Expand Up @@ -174,14 +180,14 @@ export const useDatasetQualityFilters = () => {

const typeItems: Item[] = useMemo(() => {
const validTypeItems = isDatasetQualityAllSignalsAvailable
? KNOWN_TYPES
? authorizedDatasetTypes
: [DEFAULT_DATASET_TYPE];

return validTypeItems.map((type) => ({
label: type,
checked: selectedTypes.includes(type) ? 'on' : undefined,
}));
}, [isDatasetQualityAllSignalsAvailable, selectedTypes]);
}, [authorizedDatasetTypes, isDatasetQualityAllSignalsAvailable, selectedTypes]);

const onTypesChange = useCallback(
(newTypeItems: Item[]) => {
Expand Down Expand Up @@ -214,6 +220,7 @@ export const useDatasetQualityFilters = () => {
namespaces: namespaceItems,
qualities: qualityItems,
types: typeItems,
authorizedDatasetTypes,
onIntegrationsChange,
onNamespacesChange,
onQualitiesChange,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,34 @@ import { useDatasetQualityContext } from '../components/dataset_quality/context'
export const useDatasetQualityState = () => {
const { service } = useDatasetQualityContext();

const { datasetUserPrivileges } = useSelector(service, (state) => state.context) ?? {};
const { datasetUserPrivileges, dataStreamStats } =
useSelector(service, (state) => state.context) ?? {};

const statsLoading = useSelector(service, (state) => state.matches('stats.datasets.fetching'));
const statsLoading = useSelector(
service,
(state) => state.matches('initializing') || state.matches('main.stats.datasets.fetching')
);

const canUserReadFailureStore = Boolean(datasetUserPrivileges?.canReadFailureStore);
const canUserReadFailureStore = Boolean(
dataStreamStats?.some((ds) => ds.userPrivileges.canReadFailureStore)
);

const canUserMonitorAnyDataset = Boolean(
Object.values(datasetUserPrivileges?.datasetsPrivilages ?? {})?.some(
(privilege) => privilege.canMonitor
)
);

const canUserReadAnyDataset = Boolean(
Object.values(datasetUserPrivileges?.datasetsPrivilages ?? {})?.some(
(privilege) => privilege.canRead
)
);

return {
statsLoading,
canUserReadFailureStore,
canUserMonitorAnyDataset,
canUserReadAnyDataset,
};
};
Loading