mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Disable the actions button if the user has inadequate privileges Co-authored-by: Ersin Erdal <92688503+ersin-erdal@users.noreply.github.com>
This commit is contained in:
parent
7645d475b6
commit
66b6d2b406
4 changed files with 134 additions and 75 deletions
|
@ -38,7 +38,6 @@ import {
|
|||
EuiPopover,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import styled from 'styled-components';
|
||||
import React, { Suspense, useMemo, useState, useCallback, useEffect } from 'react';
|
||||
import usePrevious from 'react-use/lib/usePrevious';
|
||||
|
@ -66,6 +65,7 @@ import { getDefaultCellActions } from './default_cell_actions';
|
|||
import { LazyAlertsFlyout } from '../..';
|
||||
import { parseAlert } from './parse_alert';
|
||||
import { CoreStart } from '../../../../../../src/core/public';
|
||||
import { translations } from './translations';
|
||||
|
||||
const ALERT_DURATION: typeof ALERT_DURATION_TYPED = ALERT_DURATION_NON_TYPED;
|
||||
const ALERT_REASON: typeof ALERT_REASON_TYPED = ALERT_REASON_NON_TYPED;
|
||||
|
@ -115,33 +115,25 @@ export const columns: Array<
|
|||
> = [
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: i18n.translate('xpack.observability.alertsTGrid.statusColumnDescription', {
|
||||
defaultMessage: 'Alert Status',
|
||||
}),
|
||||
displayAsText: translations.statusColumnDescription,
|
||||
id: ALERT_STATUS,
|
||||
initialWidth: 110,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: i18n.translate('xpack.observability.alertsTGrid.lastUpdatedColumnDescription', {
|
||||
defaultMessage: 'Last updated',
|
||||
}),
|
||||
displayAsText: translations.lastUpdatedColumnDescription,
|
||||
id: TIMESTAMP,
|
||||
initialWidth: 230,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: i18n.translate('xpack.observability.alertsTGrid.durationColumnDescription', {
|
||||
defaultMessage: 'Duration',
|
||||
}),
|
||||
displayAsText: translations.durationColumnDescription,
|
||||
id: ALERT_DURATION,
|
||||
initialWidth: 116,
|
||||
},
|
||||
{
|
||||
columnHeaderType: 'not-filtered',
|
||||
displayAsText: i18n.translate('xpack.observability.alertsTGrid.reasonColumnDescription', {
|
||||
defaultMessage: 'Reason',
|
||||
}),
|
||||
displayAsText: translations.reasonColumnDescription,
|
||||
id: ALERT_REASON,
|
||||
linkField: '*',
|
||||
},
|
||||
|
@ -249,73 +241,61 @@ function ObservabilityActions({
|
|||
];
|
||||
}, [afterCaseSelection, casePermissions, timelines, event, statusActionItems, alertPermissions]);
|
||||
|
||||
const viewDetailsTextLabel = i18n.translate(
|
||||
'xpack.observability.alertsTable.viewDetailsTextLabel',
|
||||
{
|
||||
defaultMessage: 'View details',
|
||||
}
|
||||
);
|
||||
const viewInAppTextLabel = i18n.translate('xpack.observability.alertsTable.viewInAppTextLabel', {
|
||||
defaultMessage: 'View in app',
|
||||
});
|
||||
const moreActionsTextLabel = i18n.translate(
|
||||
'xpack.observability.alertsTable.moreActionsTextLabel',
|
||||
{
|
||||
defaultMessage: 'More actions',
|
||||
}
|
||||
);
|
||||
const actionsToolTip =
|
||||
actionsMenuItems.length <= 0
|
||||
? translations.notEnoughPermissions
|
||||
: translations.moreActionsTextLabel;
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup gutterSize="none" responsive={false}>
|
||||
<EuiFlexItem>
|
||||
<EuiToolTip content={viewDetailsTextLabel}>
|
||||
<EuiToolTip content={translations.viewDetailsTextLabel}>
|
||||
<EuiButtonIcon
|
||||
size="s"
|
||||
iconType="expand"
|
||||
color="text"
|
||||
onClick={() => setFlyoutAlert(alert)}
|
||||
data-test-subj="openFlyoutButton"
|
||||
aria-label={viewDetailsTextLabel}
|
||||
aria-label={translations.viewDetailsTextLabel}
|
||||
/>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiToolTip content={viewInAppTextLabel}>
|
||||
<EuiToolTip content={translations.viewInAppTextLabel}>
|
||||
<EuiButtonIcon
|
||||
size="s"
|
||||
href={prepend(alert.link ?? '')}
|
||||
iconType="eye"
|
||||
color="text"
|
||||
aria-label={viewInAppTextLabel}
|
||||
aria-label={translations.viewInAppTextLabel}
|
||||
/>
|
||||
</EuiToolTip>
|
||||
</EuiFlexItem>
|
||||
{actionsMenuItems.length > 0 && (
|
||||
<EuiFlexItem>
|
||||
<EuiPopover
|
||||
button={
|
||||
<EuiToolTip content={moreActionsTextLabel}>
|
||||
<EuiButtonIcon
|
||||
display="empty"
|
||||
size="s"
|
||||
color="text"
|
||||
iconType="boxesHorizontal"
|
||||
aria-label={moreActionsTextLabel}
|
||||
onClick={() => toggleActionsPopover(eventId)}
|
||||
data-test-subj="alerts-table-row-action-more"
|
||||
/>
|
||||
</EuiToolTip>
|
||||
}
|
||||
isOpen={openActionsPopoverId === eventId}
|
||||
closePopover={closeActionsPopover}
|
||||
panelPaddingSize="none"
|
||||
anchorPosition="downLeft"
|
||||
>
|
||||
<EuiContextMenuPanel size="s" items={actionsMenuItems} />
|
||||
</EuiPopover>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
<EuiFlexItem>
|
||||
<EuiPopover
|
||||
button={
|
||||
<EuiToolTip content={actionsToolTip}>
|
||||
<EuiButtonIcon
|
||||
display="empty"
|
||||
disabled={actionsMenuItems.length <= 0}
|
||||
size="s"
|
||||
color="text"
|
||||
iconType="boxesHorizontal"
|
||||
aria-label={actionsToolTip}
|
||||
onClick={() => toggleActionsPopover(eventId)}
|
||||
data-test-subj="alerts-table-row-action-more"
|
||||
/>
|
||||
</EuiToolTip>
|
||||
}
|
||||
isOpen={openActionsPopoverId === eventId}
|
||||
closePopover={closeActionsPopover}
|
||||
panelPaddingSize="none"
|
||||
anchorPosition="downLeft"
|
||||
>
|
||||
<EuiContextMenuPanel size="s" items={actionsMenuItems} />
|
||||
</EuiPopover>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
);
|
||||
|
@ -363,13 +343,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
|
|||
id: 'expand',
|
||||
width: 120,
|
||||
headerCellRender: () => {
|
||||
return (
|
||||
<EventsThContent>
|
||||
{i18n.translate('xpack.observability.alertsTable.actionsTextLabel', {
|
||||
defaultMessage: 'Actions',
|
||||
})}
|
||||
</EventsThContent>
|
||||
);
|
||||
return <EventsThContent>{translations.actionsTextLabel}</EventsThContent>;
|
||||
},
|
||||
rowCellRender: (actionProps: ActionProps) => {
|
||||
return (
|
||||
|
@ -400,12 +374,8 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
|
|||
hasAlertsCrudPermissions,
|
||||
indexNames,
|
||||
itemsPerPageOptions: [10, 25, 50],
|
||||
loadingText: i18n.translate('xpack.observability.alertsTable.loadingTextLabel', {
|
||||
defaultMessage: 'loading alerts',
|
||||
}),
|
||||
footerText: i18n.translate('xpack.observability.alertsTable.footerTextLabel', {
|
||||
defaultMessage: 'alerts',
|
||||
}),
|
||||
loadingText: translations.loadingTextLabel,
|
||||
footerText: translations.footerTextLabel,
|
||||
query: {
|
||||
query: `${ALERT_WORKFLOW_STATUS}: ${workflowStatus}${kuery !== '' ? ` and ${kuery}` : ''}`,
|
||||
language: 'kuery',
|
||||
|
@ -424,11 +394,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
|
|||
filterStatus: workflowStatus as AlertWorkflowStatus,
|
||||
leadingControlColumns,
|
||||
trailingControlColumns,
|
||||
unit: (totalAlerts: number) =>
|
||||
i18n.translate('xpack.observability.alertsTable.showingAlertsTitle', {
|
||||
values: { totalAlerts },
|
||||
defaultMessage: '{totalAlerts, plural, =1 {alert} other {alerts}}',
|
||||
}),
|
||||
unit: (totalAlerts: number) => translations.showingAlertsTitle(totalAlerts),
|
||||
};
|
||||
}, [
|
||||
casePermissions,
|
||||
|
@ -443,6 +409,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
|
|||
leadingControlColumns,
|
||||
deletedEventIds,
|
||||
]);
|
||||
|
||||
const handleFlyoutClose = () => setFlyoutAlert(undefined);
|
||||
const { observabilityRuleTypeRegistry } = usePluginContext();
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
|
||||
export const translations = {
|
||||
viewDetailsTextLabel: i18n.translate('xpack.observability.alertsTable.viewDetailsTextLabel', {
|
||||
defaultMessage: 'View details',
|
||||
}),
|
||||
viewInAppTextLabel: i18n.translate('xpack.observability.alertsTable.viewInAppTextLabel', {
|
||||
defaultMessage: 'View in app',
|
||||
}),
|
||||
moreActionsTextLabel: i18n.translate('xpack.observability.alertsTable.moreActionsTextLabel', {
|
||||
defaultMessage: 'More actions',
|
||||
}),
|
||||
notEnoughPermissions: i18n.translate('xpack.observability.alertsTable.notEnoughPermissions', {
|
||||
defaultMessage: 'Additional privileges required',
|
||||
}),
|
||||
statusColumnDescription: i18n.translate(
|
||||
'xpack.observability.alertsTGrid.statusColumnDescription',
|
||||
{
|
||||
defaultMessage: 'Alert Status',
|
||||
}
|
||||
),
|
||||
lastUpdatedColumnDescription: i18n.translate(
|
||||
'xpack.observability.alertsTGrid.lastUpdatedColumnDescription',
|
||||
{
|
||||
defaultMessage: 'Last updated',
|
||||
}
|
||||
),
|
||||
durationColumnDescription: i18n.translate(
|
||||
'xpack.observability.alertsTGrid.durationColumnDescription',
|
||||
{
|
||||
defaultMessage: 'Duration',
|
||||
}
|
||||
),
|
||||
reasonColumnDescription: i18n.translate(
|
||||
'xpack.observability.alertsTGrid.reasonColumnDescription',
|
||||
{
|
||||
defaultMessage: 'Reason',
|
||||
}
|
||||
),
|
||||
actionsTextLabel: i18n.translate('xpack.observability.alertsTable.actionsTextLabel', {
|
||||
defaultMessage: 'Actions',
|
||||
}),
|
||||
loadingTextLabel: i18n.translate('xpack.observability.alertsTable.loadingTextLabel', {
|
||||
defaultMessage: 'loading alerts',
|
||||
}),
|
||||
footerTextLabel: i18n.translate('xpack.observability.alertsTable.footerTextLabel', {
|
||||
defaultMessage: 'alerts',
|
||||
}),
|
||||
showingAlertsTitle: (totalAlerts: number) =>
|
||||
i18n.translate('xpack.observability.alertsTable.showingAlertsTitle', {
|
||||
values: { totalAlerts },
|
||||
defaultMessage: '{totalAlerts, plural, =1 {alert} other {alerts}}',
|
||||
}),
|
||||
};
|
|
@ -208,6 +208,13 @@ export function ObservabilityAlertsCommonProvider({
|
|||
return buttonText.substring(0, buttonText.indexOf('\n'));
|
||||
};
|
||||
|
||||
const getActionsButtonByIndex = async (index: number) => {
|
||||
const actionsOverflowButtons = await find.allByCssSelector(
|
||||
'[data-test-subj="alerts-table-row-action-more"]'
|
||||
);
|
||||
return actionsOverflowButtons[index] || null;
|
||||
};
|
||||
|
||||
return {
|
||||
getQueryBar,
|
||||
clearQueryBar,
|
||||
|
@ -236,5 +243,6 @@ export function ObservabilityAlertsCommonProvider({
|
|||
typeInQueryBar,
|
||||
openActionsMenuForRow,
|
||||
getTimeRange,
|
||||
getActionsButtonByIndex,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -214,5 +214,28 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Actions Button', () => {
|
||||
before(async () => {
|
||||
await observability.users.setTestUserRole(
|
||||
observability.users.defineBasicObservabilityRole({
|
||||
observabilityCases: ['read'],
|
||||
logs: ['read'],
|
||||
})
|
||||
);
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
await observability.alerts.common.navigateToTimeWithData();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await observability.users.restoreDefaultTestUserRole();
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
});
|
||||
|
||||
it('Is disabled when a user has only read privilages', async () => {
|
||||
const actionsButton = await observability.alerts.common.getActionsButtonByIndex(0);
|
||||
expect(await actionsButton.getAttribute('disabled')).to.be('true');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue