[Alerting UI] Fixed display permissions for edit/delete buttons when user has read only access. (#107996) (#108130)
* [Alerting UI] Fixed display permissions for Edit/delete buttons when user has read only access * fixed due to comments
This commit is contained in:
parent
d08b49f313
commit
331a27c6f5
5 changed files with 145 additions and 25 deletions
|
@ -434,10 +434,10 @@ describe('alerts_list component with items', () => {
|
|||
expect(wrapper.find('[data-test-subj="alertSidebarDeleteAction"]').exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('does not render edit button when rule type does not allow editing in rules management', async () => {
|
||||
it('does not render edit and delete button when rule type does not allow editing in rules management', async () => {
|
||||
await setup(false);
|
||||
expect(wrapper.find('[data-test-subj="alertSidebarEditAction"]').exists()).toBeFalsy();
|
||||
expect(wrapper.find('[data-test-subj="alertSidebarDeleteAction"]').exists()).toBeTruthy();
|
||||
expect(wrapper.find('[data-test-subj="alertSidebarDeleteAction"]').exists()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -567,11 +567,18 @@ describe('alerts_list with show only capability', () => {
|
|||
});
|
||||
}
|
||||
|
||||
it('renders table of alerts with edit button disabled', async () => {
|
||||
await setup();
|
||||
expect(wrapper.find('EuiBasicTable')).toHaveLength(1);
|
||||
expect(wrapper.find('EuiTableRow')).toHaveLength(2);
|
||||
expect(wrapper.find('[data-test-subj="editActionHoverButton"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('renders table of alerts with delete button disabled', async () => {
|
||||
await setup();
|
||||
expect(wrapper.find('EuiBasicTable')).toHaveLength(1);
|
||||
expect(wrapper.find('EuiTableRow')).toHaveLength(2);
|
||||
// TODO: check delete button
|
||||
expect(wrapper.find('[data-test-subj="deleteActionHoverButton"]')).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -464,28 +464,27 @@ export const AlertsList: React.FunctionComponent = () => {
|
|||
name: '',
|
||||
width: '10%',
|
||||
render(item: AlertTableItem) {
|
||||
return (
|
||||
return item.isEditable && isRuleTypeEditableInContext(item.alertTypeId) ? (
|
||||
<EuiFlexGroup justifyContent="spaceBetween" gutterSize="s">
|
||||
<EuiFlexItem grow={false} className="alertSidebarItem">
|
||||
<EuiFlexGroup justifyContent="flexEnd" gutterSize="s">
|
||||
{item.isEditable && isRuleTypeEditableInContext(item.alertTypeId) && (
|
||||
<EuiFlexItem grow={false} data-test-subj="alertSidebarEditAction">
|
||||
<EuiButtonIcon
|
||||
color={'primary'}
|
||||
title={i18n.translate(
|
||||
'xpack.triggersActionsUI.sections.alertsList.alertsListTable.columns.editButtonTooltip',
|
||||
{ defaultMessage: 'Edit' }
|
||||
)}
|
||||
className="alertSidebarItem__action"
|
||||
onClick={() => onRuleEdit(item)}
|
||||
iconType={'pencil'}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.triggersActionsUI.sections.alertsList.alertsListTable.columns.editAriaLabel',
|
||||
{ defaultMessage: 'Edit' }
|
||||
)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
<EuiFlexItem grow={false} data-test-subj="alertSidebarEditAction">
|
||||
<EuiButtonIcon
|
||||
color={'primary'}
|
||||
title={i18n.translate(
|
||||
'xpack.triggersActionsUI.sections.alertsList.alertsListTable.columns.editButtonTooltip',
|
||||
{ defaultMessage: 'Edit' }
|
||||
)}
|
||||
className="alertSidebarItem__action"
|
||||
data-test-subj="editActionHoverButton"
|
||||
onClick={() => onRuleEdit(item)}
|
||||
iconType={'pencil'}
|
||||
aria-label={i18n.translate(
|
||||
'xpack.triggersActionsUI.sections.alertsList.alertsListTable.columns.editAriaLabel',
|
||||
{ defaultMessage: 'Edit' }
|
||||
)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false} data-test-subj="alertSidebarDeleteAction">
|
||||
<EuiButtonIcon
|
||||
color={'danger'}
|
||||
|
@ -494,6 +493,7 @@ export const AlertsList: React.FunctionComponent = () => {
|
|||
{ defaultMessage: 'Delete' }
|
||||
)}
|
||||
className="alertSidebarItem__action"
|
||||
data-test-subj="deleteActionHoverButton"
|
||||
onClick={() => setAlertsToDelete([item.id])}
|
||||
iconType={'trash'}
|
||||
aria-label={i18n.translate(
|
||||
|
@ -504,6 +504,7 @@ export const AlertsList: React.FunctionComponent = () => {
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<CollapsedItemActions
|
||||
key={item.id}
|
||||
|
@ -514,7 +515,7 @@ export const AlertsList: React.FunctionComponent = () => {
|
|||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
) : null;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
import { mountWithIntl, nextTick } from '@kbn/test/jest';
|
||||
|
@ -95,6 +94,20 @@ describe('CollapsedItemActions', () => {
|
|||
};
|
||||
};
|
||||
|
||||
test('renders panel items as disabled', async () => {
|
||||
await setup();
|
||||
const wrapper = mountWithIntl(
|
||||
<CollapsedItemActions {...getPropsWithRule({ isEditable: false })} />
|
||||
);
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
});
|
||||
expect(
|
||||
wrapper.find('[data-test-subj="selectActionButton"]').first().props().disabled
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
test('renders closed popover initially and opens on click with all actions enabled', async () => {
|
||||
await setup();
|
||||
const wrapper = mountWithIntl(<CollapsedItemActions {...getPropsWithRule()} />);
|
||||
|
@ -118,6 +131,10 @@ describe('CollapsedItemActions', () => {
|
|||
expect(wrapper.find('[data-test-subj="editAlert"]').exists()).toBeTruthy();
|
||||
expect(wrapper.find('[data-test-subj="deleteAlert"]').exists()).toBeTruthy();
|
||||
|
||||
expect(
|
||||
wrapper.find('[data-test-subj="selectActionButton"]').first().props().disabled
|
||||
).toBeFalsy();
|
||||
|
||||
expect(wrapper.find(`[data-test-subj="muteButton"] button`).prop('disabled')).toBeFalsy();
|
||||
expect(wrapper.find(`[data-test-subj="muteButton"] button`).text()).toEqual('Mute');
|
||||
expect(wrapper.find(`[data-test-subj="disableButton"] button`).prop('disabled')).toBeFalsy();
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
import { mountWithIntl } from '@kbn/test/jest';
|
||||
import { RuleEnabledSwitch, ComponentOpts } from './rule_enabled_switch';
|
||||
|
||||
describe('RuleEnabledSwitch', () => {
|
||||
const enableAlert = jest.fn();
|
||||
const props: ComponentOpts = {
|
||||
disableAlert: jest.fn(),
|
||||
enableAlert,
|
||||
item: {
|
||||
id: '1',
|
||||
name: 'test alert',
|
||||
tags: ['tag1'],
|
||||
enabled: true,
|
||||
alertTypeId: 'test_alert_type',
|
||||
schedule: { interval: '5d' },
|
||||
actions: [],
|
||||
params: { name: 'test alert type name' },
|
||||
createdBy: null,
|
||||
updatedBy: null,
|
||||
apiKeyOwner: null,
|
||||
throttle: '1m',
|
||||
muteAll: false,
|
||||
mutedInstanceIds: [],
|
||||
executionStatus: {
|
||||
status: 'active',
|
||||
lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
|
||||
},
|
||||
consumer: 'test',
|
||||
actionsCount: 0,
|
||||
alertType: 'test_alert_type',
|
||||
createdAt: new Date('2020-08-20T19:23:38Z'),
|
||||
enabledInLicense: true,
|
||||
isEditable: false,
|
||||
notifyWhen: null,
|
||||
tagsText: 'test',
|
||||
updatedAt: new Date('2020-08-20T19:23:38Z'),
|
||||
},
|
||||
onAlertChanged: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => jest.resetAllMocks());
|
||||
|
||||
test('renders switch control as disabled when rule is not editable', () => {
|
||||
const wrapper = mountWithIntl(<RuleEnabledSwitch {...props} />);
|
||||
expect(wrapper.find('[data-test-subj="enableSwitch"]').first().props().disabled).toBeTruthy();
|
||||
});
|
||||
|
||||
test('renders switch control', () => {
|
||||
const wrapper = mountWithIntl(
|
||||
<RuleEnabledSwitch
|
||||
{...{
|
||||
...props,
|
||||
item: {
|
||||
id: '1',
|
||||
name: 'test alert',
|
||||
tags: ['tag1'],
|
||||
enabled: false,
|
||||
alertTypeId: 'test_alert_type',
|
||||
schedule: { interval: '5d' },
|
||||
actions: [],
|
||||
params: { name: 'test alert type name' },
|
||||
createdBy: null,
|
||||
updatedBy: null,
|
||||
apiKeyOwner: null,
|
||||
throttle: '1m',
|
||||
muteAll: false,
|
||||
mutedInstanceIds: [],
|
||||
executionStatus: {
|
||||
status: 'active',
|
||||
lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
|
||||
},
|
||||
consumer: 'test',
|
||||
actionsCount: 0,
|
||||
alertType: 'test_alert_type',
|
||||
createdAt: new Date('2020-08-20T19:23:38Z'),
|
||||
enabledInLicense: true,
|
||||
isEditable: true,
|
||||
notifyWhen: null,
|
||||
tagsText: 'test',
|
||||
updatedAt: new Date('2020-08-20T19:23:38Z'),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
expect(wrapper.find('[data-test-subj="enableSwitch"]').first().props().checked).toBeFalsy();
|
||||
});
|
||||
});
|
|
@ -10,7 +10,7 @@ import { EuiSwitch, EuiLoadingSpinner } from '@elastic/eui';
|
|||
|
||||
import { Alert, AlertTableItem } from '../../../../types';
|
||||
|
||||
interface ComponentOpts {
|
||||
export interface ComponentOpts {
|
||||
item: AlertTableItem;
|
||||
onAlertChanged: () => void;
|
||||
enableAlert: (alert: Alert) => Promise<void>;
|
||||
|
|
Loading…
Reference in a new issue