Skip to content
代码片段 群组 项目
未验证 提交 14855c11 编辑于 作者: Justin Ho Tuan Duong's avatar Justin Ho Tuan Duong 提交者: GitLab
浏览文件

Add "Imported" badge to MR header

This is not shown at the moment as the backend is not providing
any data.

Changelog: changed
上级 711cc243
No related branches found
No related tags found
无相关合并请求
......@@ -8,6 +8,7 @@ import StatusBadge from '~/issuable/components/status_badge.vue';
import { TYPE_ISSUE, TYPE_MERGE_REQUEST, WORKSPACE_PROJECT } from '~/issues/constants';
import { fetchPolicies } from '~/lib/graphql';
import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue';
import ImportedBadge from '~/vue_shared/components/imported_badge.vue';
export const badgeState = Vue.observable({
state: '',
......@@ -22,6 +23,7 @@ export default {
ConfidentialityBadge,
LockedBadge,
HiddenBadge,
ImportedBadge,
StatusBadge,
},
inject: {
......@@ -36,6 +38,11 @@ export default {
required: false,
default: null,
},
isImported: {
type: Boolean,
required: false,
default: false,
},
},
data() {
if (!this.iid) {
......@@ -109,5 +116,10 @@ export default {
class="gl-align-self-center gl-mr-2"
:issuable-type="$options.TYPE_MERGE_REQUEST"
/>
<imported-badge
v-if="isImported"
class="gl-align-self-center gl-mr-2"
:importable-type="$options.TYPE_MERGE_REQUEST"
/>
</span>
</template>
......@@ -18,6 +18,7 @@ import { convertToGraphQLId } from '~/graphql_shared/utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { isLoggedIn } from '~/lib/utils/common_utils';
import StatusBadge from '~/issuable/components/status_badge.vue';
import ImportedBadge from '~/vue_shared/components/imported_badge.vue';
import { TYPE_MERGE_REQUEST } from '~/issues/constants';
import DiscussionCounter from '~/notes/components/discussion_counter.vue';
import TodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
......@@ -58,6 +59,7 @@ export default {
GlIcon,
DiscussionCounter,
StatusBadge,
ImportedBadge,
TodoWidget,
SubscriptionsWidget,
ClipboardButton,
......@@ -75,6 +77,11 @@ export default {
blocksMerge: { default: false },
},
props: {
isImported: {
type: Boolean,
required: false,
default: false,
},
tabs: {
type: Array,
required: true,
......@@ -160,18 +167,15 @@ export default {
class="issue-sticky-header-text gl-display-flex gl-flex-direction-column gl-align-items-center gl-mx-auto gl-w-full"
:class="{ 'container-limited': !isFluidLayout }"
>
<div class="gl-w-full gl-display-flex gl-align-items-baseline">
<status-badge
class="gl-align-self-center gl-mr-3"
:issuable-type="$options.TYPE_MERGE_REQUEST"
:state="badgeState.state"
/>
<div class="gl-w-full gl-display-flex gl-align-items-center gl-gap-2">
<status-badge :issuable-type="$options.TYPE_MERGE_REQUEST" :state="badgeState.state" />
<imported-badge v-if="isImported" :importable-type="$options.TYPE_MERGE_REQUEST" />
<a
v-safe-html:[$options.safeHtmlConfig]="titleHtml"
href="#top"
class="gl-display-none gl-lg-display-block gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0 gl-mr-4 gl-text-black-normal"
class="gl-display-none gl-lg-display-block gl-font-weight-bold gl-overflow-hidden gl-white-space-nowrap gl-text-overflow-ellipsis gl-my-0 gl-ml-1 gl-mr-2 gl-text-black-normal"
></a>
<div class="gl-display-flex gl-align-items-baseline">
<div class="gl-display-flex gl-align-items-center">
<gl-sprintf :message="__('%{source} %{copyButton} into %{target}')">
<template #copyButton>
<clipboard-button
......
......@@ -27,7 +27,7 @@ export default function initMergeRequestShow(store) {
initCheckoutModal();
const el = document.querySelector('.js-mr-header');
const { hidden, iid, projectPath, state } = el.dataset;
const { hidden, imported, iid, projectPath, state } = el.dataset;
// eslint-disable-next-line no-new
new Vue({
......@@ -47,6 +47,7 @@ export default function initMergeRequestShow(store) {
return createElement(MergeRequestHeader, {
props: {
initialState: state,
isImported: parseBoolean(imported),
},
});
},
......
......@@ -51,6 +51,7 @@ requestIdleCallback(() => {
isFluidLayout,
sourceProjectPath,
blocksMerge,
imported,
} = JSON.parse(data);
tabData.tabs = tabs;
......@@ -58,6 +59,7 @@ requestIdleCallback(() => {
// eslint-disable-next-line no-new
new Vue({
el,
name: 'MergeRequestStickyHeaderRoot',
store,
apolloProvider,
provide: {
......@@ -73,6 +75,7 @@ requestIdleCallback(() => {
return h(StickyHeader, {
props: {
tabs: tabData.tabs,
isImported: parseBoolean(imported),
},
});
},
......
......@@ -5,6 +5,7 @@ import StatusBadge from '~/issuable/components/status_badge.vue';
import MergeRequestHeader from '~/merge_requests/components/merge_request_header.vue';
import mrStore from '~/mr_notes/stores';
import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue';
import ImportedBadge from '~/vue_shared/components/imported_badge.vue';
jest.mock('~/mr_notes/stores', () => jest.requireActual('helpers/mocks/mr_notes/stores'));
......@@ -14,11 +15,12 @@ describe('MergeRequestHeader component', () => {
const findConfidentialBadge = () => wrapper.findComponent(ConfidentialityBadge);
const findLockedBadge = () => wrapper.findComponent(LockedBadge);
const findHiddenBadge = () => wrapper.findComponent(HiddenBadge);
const findImportedBadge = () => wrapper.findComponent(ImportedBadge);
const findStatusBadge = () => wrapper.findComponent(StatusBadge);
const renderTestMessage = (renders) => (renders ? 'renders' : 'does not render');
const createComponent = ({ confidential, hidden, locked }) => {
const createComponent = ({ confidential, hidden, locked, isImported = false }) => {
const store = mrStore;
store.getters.getNoteableData = {};
store.getters.getNoteableData.confidential = confidential;
......@@ -34,6 +36,7 @@ describe('MergeRequestHeader component', () => {
},
propsData: {
initialState: 'opened',
isImported,
},
});
};
......@@ -85,4 +88,18 @@ describe('MergeRequestHeader component', () => {
});
},
);
describe('imported badge', () => {
it('renders when merge request is imported', () => {
createComponent({ isImported: true });
expect(findImportedBadge().props('importableType')).toBe('merge_request');
});
it('does not render when merge request is not imported', () => {
createComponent({ isImported: false });
expect(findImportedBadge().exists()).toBe(false);
});
});
});
......@@ -4,45 +4,72 @@ import Vuex from 'vuex';
import { GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import StickyHeader from '~/merge_requests/components/sticky_header.vue';
import ImportedBadge from '~/vue_shared/components/imported_badge.vue';
Vue.use(Vuex);
let wrapper;
function createComponent(provide = {}) {
const store = new Vuex.Store({
state: {
page: { activeTab: 'overview' },
notes: { notes: { doneFetchingBatchDiscussions: true } },
},
getters: {
getNoteableData: () => ({
id: 1,
source_branch: 'source-branch',
target_branch: 'main',
}),
discussionTabCounter: () => 1,
},
});
describe('Merge requests sticky header component', () => {
let wrapper;
wrapper = shallowMountExtended(StickyHeader, {
store,
provide,
stubs: {
GlSprintf,
},
});
}
const createComponent = ({ provide = {}, props = {} } = {}) => {
const store = new Vuex.Store({
state: {
page: { activeTab: 'overview' },
notes: { notes: { doneFetchingBatchDiscussions: true } },
},
getters: {
getNoteableData: () => ({
id: 1,
source_branch: 'source-branch',
target_branch: 'main',
}),
discussionTabCounter: () => 1,
},
});
wrapper = shallowMountExtended(StickyHeader, {
store,
provide,
propsData: {
tabs: [],
...props,
},
stubs: {
GlSprintf,
},
});
};
const findImportedBadge = () => wrapper.findComponent(ImportedBadge);
describe('Merge requests sticky header component', () => {
describe('forked project', () => {
it('renders source branch with source project path', () => {
createComponent({
projectPath: 'gitlab-org/gitlab',
sourceProjectPath: 'root/gitlab',
provide: {
projectPath: 'gitlab-org/gitlab',
sourceProjectPath: 'root/gitlab',
},
});
expect(wrapper.findByTestId('source-branch').text()).toBe('root/gitlab:source-branch');
});
});
describe('imported badge', () => {
it('renders when merge request is imported', () => {
createComponent({
props: { isImported: true },
});
expect(findImportedBadge().props('importableType')).toBe('merge_request');
});
it('does not render when merge request is not imported', () => {
createComponent({
props: { isImported: false },
});
expect(findImportedBadge().exists()).toBe(false);
});
});
});
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册