Commit 1d48e365 authored by Scott Hampton's avatar Scott Hampton

Merge branch '267612-make-code-quality-mr-diff-badge-a-link' into 'master'

Make code quality badge in MR diff a link to a modal with the details of the code quality issues for that file

See merge request gitlab-org/gitlab!57791
parents 4fbf3bc3 b1f07433
......@@ -148,10 +148,8 @@ export default {
return loggedIn && featureOn;
},
hasCodequalityChanges() {
return (
this.codequalityDiff?.files && this.codequalityDiff?.files[this.file.file_path]?.length > 0
);
codequalityDiffForFile() {
return this.codequalityDiff?.files?.[this.file.file_path] || [];
},
},
watch: {
......@@ -299,7 +297,7 @@ export default {
:add-merge-request-buttons="true"
:view-diffs-file-by-file="viewDiffsFileByFile"
:show-local-file-reviews="showLocalFileReviews"
:has-codequality-changes="hasCodequalityChanges"
:codequality-diff="codequalityDiffForFile"
class="js-file-title file-title gl-border-1 gl-border-solid gl-border-gray-100"
:class="hasBodyClasses.header"
@toggleFile="handleToggle"
......
......@@ -96,10 +96,10 @@ export default {
required: false,
default: false,
},
hasCodequalityChanges: {
type: Boolean,
codequalityDiff: {
type: Array,
required: false,
default: false,
default: () => [],
},
},
data() {
......@@ -333,7 +333,12 @@ export default {
data-track-property="diff_copy_file"
/>
<code-quality-badge v-if="hasCodequalityChanges" class="gl-mr-2" />
<code-quality-badge
v-if="codequalityDiff.length"
:file-name="filePath"
:codequality-diff="codequalityDiff"
class="gl-mr-2"
/>
<small v-if="isModeChanged" ref="fileMode" class="mr-1">
{{ diffFile.a_mode }}{{ diffFile.b_mode }}
......
......@@ -6,7 +6,7 @@
import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { s__ } from '~/locale';
import ReportLink from '~/reports/components/report_link.vue';
import { STATUS_SUCCESS } from '~/reports/constants';
import { STATUS_SUCCESS, STATUS_NEUTRAL } from '~/reports/constants';
import { SEVERITY_CLASSES, SEVERITY_ICONS } from '../constants';
export default {
......@@ -21,7 +21,8 @@ export default {
props: {
status: {
type: String,
required: true,
required: false,
default: STATUS_NEUTRAL,
},
issue: {
type: Object,
......
<script>
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
import { __ } from '~/locale';
import { GlBadge, GlTooltipDirective, GlModalDirective, GlModal } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import CodequalityIssueBody from '~/reports/codequality_report/components/codequality_issue_body.vue';
export default {
components: {
CodequalityIssueBody,
GlBadge,
GlModal,
},
directives: {
GlTooltip: GlTooltipDirective,
GlModal: GlModalDirective,
},
i18n: {
badgeTitle: __('Code Quality'),
badgeTooltip: __(
'The merge request has made changes to this file that affect the number of code quality violations in it.',
),
badgeTitle: s__('CodeQuality|Code quality'),
badgeTooltip: s__('CodeQuality|Some changes in this file degrade the code quality.'),
modalTitle: s__('CodeQuality|New code quality degradations in this file'),
},
modalCloseButton: {
text: __('Close'),
attributes: [{ variant: 'info' }],
},
props: {
fileName: {
type: String,
required: true,
},
codequalityDiff: {
type: Array,
required: false,
default: () => [],
},
},
computed: {
degradations() {
return this.codequalityDiff.map((degradation) => {
return {
name: degradation.description,
path: this.fileName,
severity: degradation.severity,
};
});
},
},
};
</script>
<template>
<gl-badge
v-gl-tooltip
:title="$options.i18n.badgeTooltip"
icon="information"
class="gl-display-inline-block"
>
{{ $options.i18n.badgeTitle }}
</gl-badge>
<span>
<gl-badge
v-gl-modal="`codequality-details-${fileName}`"
v-gl-tooltip
:title="$options.i18n.badgeTooltip"
class="gl-display-inline-block"
icon="information"
href="#"
>
{{ $options.i18n.badgeTitle }}
</gl-badge>
<gl-modal
:modal-id="`codequality-details-${fileName}`"
:title="$options.i18n.modalTitle"
:action-primary="$options.modalCloseButton"
>
<codequality-issue-body
v-for="(degradation, index) in degradations"
:key="index"
:issue="degradation"
/>
</gl-modal>
</span>
</template>
import { GlBadge } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import CodeQualityBadge from 'ee/diffs/components/code_quality_badge.vue';
import CodequalityIssueBody from '~/reports/codequality_report/components/codequality_issue_body.vue';
describe('EE CodeQualityBadge', () => {
let wrapper;
const props = {
fileName: 'index.js',
codequalityDiff: [
{
severity: 'major',
description:
'Function `aVeryLongFunction` has 52 lines of code (exceeds 25 allowed). Consider refactoring.',
},
{
severity: 'minor',
description: 'Arrow function has too many statements (52). Maximum allowed is 30.',
},
],
};
beforeEach(() => {
wrapper = shallowMount(CodeQualityBadge, {
propsData: props,
});
});
afterEach(() => {
wrapper.destroy();
});
it('opens a code quality details modal on click', () => {
const modalId = 'codequality-details-index.js';
const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
wrapper.findComponent(GlBadge).trigger('click');
expect(rootEmit.mock.calls[0]).toContainEqual(modalId);
});
it('passes the issue data into the issue components correctly', () => {
const issueProps = wrapper
.findAllComponents(CodequalityIssueBody)
.wrappers.map((w) => w.props());
expect(issueProps).toEqual([
{
issue: {
path: props.fileName,
severity: props.codequalityDiff[0].severity,
name: props.codequalityDiff[0].description,
},
status: 'neutral',
},
{
issue: {
path: props.fileName,
severity: props.codequalityDiff[1].severity,
name: props.codequalityDiff[1].description,
},
status: 'neutral',
},
]);
});
});
......@@ -7913,6 +7913,15 @@ msgstr ""
msgid "CodeOwner|Pattern"
msgstr ""
msgid "CodeQuality|Code quality"
msgstr ""
msgid "CodeQuality|New code quality degradations in this file"
msgstr ""
msgid "CodeQuality|Some changes in this file degrade the code quality."
msgstr ""
msgid "Cohorts|Inactive users"
msgstr ""
......@@ -31991,9 +32000,6 @@ msgstr ""
msgid "The merge request can now be merged."
msgstr ""
msgid "The merge request has made changes to this file that affect the number of code quality violations in it."
msgstr ""
msgid "The metric must be one of %{metrics}."
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment