Skip to content
代码片段 群组 项目
提交 f404f05c 编辑于 作者: Jose Ivan Vargas's avatar Jose Ivan Vargas
浏览文件

Merge branch 'jnkkl-refactor-code-quality-gutter-icon' into 'master'

Refactor code_quality_gutter_icon component

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/126956



Merged-by: default avatarJose Ivan Vargas <jvargas@gitlab.com>
Approved-by: default avatarLee Tickett <ltickett@gitlab.com>
Approved-by: default avatarJose Ivan Vargas <jvargas@gitlab.com>
Co-authored-by: default avatarJannik Lehmann <jlehmann@gitlab.com>
No related branches found
No related tags found
无相关合并请求
...@@ -24,7 +24,8 @@ import * as utils from './diff_row_utils'; ...@@ -24,7 +24,8 @@ import * as utils from './diff_row_utils';
export default { export default {
DiffGutterAvatars, DiffGutterAvatars,
CodeQualityGutterIcon: () => import('ee_component/diffs/components/code_quality_gutter_icon.vue'), InlineFindingsGutterIcon: () =>
import('ee_component/diffs/components/inline_findings_gutter_icon.vue'),
// Temporary mixin for migration from Vue.js 2 to @vue/compat // Temporary mixin for migration from Vue.js 2 to @vue/compat
mixins: [compatFunctionalMixin], mixins: [compatFunctionalMixin],
...@@ -79,7 +80,7 @@ export default { ...@@ -79,7 +80,7 @@ export default {
type: Function, type: Function,
required: true, required: true,
}, },
codeQualityExpanded: { inlineFindingsExpanded: {
type: Boolean, type: Boolean,
required: false, required: false,
default: false, default: false,
...@@ -336,13 +337,13 @@ export default { ...@@ -336,13 +337,13 @@ export default {
:class="$options.parallelViewLeftLineType(props)" :class="$options.parallelViewLeftLineType(props)"
> >
<component <component
:is="$options.CodeQualityGutterIcon" :is="$options.InlineFindingsGutterIcon"
v-if="$options.showCodequalityLeft(props) || $options.showSecurityLeft(props)" v-if="$options.showCodequalityLeft(props) || $options.showSecurityLeft(props)"
:code-quality-expanded="props.codeQualityExpanded" :inline-findings-expanded="props.inlineFindingsExpanded"
:codequality="props.line.left.codequality" :codequality="props.line.left.codequality"
:sast="props.line.left.sast" :sast="props.line.left.sast"
:file-path="props.filePath" :file-path="props.filePath"
@showCodeQualityFindings=" @showInlineFindings="
listeners.toggleCodeQualityFindings( listeners.toggleCodeQualityFindings(
props.line.left.codequality[0] props.line.left.codequality[0]
? props.line.left.codequality[0].line ? props.line.left.codequality[0].line
...@@ -477,13 +478,13 @@ export default { ...@@ -477,13 +478,13 @@ export default {
:class="$options.classNameMapCellRight(props)" :class="$options.classNameMapCellRight(props)"
> >
<component <component
:is="$options.CodeQualityGutterIcon" :is="$options.InlineFindingsGutterIcon"
v-if="$options.showCodequalityRight(props) || $options.showSecurityRight(props)" v-if="$options.showCodequalityRight(props) || $options.showSecurityRight(props)"
:codequality="props.line.right.codequality" :codequality="props.line.right.codequality"
:sast="props.line.right.sast" :sast="props.line.right.sast"
:file-path="props.filePath" :file-path="props.filePath"
data-testid="codeQualityIcon" data-testid="inlineFindingsIcon"
@showCodeQualityFindings=" @showInlineFindings="
listeners.toggleCodeQualityFindings( listeners.toggleCodeQualityFindings(
props.line.right.codequality[0] props.line.right.codequality[0]
? props.line.right.codequality[0].line ? props.line.right.codequality[0].line
......
...@@ -646,12 +646,12 @@ table.code { ...@@ -646,12 +646,12 @@ table.code {
.diff-comments-more-count, .diff-comments-more-count,
.diff-notes-collapse, .diff-notes-collapse,
.diff-codequality-collapse { .inline-findings-collapse {
@include avatar-counter(50%); @include avatar-counter(50%);
} }
.diff-notes-collapse, .diff-notes-collapse,
.diff-codequality-collapse { .inline-findings-collapse {
border: 0; border: 0;
border-radius: 50%; border-radius: 50%;
padding: 0; padding: 0;
...@@ -735,7 +735,7 @@ table.code { ...@@ -735,7 +735,7 @@ table.code {
} }
.diff-notes-collapse, .diff-notes-collapse,
.diff-codequality-collapse { .inline-findings-collapse {
position: absolute; position: absolute;
left: -12px; left: -12px;
} }
...@@ -845,7 +845,7 @@ table.code { ...@@ -845,7 +845,7 @@ table.code {
} }
.diff-notes-collapse, .diff-notes-collapse,
.diff-codequality-collapse, .inline-findings-collapse,
.note, .note,
.discussion-reply-holder { .discussion-reply-holder {
display: none; display: none;
......
...@@ -6,7 +6,7 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; ...@@ -6,7 +6,7 @@ import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { getSeverity } from '~/ci/reports/utils'; import { getSeverity } from '~/ci/reports/utils';
import { SAST_SCALE_KEY, CODE_QUALITY_SCALE_KEY } from '~/ci/reports/constants'; import { SAST_SCALE_KEY, CODE_QUALITY_SCALE_KEY } from '~/ci/reports/constants';
const codequalityCountThreshold = 3; const inlineFindingsCountThreshold = 3;
export default { export default {
components: { components: {
...@@ -15,7 +15,7 @@ export default { ...@@ -15,7 +15,7 @@ export default {
}, },
mixins: [glFeatureFlagsMixin()], mixins: [glFeatureFlagsMixin()],
props: { props: {
codeQualityExpanded: { inlineFindingsExpanded: {
type: Boolean, type: Boolean,
required: false, required: false,
default: false, default: false,
...@@ -70,18 +70,18 @@ export default { ...@@ -70,18 +70,18 @@ export default {
return this.combinedFindings[0].line; return this.combinedFindings[0].line;
}, },
moreCount() { moreCount() {
return this.combinedFindings.length > codequalityCountThreshold return this.combinedFindings.length > inlineFindingsCountThreshold
? this.combinedFindings.length - codequalityCountThreshold ? this.combinedFindings.length - inlineFindingsCountThreshold
: 0; : 0;
}, },
findingsWithSeverity() { findingsWithSeverity() {
return getSeverity(this.combinedFindings); return getSeverity(this.combinedFindings);
}, },
firstCodequalityItem() { firstItem() {
return { ...this.combinedFindings[0], filePath: this.filePath }; return { ...this.combinedFindings[0], filePath: this.filePath };
}, },
codeQualitySubItems() { inlineFindingsSubItems() {
return this.findingsWithSeverity.slice(1, codequalityCountThreshold); return this.findingsWithSeverity.slice(1, inlineFindingsCountThreshold);
}, },
}, },
}; };
...@@ -91,17 +91,14 @@ export default { ...@@ -91,17 +91,14 @@ export default {
<div <div
v-if="findingsWithSeverity.length" v-if="findingsWithSeverity.length"
class="gl-z-index-1 gl-relative" class="gl-z-index-1 gl-relative"
@click="$emit('showCodeQualityFindings')" @click="$emit('showInlineFindings')"
> >
<div <div v-if="!inlineFindingsExpanded" class="gl-display-inline-flex">
v-if="!codeQualityExpanded" <span ref="inlineFindingsIcon" class="gl-z-index-200">
class="codequality-severity-icon-container gl-display-inline-flex"
>
<span ref="codeQualityIcon" class="gl-z-index-200">
<gl-icon <gl-icon
:id="`codequality-${firstCodequalityItem.filePath}:${firstCodequalityItem.line}`" :id="`inline-findings-${firstItem.filePath}:${firstItem.line}`"
ref="firstCodeQualityIcon" ref="firstInlineFindingsIcon"
:key="firstCodequalityItem.description" :key="firstItem.description"
:size="16" :size="16"
:name="findingsWithSeverity[0].name" :name="findingsWithSeverity[0].name"
:class="findingsWithSeverity[0].class" :class="findingsWithSeverity[0].class"
...@@ -110,7 +107,7 @@ export default { ...@@ -110,7 +107,7 @@ export default {
@mouseleave="isHoveringFirstIcon = false" @mouseleave="isHoveringFirstIcon = false"
/> />
</span> </span>
<span class="code-quality-transition-container gl-display-inline-flex"> <span class="inline-findings-transition-container gl-display-inline-flex">
<transition-group name="icons"> <transition-group name="icons">
<!-- <!--
The TransitionGroup Component will only apply its classes when first-level children are added/removed to the DOM. The TransitionGroup Component will only apply its classes when first-level children are added/removed to the DOM.
...@@ -118,11 +115,11 @@ export default { ...@@ -118,11 +115,11 @@ export default {
--> -->
<!-- eslint-disable vue/no-use-v-if-with-v-for --> <!-- eslint-disable vue/no-use-v-if-with-v-for -->
<gl-icon <gl-icon
v-for="(item, index) in codeQualitySubItems" v-for="(item, index) in inlineFindingsSubItems"
v-if="isHoveringFirstIcon" v-if="isHoveringFirstIcon"
:key="item.description" :key="item.description"
:name="codeQualitySubItems[index].name" :name="inlineFindingsSubItems[index].name"
:class="codeQualitySubItems[index].class" :class="inlineFindingsSubItems[index].class"
class="gl-hover-cursor-pointer gl-relative gl-top-1 inline-findings-severity-icon gl-absolute gl-left-0" class="gl-hover-cursor-pointer gl-relative gl-top-1 inline-findings-severity-icon gl-absolute gl-left-0"
/> />
<!-- eslint-enable --> <!-- eslint-enable -->
...@@ -131,25 +128,21 @@ export default { ...@@ -131,25 +128,21 @@ export default {
<div <div
v-if="showMoreCount" v-if="showMoreCount"
class="more-count gl-px-2 gl-w-auto gl-absolute gl-left-0 gl-relative gl-top-1" class="more-count gl-px-2 gl-w-auto gl-absolute gl-left-0 gl-relative gl-top-1"
data-testid="codeQualityMoreCount" data-testid="inlineFindingsMoreCount"
> >
<p class="gl-mb-0 gl-display-block gl-w-3 more-count-copy">{{ moreCount }}</p> <p class="gl-mb-0 gl-display-block gl-w-3 more-count-copy">{{ moreCount }}</p>
</div> </div>
</transition> </transition>
</span> </span>
</div> </div>
<button v-else class="diff-codequality-collapse gl-mx-n2"> <button v-else class="inline-findings-collapse gl-mx-n2">
<gl-icon :size="12" name="collapse" /> <gl-icon :size="12" name="collapse" />
</button> </button>
<!-- Only show tooltip when indicator is not expanded <!-- Only show tooltip when indicator is not expanded
a) to stay consistent with other collapsed icon on the same page a) to stay consistent with other collapsed icon on the same page
b) because the tooltip would be misaligned hence the negative margin b) because the tooltip would be misaligned hence the negative margin
--> -->
<gl-tooltip <gl-tooltip v-if="!$props.inlineFindingsExpanded" :target="() => $refs.inlineFindingsIcon">
v-if="!$props.codeQualityExpanded"
data-testid="codeQualityTooltip"
:target="() => $refs.codeQualityIcon"
>
<span v-if="codequality.length" class="gl-display-block">{{ <span v-if="codequality.length" class="gl-display-block">{{
codeQualityTooltipTextCollapsed codeQualityTooltipTextCollapsed
}}</span> }}</span>
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
height: $default-icon-size; height: $default-icon-size;
} }
.code-quality-transition-container .inline-findings-severity-icon { .inline-findings-transition-container .inline-findings-severity-icon {
@for $i from 1 through 4 { @for $i from 1 through 4 {
$z-index: 100; $z-index: 100;
$x-pos: 10px; $x-pos: 10px;
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
} }
.code-quality-transition-container { .inline-findings-transition-container {
.more-count-enter, .more-count-enter,
.more-count-leave-to { .more-count-leave-to {
&.more-count { &.more-count {
......
...@@ -9,7 +9,7 @@ Vue.use(Vuex); ...@@ -9,7 +9,7 @@ Vue.use(Vuex);
describe('EE DiffRow', () => { describe('EE DiffRow', () => {
let wrapper; let wrapper;
const findIcon = () => wrapper.find('[data-testid="codeQualityIcon"]'); const findIcon = () => wrapper.find('[data-testid="inlineFindingsIcon"]');
const defaultProps = { const defaultProps = {
fileHash: 'abc', fileHash: 'abc',
......
import { GlIcon, GlTooltip } from '@gitlab/ui'; import { GlIcon, GlTooltip } from '@gitlab/ui';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import CodeQualityGutterIcon from 'ee/diffs/components/code_quality_gutter_icon.vue'; import inlineFindingsGutterIcon from 'ee/diffs/components/inline_findings_gutter_icon.vue';
import store from '~/mr_notes/stores'; import store from '~/mr_notes/stores';
import { SEVERITY_CLASSES, SEVERITY_ICONS } from '~/ci/reports/codequality_report/constants'; import { SEVERITY_CLASSES, SEVERITY_ICONS } from '~/ci/reports/codequality_report/constants';
...@@ -19,7 +19,7 @@ jest.mock('~/mr_notes/stores', () => jest.requireActual('helpers/mocks/mr_notes/ ...@@ -19,7 +19,7 @@ jest.mock('~/mr_notes/stores', () => jest.requireActual('helpers/mocks/mr_notes/
let wrapper; let wrapper;
const findIcon = () => wrapper.findComponent(GlIcon); const findIcon = () => wrapper.findComponent(GlIcon);
const findIcons = () => wrapper.findAllComponents(GlIcon); const findIcons = () => wrapper.findAllComponents(GlIcon);
const findFirstIcon = () => wrapper.findComponent({ ref: 'firstCodeQualityIcon' }); const findFirstIcon = () => wrapper.findComponent({ ref: 'firstInlineFindingsIcon' });
let codequalityDiff; let codequalityDiff;
...@@ -33,10 +33,10 @@ const createComponent = (props = {}) => { ...@@ -33,10 +33,10 @@ const createComponent = (props = {}) => {
$store: store, $store: store,
}, },
}; };
wrapper = shallowMountExtended(CodeQualityGutterIcon, payload); wrapper = shallowMountExtended(inlineFindingsGutterIcon, payload);
}; };
describe('EE CodeQualityGutterIcon', () => { describe('EE inlineFindingsGutterIcon', () => {
const containsATooltip = (container) => container.findComponent(GlTooltip).exists(); const containsATooltip = (container) => container.findComponent(GlTooltip).exists();
it.each` it.each`
...@@ -82,9 +82,9 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -82,9 +82,9 @@ describe('EE CodeQualityGutterIcon', () => {
expect(wrapper.findComponent(GlTooltip).text()).toContain('3 Code Quality findings'); expect(wrapper.findComponent(GlTooltip).text()).toContain('3 Code Quality findings');
}); });
it('emits showCodeQualityFindings event on click', () => { it('emits showInlineFindings event on click', () => {
wrapper.trigger('click'); wrapper.trigger('click');
expect(wrapper.emitted('showCodeQualityFindings')).toHaveLength(1); expect(wrapper.emitted('showInlineFindings')).toHaveLength(1);
}); });
it('displays first icon with correct severity', () => { it('displays first icon with correct severity', () => {
...@@ -104,7 +104,7 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -104,7 +104,7 @@ describe('EE CodeQualityGutterIcon', () => {
}); });
it('does not display more count', () => { it('does not display more count', () => {
expect(wrapper.findByTestId('codeQualityMoreCount').exists()).toBe(false); expect(wrapper.findByTestId('inlineFindingsMoreCount').exists()).toBe(false);
}); });
}); });
...@@ -127,9 +127,9 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -127,9 +127,9 @@ describe('EE CodeQualityGutterIcon', () => {
expect(wrapper.findComponent(GlTooltip).text()).toContain('3 Security findings'); expect(wrapper.findComponent(GlTooltip).text()).toContain('3 Security findings');
}); });
it('emits showCodeQualityFindings event on click', () => { it('emits showInlineFindings event on click', () => {
wrapper.trigger('click'); wrapper.trigger('click');
expect(wrapper.emitted('showCodeQualityFindings')).toHaveLength(1); expect(wrapper.emitted('showInlineFindings')).toHaveLength(1);
}); });
it('displays first icon with correct severity', () => { it('displays first icon with correct severity', () => {
...@@ -149,7 +149,7 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -149,7 +149,7 @@ describe('EE CodeQualityGutterIcon', () => {
}); });
it('does not display more count', () => { it('does not display more count', () => {
expect(wrapper.findByTestId('codeQualityMoreCount').exists()).toBe(false); expect(wrapper.findByTestId('inlineFindingsMoreCount').exists()).toBe(false);
}); });
}); });
...@@ -174,9 +174,9 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -174,9 +174,9 @@ describe('EE CodeQualityGutterIcon', () => {
); );
}); });
it('emits showCodeQualityFindings event on click', () => { it('emits showInlineFindings event on click', () => {
wrapper.trigger('click'); wrapper.trigger('click');
expect(wrapper.emitted('showCodeQualityFindings')).toHaveLength(1); expect(wrapper.emitted('showInlineFindings')).toHaveLength(1);
}); });
it('displays first icon with correct severity', () => { it('displays first icon with correct severity', () => {
...@@ -196,7 +196,7 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -196,7 +196,7 @@ describe('EE CodeQualityGutterIcon', () => {
}); });
it('does not display more count', () => { it('does not display more count', () => {
expect(wrapper.findByTestId('codeQualityMoreCount').exists()).toBe(false); expect(wrapper.findByTestId('inlineFindingsMoreCount').exists()).toBe(false);
}); });
}); });
...@@ -219,7 +219,7 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -219,7 +219,7 @@ describe('EE CodeQualityGutterIcon', () => {
expect(icons.at(0).props('name')).toBe('severity-low'); expect(icons.at(0).props('name')).toBe('severity-low');
expect(icons.at(1).props('name')).toBe('severity-medium'); expect(icons.at(1).props('name')).toBe('severity-medium');
expect(icons.at(2).props('name')).toBe('severity-info'); expect(icons.at(2).props('name')).toBe('severity-info');
expect(wrapper.findByTestId('codeQualityMoreCount').exists()).toBe(true); expect(wrapper.findByTestId('inlineFindingsMoreCount').exists()).toBe(true);
}); });
}); });
...@@ -234,7 +234,7 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -234,7 +234,7 @@ describe('EE CodeQualityGutterIcon', () => {
expect(wrapper.findComponent(GlTooltip).text()).toContain('1 Security finding'); expect(wrapper.findComponent(GlTooltip).text()).toContain('1 Security finding');
}); });
it('does not trigger "first-icon-hovered" class when firstCodeQualityIcon is hovered', async () => { it('does not trigger "first-icon-hovered" class when firstInlineFindingsIcon is hovered', async () => {
createComponent(singularCodeQualityFinding, true); createComponent(singularCodeQualityFinding, true);
findFirstIcon().vm.$emit('mouseenter'); findFirstIcon().vm.$emit('mouseenter');
await nextTick(); await nextTick();
...@@ -243,7 +243,7 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -243,7 +243,7 @@ describe('EE CodeQualityGutterIcon', () => {
}); });
describe('indicator icon', () => { describe('indicator icon', () => {
describe('with codeQualityExpanded prop false', () => { describe('with inlineFindingsExpanded prop false', () => {
beforeEach(() => { beforeEach(() => {
createComponent(singularCodeQualityFinding, true); createComponent(singularCodeQualityFinding, true);
}); });
...@@ -253,9 +253,9 @@ describe('EE CodeQualityGutterIcon', () => { ...@@ -253,9 +253,9 @@ describe('EE CodeQualityGutterIcon', () => {
expect(wrapper.findComponent(GlIcon).props('name')).toBe('severity-low'); expect(wrapper.findComponent(GlIcon).props('name')).toBe('severity-low');
}); });
}); });
describe('with codeQualityExpanded prop true', () => { describe('with inlineFindingsExpanded prop true', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ ...singularCodeQualityFinding, codeQualityExpanded: true }, true); createComponent({ ...singularCodeQualityFinding, inlineFindingsExpanded: true }, true);
}); });
it('shows collapse icon', () => { it('shows collapse icon', () => {
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册