Commit 2fcca0f5 authored by Miranda Fluharty's avatar Miranda Fluharty Committed by Scott Hampton

UX improvements for inline code quality

Apply gl-stroke-white class to code quality gutter icons
Clicking on a code quality gutter icon opens a modal with more details
parent 5c83b952
......@@ -288,6 +288,7 @@ export default {
<div class="diff-td line-codequality left-side" :class="[...parallelViewLeftLineType]">
<code-quality-gutter-icon
v-if="showCodequalityLeft"
:file-path="filePath"
:codequality="line.left.codequality"
/>
</div>
......@@ -403,6 +404,7 @@ export default {
>
<code-quality-gutter-icon
v-if="showCodequalityRight"
:file-path="filePath"
:codequality="line.right.codequality"
/>
</div>
......
<script>
import { GlTooltipDirective, GlIcon } from '@gitlab/ui';
import { GlTooltipDirective, GlIcon, GlModalDirective, GlModal } from '@gitlab/ui';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import { __, s__, sprintf } from '~/locale';
import CodequalityIssueBody from '~/reports/codequality_report/components/codequality_issue_body.vue';
import { SEVERITY_CLASSES, SEVERITY_ICONS } from '~/reports/codequality_report/constants';
const i18n = {
tooltip: s__('CodeQuality|Code quality: %{severity} - %{description}'),
};
export default {
components: {
GlIcon,
GlModal,
CodequalityIssueBody,
},
directives: {
GlTooltip: GlTooltipDirective,
GlModal: GlModalDirective,
},
modalCloseButton: {
text: __('Close'),
attributes: [{ variant: 'info' }],
},
i18n: {
modalTitle: s__('CodeQuality|New code quality degradations on this line'),
},
props: {
filePath: {
type: String,
required: true,
},
codequality: {
type: Array,
required: false,
......@@ -17,8 +38,11 @@ export default {
},
},
computed: {
description() {
return this.codequality[0].description;
tooltipText() {
return sprintf(i18n.tooltip, {
severity: capitalizeFirstCharacter(this.severity),
description: this.codequality[0].description,
});
},
severity() {
return this.codequality[0].severity;
......@@ -29,12 +53,44 @@ export default {
severityIcon() {
return SEVERITY_ICONS[this.severity] || SEVERITY_ICONS.unknown;
},
line() {
return this.codequality[0].line;
},
degradations() {
return this.codequality.map((degradation) => {
return {
name: degradation.description,
severity: degradation.severity,
path: this.filePath,
line: this.line,
};
});
},
},
};
</script>
<template>
<div v-gl-tooltip.hover :title="description">
<gl-icon :size="12" :name="severityIcon" :class="severityClass" />
<div>
<gl-icon
v-gl-modal="`codequality-${filePath}:${line}`"
v-gl-tooltip.hover
:title="tooltipText"
:size="12"
:name="severityIcon"
:class="severityClass"
class="gl-hover-cursor-pointer codequality-severity-icon"
/>
<gl-modal
:modal-id="`codequality-${filePath}:${line}`"
:title="$options.i18n.modalTitle"
:action-primary="$options.modalCloseButton"
>
<codequality-issue-body
v-for="(degradation, index) in degradations"
:key="index"
:issue="degradation"
/>
</gl-modal>
</div>
</template>
......@@ -11,4 +11,8 @@
grid-template-columns: 50px 50px 8px 20px 1fr;
}
}
.codequality-severity-icon {
filter: drop-shadow(0 1px 0.5px #fff) drop-shadow(1px 0 0.5px #fff) drop-shadow(0 -1px 0.5px #fff) drop-shadow(-1px 0 0.5px #fff);
}
}
......@@ -4,6 +4,7 @@ import Vue from 'vue';
import Vuex from 'vuex';
import CodeQualityGutterIcon from 'ee/diffs/components/code_quality_gutter_icon.vue';
import createDiffsStore from 'jest/diffs/create_diffs_store';
import CodequalityIssueBody from '~/reports/codequality_report/components/codequality_issue_body.vue';
import { SEVERITY_CLASSES, SEVERITY_ICONS } from '~/reports/codequality_report/constants';
Vue.use(Vuex);
......@@ -15,6 +16,23 @@ describe('EE CodeQualityGutterIcon', () => {
const findIcon = () => wrapper.findComponent(GlIcon);
const defaultProps = {
filePath: 'index.js',
codequality: [
{
severity: 'major',
description:
'Function `aVeryLongFunction` has 52 lines of code (exceeds 25 allowed). Consider refactoring.',
line: 3,
},
{
severity: 'minor',
description: 'Arrow function has too many statements (52). Maximum allowed is 30.',
line: 3,
},
],
};
const createComponent = (props = {}, extendStore = () => {}) => {
store = createDiffsStore();
store.state.diffs.codequalityDiff = codequalityDiff;
......@@ -22,7 +40,7 @@ describe('EE CodeQualityGutterIcon', () => {
extendStore(store);
wrapper = shallowMount(CodeQualityGutterIcon, {
propsData: { ...props },
propsData: { ...defaultProps, ...props },
store,
});
};
......@@ -43,10 +61,51 @@ describe('EE CodeQualityGutterIcon', () => {
createComponent({ codequality: [{ severity }] });
expect(findIcon().exists()).toBe(true);
expect(findIcon().attributes()).toEqual({
class: SEVERITY_CLASSES[severity],
expect(findIcon().attributes()).toMatchObject({
class: `gl-hover-cursor-pointer codequality-severity-icon ${SEVERITY_CLASSES[severity]}`,
name: SEVERITY_ICONS[severity],
size: '12',
});
});
describe('code quality modal', () => {
beforeEach(() => {
createComponent();
});
it('opens a code quality modal on click', () => {
const modalId = 'codequality-index.js:3';
const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit');
wrapper.findComponent(GlIcon).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: defaultProps.filePath,
severity: defaultProps.codequality[0].severity,
name: defaultProps.codequality[0].description,
line: defaultProps.codequality[0].line,
},
status: 'neutral',
},
{
issue: {
path: defaultProps.filePath,
severity: defaultProps.codequality[1].severity,
name: defaultProps.codequality[1].description,
line: defaultProps.codequality[1].line,
},
status: 'neutral',
},
]);
});
});
});
......@@ -7948,9 +7948,15 @@ msgstr ""
msgid "CodeQuality|Code quality"
msgstr ""
msgid "CodeQuality|Code quality: %{severity} - %{description}"
msgstr ""
msgid "CodeQuality|New code quality degradations in this file"
msgstr ""
msgid "CodeQuality|New code quality degradations on this line"
msgstr ""
msgid "CodeQuality|Some changes in this file degrade the code quality."
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