Skip to content

Commit 912741c

Browse files
committed
Merge branch '53227-empty-list' into 'master'
Resolve "Empty list for links to changed pages in Review App from MR Widget" Closes #53227 See merge request gitlab-org/gitlab-ce!22665
2 parents 4845401 + 15db499 commit 912741c

File tree

5 files changed

+111
-24
lines changed

5 files changed

+111
-24
lines changed

app/assets/javascripts/vue_merge_request_widget/components/deployment.vue

+17-24
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { visitUrl } from '../../lib/utils/url_utility';
1010
import createFlash from '../../flash';
1111
import MemoryUsage from './memory_usage.vue';
1212
import StatusIcon from './mr_widget_status_icon.vue';
13+
import ReviewAppLink from './review_app_link.vue';
1314
import MRWidgetService from '../services/mr_widget_service';
1415
1516
export default {
@@ -21,6 +22,7 @@ export default {
2122
Icon,
2223
TooltipOnTruncate,
2324
FilteredSearchDropdown,
25+
ReviewAppLink,
2426
},
2527
directives: {
2628
tooltip,
@@ -63,6 +65,12 @@ export default {
6365
deployedText() {
6466
return this.$options.deployedTextMap[this.deployment.status];
6567
},
68+
shouldRenderDropdown() {
69+
return (
70+
this.enableCiEnvironmentsStatusChanges &&
71+
(this.deployment.changes && this.deployment.changes.length > 0)
72+
);
73+
},
6674
},
6775
methods: {
6876
stopEnvironment() {
@@ -133,7 +141,7 @@ export default {
133141
<div>
134142
<template v-if="hasExternalUrls">
135143
<filtered-search-dropdown
136-
v-if="enableCiEnvironmentsStatusChanges"
144+
v-if="shouldRenderDropdown"
137145
class="js-mr-wigdet-deployment-dropdown inline"
138146
:items="deployment.changes"
139147
:main-action-link="deployment.external_url"
@@ -143,18 +151,10 @@ export default {
143151
slot="mainAction"
144152
slot-scope="slotProps"
145153
>
146-
<a
147-
:href="deployment.external_url"
148-
target="_blank"
149-
rel="noopener noreferrer nofollow"
150-
class="deploy-link js-deploy-url inline"
151-
:class="slotProps.className"
152-
>
153-
<span>
154-
{{ __('View app') }}
155-
<icon name="external-link" />
156-
</span>
157-
</a>
154+
<review-app-link
155+
:link="deployment.external_url"
156+
:css-class="`deploy-link js-deploy-url inline ${slotProps.className}`"
157+
/>
158158
</template>
159159

160160
<template
@@ -177,18 +177,11 @@ export default {
177177
</a>
178178
</template>
179179
</filtered-search-dropdown>
180-
<a
180+
<review-app-link
181181
v-else
182-
:href="deployment.external_url"
183-
target="_blank"
184-
rel="noopener noreferrer nofollow"
185-
class="js-deploy-url js-deploy-url-feature-flag deploy-link btn btn-default btn-sm inline"
186-
>
187-
<span>
188-
{{ __('View app') }}
189-
<icon name="external-link" />
190-
</span>
191-
</a>
182+
:link="deployment.external_url"
183+
css-class="js-deploy-url js-deploy-url-feature-flag deploy-link btn btn-default btn-sm inlin"
184+
/>
192185
</template>
193186
<loading-button
194187
v-if="deployment.stop_url"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script>
2+
import Icon from '~/vue_shared/components/icon.vue';
3+
4+
export default {
5+
components: {
6+
Icon,
7+
},
8+
props: {
9+
link: {
10+
type: String,
11+
required: true,
12+
},
13+
cssClass: {
14+
type: String,
15+
required: true,
16+
},
17+
},
18+
};
19+
</script>
20+
<template>
21+
<a
22+
:href="link"
23+
target="_blank"
24+
rel="noopener noreferrer nofollow"
25+
:class="cssClass"
26+
>
27+
{{ __('View app') }}
28+
<icon name="external-link" />
29+
</a>
30+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: Only renders dropdown for review app changes when we have a list of files to
3+
show. Otherwise will render the regular review app button
4+
merge_request:
5+
author:
6+
type: other

spec/javascripts/vue_mr_widget/components/deployment_spec.js

+20
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,26 @@ describe('Deployment component', () => {
211211
});
212212
});
213213

214+
describe('without changes', () => {
215+
beforeEach(() => {
216+
window.gon = window.gon || {};
217+
window.gon.features = window.gon.features || {};
218+
window.gon.features.ciEnvironmentsStatusChanges = true;
219+
delete deploymentMockData.changes;
220+
221+
vm = mountComponent(Component, { deployment: { ...deploymentMockData } });
222+
});
223+
224+
afterEach(() => {
225+
delete window.gon.features.ciEnvironmentsStatusChanges;
226+
});
227+
228+
it('renders the link to the review app without dropdown', () => {
229+
expect(vm.$el.querySelector('.js-mr-wigdet-deployment-dropdown')).toBeNull();
230+
expect(vm.$el.querySelector('.js-deploy-url-feature-flag')).not.toBeNull();
231+
});
232+
});
233+
214234
describe('deployment status', () => {
215235
describe('running', () => {
216236
beforeEach(() => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import Vue from 'vue';
2+
import component from '~/vue_merge_request_widget/components/review_app_link.vue';
3+
import mountComponent from '../../helpers/vue_mount_component_helper';
4+
5+
describe('review app link', () => {
6+
const Component = Vue.extend(component);
7+
const props = {
8+
link: '/review',
9+
cssClass: 'js-link',
10+
};
11+
let vm;
12+
let el;
13+
14+
beforeEach(() => {
15+
vm = mountComponent(Component, props);
16+
el = vm.$el;
17+
});
18+
19+
afterEach(() => {
20+
vm.$destroy();
21+
});
22+
23+
it('renders provided link as href attribute', () => {
24+
expect(el.getAttribute('href')).toEqual(props.link);
25+
});
26+
27+
it('renders provided cssClass as class attribute', () => {
28+
expect(el.getAttribute('class')).toEqual(props.cssClass);
29+
});
30+
31+
it('renders View app text', () => {
32+
expect(el.textContent.trim()).toEqual('View app');
33+
});
34+
35+
it('renders svg icon', () => {
36+
expect(el.querySelector('svg')).not.toBeNull();
37+
});
38+
});

0 commit comments

Comments
 (0)