Commit 2e09691a authored by Olena Horal-Koretska's avatar Olena Horal-Koretska

Merge branch '299357-add-path-info-to-compliance-dashboard-drawer' into 'master'

Add reference and path sections to the drawer

See merge request gitlab-org/gitlab!65143
parents 72f4c57f a04788c5
<script> <script>
import { GlDrawer } from '@gitlab/ui'; import { GlDrawer } from '@gitlab/ui';
import BranchPath from './drawer_sections/branch_path.vue';
import Project from './drawer_sections/project.vue'; import Project from './drawer_sections/project.vue';
import Reference from './drawer_sections/reference.vue';
export default { export default {
components: { components: {
GlDrawer, GlDrawer,
BranchPath,
Reference,
Project, Project,
}, },
props: { props: {
...@@ -18,6 +22,11 @@ export default { ...@@ -18,6 +22,11 @@ export default {
default: false, default: false,
}, },
}, },
computed: {
hasBranchDetails() {
return this.mergeRequest.source_branch && this.mergeRequest.target_branch;
},
},
methods: { methods: {
getDrawerHeaderHeight() { getDrawerHeaderHeight() {
const wrapperEl = document.querySelector('.content-wrapper'); const wrapperEl = document.querySelector('.content-wrapper');
...@@ -51,6 +60,14 @@ export default { ...@@ -51,6 +60,14 @@ export default {
:name="mergeRequest.project.name" :name="mergeRequest.project.name"
:url="mergeRequest.project.web_url" :url="mergeRequest.project.web_url"
/> />
<reference :path="mergeRequest.path" :reference="mergeRequest.reference" />
<branch-path
v-if="hasBranchDetails"
:source-branch="mergeRequest.source_branch"
:source-branch-uri="mergeRequest.source_branch_uri"
:target-branch="mergeRequest.target_branch"
:target-branch-uri="mergeRequest.target_branch_uri"
/>
</template> </template>
</gl-drawer> </gl-drawer>
</template> </template>
<script>
import { __ } from '~/locale';
import BranchDetails from '../shared/branch_details.vue';
import DrawerSectionHeader from '../shared/drawer_section_header.vue';
export default {
components: {
BranchDetails,
DrawerSectionHeader,
},
props: {
sourceBranch: {
type: String,
required: false,
default: '',
},
sourceBranchUri: {
type: String,
required: false,
default: '',
},
targetBranch: {
type: String,
required: false,
default: '',
},
targetBranchUri: {
type: String,
required: false,
default: '',
},
},
i18n: {
header: __('Path'),
},
};
</script>
<template>
<div>
<drawer-section-header>{{ $options.i18n.header }}</drawer-section-header>
<branch-details
class="gl-justify-content-start gl-text-gray-500"
:source-branch="{
name: sourceBranch,
uri: sourceBranchUri,
}"
:target-branch="{
name: targetBranch,
uri: targetBranchUri,
}"
/>
</div>
</template>
<script>
import { GlLink } from '@gitlab/ui';
import { __ } from '~/locale';
import DrawerSectionHeader from '../shared/drawer_section_header.vue';
export default {
components: {
DrawerSectionHeader,
GlLink,
},
props: {
path: {
type: String,
required: true,
},
reference: {
type: String,
required: true,
},
},
i18n: {
header: __('Merge request'),
},
};
</script>
<template>
<div>
<drawer-section-header>{{ $options.i18n.header }}</drawer-section-header>
<gl-link :href="path">{{ reference }}</gl-link>
</div>
</template>
...@@ -4,10 +4,10 @@ import { GlSprintf } from '@gitlab/ui'; ...@@ -4,10 +4,10 @@ import { GlSprintf } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import BranchDetails from '../shared/branch_details.vue';
import GridColumnHeading from '../shared/grid_column_heading.vue'; import GridColumnHeading from '../shared/grid_column_heading.vue';
import Pagination from '../shared/pagination.vue'; import Pagination from '../shared/pagination.vue';
import Approvers from './approvers.vue'; import Approvers from './approvers.vue';
import BranchDetails from './branch_details.vue';
import MergeRequest from './merge_request.vue'; import MergeRequest from './merge_request.vue';
import Status from './status.vue'; import Status from './status.vue';
...@@ -101,6 +101,7 @@ export default { ...@@ -101,6 +101,7 @@ export default {
<approvers :approvers="mergeRequest.approved_by_users" /> <approvers :approvers="mergeRequest.approved_by_users" />
<branch-details <branch-details
v-if="hasBranchDetails(mergeRequest)" v-if="hasBranchDetails(mergeRequest)"
class="gl-justify-content-end gl-text-gray-900"
:source-branch="{ :source-branch="{
name: mergeRequest.source_branch, name: mergeRequest.source_branch,
uri: mergeRequest.source_branch_uri, uri: mergeRequest.source_branch_uri,
...@@ -148,6 +149,7 @@ export default { ...@@ -148,6 +149,7 @@ export default {
<approvers :approvers="mergeRequest.approved_by_users" /> <approvers :approvers="mergeRequest.approved_by_users" />
<branch-details <branch-details
v-if="hasBranchDetails(mergeRequest)" v-if="hasBranchDetails(mergeRequest)"
class="gl-justify-content-end gl-text-gray-900"
:source-branch="{ :source-branch="{
name: mergeRequest.source_branch, name: mergeRequest.source_branch,
uri: mergeRequest.source_branch_uri, uri: mergeRequest.source_branch_uri,
......
...@@ -29,7 +29,7 @@ export default { ...@@ -29,7 +29,7 @@ export default {
</script> </script>
<template> <template>
<div class="gl-display-flex gl-align-items-center gl-justify-content-end gl-text-gray-900"> <div class="gl-display-flex gl-align-items-center">
<gl-sprintf :message="this.$options.strings.branchDetails"> <gl-sprintf :message="this.$options.strings.branchDetails">
<template #sourceBranch> <template #sourceBranch>
<span class="gl-mr-2 gl-min-w-0"> <span class="gl-mr-2 gl-min-w-0">
......
...@@ -20,6 +20,10 @@ class MergeRequestComplianceEntity < Grape::Entity ...@@ -20,6 +20,10 @@ class MergeRequestComplianceEntity < Grape::Entity
merge_request.to_reference(merge_request.project.group) merge_request.to_reference(merge_request.project.group)
end end
expose :reference do |merge_request|
merge_request.to_reference
end
expose :project do |merge_request| expose :project do |merge_request|
{ {
avatar_url: merge_request.project.avatar_url, avatar_url: merge_request.project.avatar_url,
......
import { shallowMount } from '@vue/test-utils';
import BranchPath from 'ee/compliance_dashboard/components/drawer_sections/branch_path.vue';
import BranchDetails from 'ee/compliance_dashboard/components/shared/branch_details.vue';
import DrawerSectionHeader from 'ee/compliance_dashboard/components/shared/drawer_section_header.vue';
describe('BranchPath component', () => {
let wrapper;
const sourceBranch = 'feature-branch';
const sourceBranchUri = '/project/feature-branch';
const targetBranch = 'main';
const targetBranchUri = '/project/main';
const findSectionHeader = () => wrapper.findComponent(DrawerSectionHeader);
const findBranchDetails = () => wrapper.findComponent(BranchDetails);
const createComponent = () => {
return shallowMount(BranchPath, {
propsData: { sourceBranch, sourceBranchUri, targetBranch, targetBranchUri },
});
};
beforeEach(() => {
wrapper = createComponent();
});
afterEach(() => {
wrapper.destroy();
});
describe('rendering', () => {
it('renders the header', () => {
expect(findSectionHeader().text()).toBe('Path');
});
it('renders the branch details', () => {
expect(findBranchDetails().props()).toStrictEqual({
sourceBranch: { name: sourceBranch, uri: sourceBranchUri },
targetBranch: { name: targetBranch, uri: targetBranchUri },
});
});
});
});
import { GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Reference from 'ee/compliance_dashboard/components/drawer_sections/reference.vue';
import DrawerSectionHeader from 'ee/compliance_dashboard/components/shared/drawer_section_header.vue';
describe('Reference component', () => {
let wrapper;
const path = '/path/to/merge_request';
const reference = '!12345';
const findSectionHeader = () => wrapper.findComponent(DrawerSectionHeader);
const findLink = () => wrapper.findComponent(GlLink);
const createComponent = () => {
return shallowMount(Reference, {
propsData: { path, reference },
});
};
afterEach(() => {
wrapper.destroy();
});
describe('rendering', () => {
beforeEach(() => {
wrapper = createComponent();
});
it('renders the header', () => {
expect(findSectionHeader().text()).toBe('Merge request');
});
it('renders the link', () => {
expect(findLink().attributes('href')).toBe(path);
expect(findLink().text()).toBe(reference);
});
});
});
import { GlDrawer } from '@gitlab/ui'; import { GlDrawer } from '@gitlab/ui';
import MergeRequestDrawer from 'ee/compliance_dashboard/components/drawer.vue'; import MergeRequestDrawer from 'ee/compliance_dashboard/components/drawer.vue';
import BranchPath from 'ee/compliance_dashboard/components/drawer_sections/branch_path.vue';
import Project from 'ee/compliance_dashboard/components/drawer_sections/project.vue'; import Project from 'ee/compliance_dashboard/components/drawer_sections/project.vue';
import Reference from 'ee/compliance_dashboard/components/drawer_sections/reference.vue';
import { complianceFramework } from 'ee_jest/vue_shared/components/compliance_framework_label/mock_data'; import { complianceFramework } from 'ee_jest/vue_shared/components/compliance_framework_label/mock_data';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMergeRequests } from '../mock_data'; import { createMergeRequests } from '../mock_data';
...@@ -17,6 +19,8 @@ describe('MergeRequestDrawer component', () => { ...@@ -17,6 +19,8 @@ describe('MergeRequestDrawer component', () => {
const findTitle = () => wrapper.findByTestId('dashboard-drawer-title'); const findTitle = () => wrapper.findByTestId('dashboard-drawer-title');
const findDrawer = () => wrapper.findComponent(GlDrawer); const findDrawer = () => wrapper.findComponent(GlDrawer);
const findProject = () => wrapper.findComponent(Project); const findProject = () => wrapper.findComponent(Project);
const findReference = () => wrapper.findComponent(Reference);
const findBranchPath = () => wrapper.findComponent(BranchPath);
const createComponent = (props) => { const createComponent = (props) => {
return shallowMountExtended(MergeRequestDrawer, { return shallowMountExtended(MergeRequestDrawer, {
...@@ -66,5 +70,41 @@ describe('MergeRequestDrawer component', () => { ...@@ -66,5 +70,41 @@ describe('MergeRequestDrawer component', () => {
url: mergeRequest.project.web_url, url: mergeRequest.project.web_url,
}); });
}); });
it('has the reference section', () => {
expect(findReference().props()).toStrictEqual({
path: mergeRequest.path,
reference: mergeRequest.reference,
});
});
});
describe('when the branch details are given', () => {
const sourceBranch = 'feature-branch';
const sourceBranchUri = '/project/feature-branch';
const targetBranch = 'main';
const targetBranchUri = '/project/main';
beforeEach(() => {
wrapper = createComponent({
showDrawer: true,
mergeRequest: {
...mergeRequest,
source_branch: sourceBranch,
source_branch_uri: sourceBranchUri,
target_branch: targetBranch,
target_branch_uri: targetBranchUri,
},
});
});
it('has the branch path section', () => {
expect(findBranchPath().props()).toStrictEqual({
sourceBranch,
sourceBranchUri,
targetBranch,
targetBranchUri,
});
});
}); });
}); });
...@@ -19,7 +19,7 @@ exports[`MergeRequest component when there is a merge request matches the snapsh ...@@ -19,7 +19,7 @@ exports[`MergeRequest component when there is a merge request matches the snapsh
<span <span
class="gl-text-gray-500" class="gl-text-gray-500"
> >
!1 project!1
</span> </span>
<span <span
......
import Approvers from 'ee/compliance_dashboard/components/merge_requests/approvers.vue'; import Approvers from 'ee/compliance_dashboard/components/merge_requests/approvers.vue';
import BranchDetails from 'ee/compliance_dashboard/components/merge_requests/branch_details.vue';
import MergeRequestsGrid from 'ee/compliance_dashboard/components/merge_requests/grid.vue'; import MergeRequestsGrid from 'ee/compliance_dashboard/components/merge_requests/grid.vue';
import Status from 'ee/compliance_dashboard/components/merge_requests/status.vue'; import Status from 'ee/compliance_dashboard/components/merge_requests/status.vue';
import BranchDetails from 'ee/compliance_dashboard/components/shared/branch_details.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { createMergeRequests, mergedAt } from '../../mock_data'; import { createMergeRequests, mergedAt } from '../../mock_data';
......
import { GlLink } from '@gitlab/ui'; import { GlLink } from '@gitlab/ui';
import { mount } from '@vue/test-utils'; import BranchDetails from 'ee/compliance_dashboard/components/shared/branch_details.vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import BranchDetails from 'ee/compliance_dashboard/components/merge_requests/branch_details.vue';
describe('BranchDetails component', () => { describe('BranchDetails component', () => {
let wrapper; let wrapper;
// The truncate component adds left-to-right marks into the text that we have to remove // The truncate component adds left-to-right marks into the text that we have to remove
const getText = () => wrapper.text().replace(/\u200E/gi, ''); const getText = () => wrapper.text().replace(/\u200E/gi, '');
const linkExists = (testId) => wrapper.find(`[data-testid="${testId}"]`).exists(); const linkExists = (testId) => wrapper.findByTestId(testId).exists();
const createComponent = ({ sourceUri = '', targetUri = '' } = {}) => { const createComponent = ({ sourceUri = '', targetUri = '' } = {}) => {
return mount(BranchDetails, { return mountExtended(BranchDetails, {
propsData: { propsData: {
sourceBranch: { sourceBranch: {
name: 'feature', name: 'feature',
......
...@@ -32,7 +32,8 @@ export const createMergeRequest = ({ id = 1, props } = {}) => { ...@@ -32,7 +32,8 @@ export const createMergeRequest = ({ id = 1, props } = {}) => {
const mergeRequest = { const mergeRequest = {
id, id,
approved_by_users: [], approved_by_users: [],
issuable_reference: '!1', issuable_reference: 'project!1',
reference: '!1',
merged_at: mergedAt(), merged_at: mergedAt(),
milestone: null, milestone: null,
path: `/h5bp/html5-boilerplate/-/merge_requests/${id}`, path: `/h5bp/html5-boilerplate/-/merge_requests/${id}`,
......
...@@ -23,6 +23,7 @@ RSpec.describe MergeRequestComplianceEntity do ...@@ -23,6 +23,7 @@ RSpec.describe MergeRequestComplianceEntity do
:milestone, :milestone,
:path, :path,
:issuable_reference, :issuable_reference,
:reference,
:author, :author,
:approved_by_users, :approved_by_users,
:approval_status, :approval_status,
......
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