From: Wouter Admiraal Date: Thu, 27 Apr 2023 09:53:27 +0000 (+0200) Subject: Revert "SONAR-19069 Disable the option to change an issue type in issues list and... X-Git-Tag: 10.1.0.73491~371 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=48de5bcbfd91b0acde1f310dae14f13e4a1f14e2;p=sonarqube.git Revert "SONAR-19069 Disable the option to change an issue type in issues list and issue view" This reverts commit 166f4620f857b53508fd737a28706b613848e48c. --- diff --git a/server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts index a60cbccd420..42eb29d92e2 100644 --- a/server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/IssuesServiceMock.ts @@ -62,8 +62,8 @@ import { editIssueComment, getIssueChangelog, getIssueFlowSnippets, - searchIssues, searchIssueTags, + searchIssues, setIssueAssignee, setIssueSeverity, setIssueTags, @@ -529,11 +529,11 @@ export default class IssuesServiceMock { } handleBulkChangeIssues = (issueKeys: string[], query: RequestData) => { - //For now we only check for issue severity change. + //For now we only check for issue type change. this.list .filter((i) => issueKeys.includes(i.issue.key)) .forEach((data) => { - data.issue.severity = query.set_severity; + data.issue.type = query.set_type; }); return this.reply({}); }; diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx index ac00a46ee7e..a7c11cbc3ca 100644 --- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx +++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesApp-it.tsx @@ -246,6 +246,12 @@ describe('issues app', () => { // Check that we bulk change the selected issue const issueBoxFixThat = within(screen.getByRole('region', { name: 'Fix that' })); + expect( + issueBoxFixThat.getByRole('button', { + name: 'issue.type.type_x_click_to_change.issue.type.CODE_SMELL', + }) + ).toBeInTheDocument(); + await user.click( screen.getByRole('checkbox', { name: 'issues.action_select.label.Fix that' }) ); @@ -255,14 +261,14 @@ describe('issues app', () => { await user.keyboard('New Comment'); expect(screen.getByRole('button', { name: 'apply' })).toBeDisabled(); - await selectEvent.select(screen.getByRole('combobox', { name: 'issue.set_severity' }), [ - 'severity.BLOCKER', + await selectEvent.select(screen.getByRole('combobox', { name: 'issue.set_type' }), [ + 'issue.type.BUG', ]); await user.click(screen.getByRole('button', { name: 'apply' })); expect( issueBoxFixThat.getByRole('button', { - name: 'issue.severity.severity_x_click_to_change.severity.BLOCKER', + name: 'issue.type.type_x_click_to_change.issue.type.BUG', }) ).toBeInTheDocument(); }); @@ -617,6 +623,22 @@ describe('issues item', () => { // Get a specific issue list item const listItem = within(await screen.findByRole('region', { name: 'Fix that' })); + // Change issue type + await user.click( + listItem.getByRole('button', { + name: `issue.type.type_x_click_to_change.issue.type.CODE_SMELL`, + }) + ); + expect(listItem.getByText('issue.type.BUG')).toBeInTheDocument(); + expect(listItem.getByText('issue.type.VULNERABILITY')).toBeInTheDocument(); + + await user.click(listItem.getByText('issue.type.VULNERABILITY')); + expect( + listItem.getByRole('button', { + name: `issue.type.type_x_click_to_change.issue.type.VULNERABILITY`, + }) + ).toBeInTheDocument(); + // Change issue severity expect(listItem.getByText('severity.MAJOR')).toBeInTheDocument(); diff --git a/server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx b/server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx index fb3e941c7bd..1a31ccfb7ff 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx @@ -33,13 +33,14 @@ import Select, { LabelValueSelectOption, SearchSelect, } from '../../../components/controls/Select'; +import IssueTypeIcon from '../../../components/icons/IssueTypeIcon'; import SeverityHelper from '../../../components/shared/SeverityHelper'; import { Alert } from '../../../components/ui/Alert'; import DeferredSpinner from '../../../components/ui/DeferredSpinner'; import { SEVERITIES } from '../../../helpers/constants'; import { throwGlobalError } from '../../../helpers/error'; import { translate, translateWithParameters } from '../../../helpers/l10n'; -import { Component, Dict, Issue, Paging } from '../../../types/types'; +import { Component, Dict, Issue, IssueType, Paging } from '../../../types/types'; import { CurrentUser } from '../../../types/users'; import AssigneeSelect, { AssigneeOption } from './AssigneeSelect'; @@ -66,6 +67,7 @@ interface FormFields { removeTags?: Array<{ label: string; value: string }>; severity?: string; transition?: string; + type?: string; } interface State extends FormFields { @@ -83,10 +85,30 @@ enum InputField { assignee = 'assignee', removeTags = 'removeTags', severity = 'severity', + type = 'type', } export const MAX_PAGE_SIZE = 500; +function typeFieldTypeRenderer(option: LabelValueSelectOption) { + return ( +
+ + {option.label} +
+ ); +} + +function TypeFieldOptionComponent(props: OptionProps) { + return {typeFieldTypeRenderer(props.data)}; +} + +function TypeFieldSingleValueComponent(props: SingleValueProps) { + return ( + {typeFieldTypeRenderer(props.data)} + ); +} + function SeverityFieldOptionComponent(props: OptionProps) { return ( @@ -196,6 +218,7 @@ export default class BulkChangeModal extends React.PureComponent { remove_tags: this.state.removeTags && this.state.removeTags.map((t) => t.value).join(), sendNotifications: this.state.notifications, set_severity: this.state.severity, + set_type: this.state.type, }, (x) => x !== undefined ); @@ -235,14 +258,15 @@ export default class BulkChangeModal extends React.PureComponent { } canSubmit = () => { - const { addTags, assignee, removeTags, severity, transition } = this.state; + const { addTags, assignee, removeTags, severity, transition, type } = this.state; return Boolean( (addTags && addTags.length > 0) || (removeTags && removeTags.length > 0) || assignee || severity || - transition + transition || + type ); }; @@ -307,6 +331,38 @@ export default class BulkChangeModal extends React.PureComponent { return this.renderField(field, 'issue.assign.formlink', affected, input); }; + renderTypeField = () => { + const affected = this.state.issues.filter(hasAction('set_type')).length; + const field = InputField.type; + + if (affected === 0) { + return null; + } + + const types: IssueType[] = ['BUG', 'VULNERABILITY', 'CODE_SMELL']; + const options: LabelValueSelectOption[] = types.map((type) => ({ + label: translate('issue.type', type), + value: type, + })); + + const input = ( +