Skip to content

Commit

Permalink
feat(issues): Disable delete on missing permission (#85278)
Browse files Browse the repository at this point in the history
  • Loading branch information
scttcper authored Feb 14, 2025
1 parent 4842a66 commit e3f3e61
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
10 changes: 7 additions & 3 deletions static/app/stores/groupStore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ interface GroupStoreDefinition extends StrictStoreDefinition<Item[]>, InternalDe
onAssignToSuccess: (changeId: string, itemId: string, response: any) => void;

onDelete: (changeId: string, itemIds: ItemIds) => void;
onDeleteError: (changeId: string, itemIds: ItemIds, error: Error) => void;
onDeleteError: (changeId: string, itemIds: ItemIds, response: RequestError) => void;
onDeleteSuccess: (changeId: string, itemIds: ItemIds, response: any) => void;

onDiscard: (changeId: string, itemId: string) => void;
Expand Down Expand Up @@ -347,8 +347,12 @@ const storeConfig: GroupStoreDefinition = {
this.updateItems(ids);
},

onDeleteError(_changeId, itemIds, _response) {
showAlert(t('Unable to delete events. Please try again.'), 'error');
onDeleteError(_changeId, itemIds, response) {
if (response.status === 403) {
showAlert(t('You do not have permission to delete issues'), 'error');
} else {
showAlert(t('Unable to delete events. Please try again.'), 'error');
}

if (!itemIds) {
return;
Expand Down
9 changes: 7 additions & 2 deletions static/app/views/issueList/actions/actionSet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,13 @@ function ActionSet({
const multipleIssueProjectsSelected = multiSelected && !selectedProjectSlug;
const {enabled: mergeSupported, disabledReason: mergeDisabledReason} =
isActionSupported(selectedIssues, 'merge');
const {enabled: deleteSupported, disabledReason: deleteDisabledReason} =
isActionSupported(selectedIssues, 'delete');

// Members may or may not have access to delete events based on organization settings
const hasDeleteAccess = organization.access.includes('event:admin');
const {enabled: deleteSupported, disabledReason: deleteDisabledReason} = hasDeleteAccess
? isActionSupported(selectedIssues, 'delete')
: {enabled: false, disabledReason: t('You do not have permission to delete issues')};

const mergeDisabled =
!multiSelected || multipleIssueProjectsSelected || !mergeSupported;
const ignoreDisabled = !anySelected;
Expand Down
21 changes: 21 additions & 0 deletions static/app/views/issueList/actions/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -466,9 +466,30 @@ describe('IssueListActions', function () {
);
});

it('disables delete if user does not have permission to delete issues', async () => {
jest
.spyOn(SelectedGroupStore, 'getSelectedIds')
.mockImplementation(() => new Set(['1', '2']));
jest.spyOn(GroupStore, 'get').mockImplementation(id => {
return GroupFixture({id});
});

render(<WrappedComponent />);

await userEvent.click(screen.getByRole('button', {name: 'More issue actions'}));
expect(screen.getByRole('menuitemradio', {name: 'Delete'})).toHaveAttribute(
'aria-disabled',
'true'
);
expect(screen.getByRole('menuitemradio', {name: 'Delete'})).toHaveTextContent(
'You do not have permission to delete issues'
);
});

describe('bulk action performance issues', function () {
const orgWithPerformanceIssues = OrganizationFixture({
features: ['performance-issues'],
access: ['event:admin'],
});

it('silently filters out performance issues when bulk deleting', async function () {
Expand Down

0 comments on commit e3f3e61

Please sign in to comment.