debian-mirror-gitlab/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue

309 lines
8.6 KiB
Vue
Raw Normal View History

2018-11-08 19:23:39 +05:30
<script>
2018-03-17 18:26:18 +05:30
import Project from '~/pages/projects/project';
import SmartInterval from '~/smart_interval';
2018-11-08 19:23:39 +05:30
import createFlash from '../flash';
2017-08-17 22:00:37 +05:30
import {
WidgetHeader,
WidgetMergeHelp,
WidgetPipeline,
2018-05-09 12:01:36 +05:30
Deployment,
2017-08-17 22:00:37 +05:30
WidgetRelatedLinks,
MergedState,
ClosedState,
2017-09-10 17:25:29 +05:30
MergingState,
2018-03-17 18:26:18 +05:30
RebaseState,
2018-10-15 14:42:47 +05:30
WorkInProgressState,
2017-08-17 22:00:37 +05:30
ArchivedState,
ConflictsState,
NothingToMergeState,
MissingBranchState,
NotAllowedState,
ReadyToMergeState,
2018-05-09 12:01:36 +05:30
ShaMismatchState,
2017-08-17 22:00:37 +05:30
UnresolvedDiscussionsState,
PipelineBlockedState,
PipelineFailedState,
FailedToMerge,
MergeWhenPipelineSucceedsState,
AutoMergeFailed,
CheckingState,
MRWidgetStore,
MRWidgetService,
eventHub,
stateMaps,
SquashBeforeMerge,
notify,
2018-05-09 12:01:36 +05:30
SourceBranchRemovalStatus,
2017-08-17 22:00:37 +05:30
} from './dependencies';
2018-11-18 11:00:15 +05:30
import GroupedTestReportsApp from '../reports/components/grouped_test_reports_app.vue';
2018-11-08 19:23:39 +05:30
import { setFaviconOverlay } from '../lib/utils/common_utils';
2017-08-17 22:00:37 +05:30
export default {
el: '#js-vue-mr-widget',
name: 'MRWidget',
2018-11-08 19:23:39 +05:30
components: {
'mr-widget-header': WidgetHeader,
'mr-widget-merge-help': WidgetMergeHelp,
'mr-widget-pipeline': WidgetPipeline,
Deployment,
'mr-widget-related-links': WidgetRelatedLinks,
'mr-widget-merged': MergedState,
'mr-widget-closed': ClosedState,
'mr-widget-merging': MergingState,
'mr-widget-failed-to-merge': FailedToMerge,
'mr-widget-wip': WorkInProgressState,
'mr-widget-archived': ArchivedState,
'mr-widget-conflicts': ConflictsState,
'mr-widget-nothing-to-merge': NothingToMergeState,
'mr-widget-not-allowed': NotAllowedState,
'mr-widget-missing-branch': MissingBranchState,
'mr-widget-ready-to-merge': ReadyToMergeState,
'sha-mismatch': ShaMismatchState,
'mr-widget-squash-before-merge': SquashBeforeMerge,
'mr-widget-checking': CheckingState,
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState,
'mr-widget-pipeline-blocked': PipelineBlockedState,
'mr-widget-pipeline-failed': PipelineFailedState,
'mr-widget-merge-when-pipeline-succeeds': MergeWhenPipelineSucceedsState,
'mr-widget-auto-merge-failed': AutoMergeFailed,
'mr-widget-rebase': RebaseState,
SourceBranchRemovalStatus,
2018-11-18 11:00:15 +05:30
GroupedTestReportsApp,
2018-11-08 19:23:39 +05:30
},
2017-09-10 17:25:29 +05:30
props: {
mrData: {
type: Object,
required: false,
2018-11-08 19:23:39 +05:30
default: null,
2017-09-10 17:25:29 +05:30
},
},
2017-08-17 22:00:37 +05:30
data() {
2017-09-10 17:25:29 +05:30
const store = new MRWidgetStore(this.mrData || window.gl.mrWidgetData);
2017-08-17 22:00:37 +05:30
const service = this.createService(store);
return {
mr: store,
service,
};
},
computed: {
componentName() {
return stateMaps.stateToComponentMap[this.mr.state];
},
shouldRenderMergeHelp() {
return stateMaps.statesToShowHelpWidget.indexOf(this.mr.state) > -1;
},
shouldRenderPipelines() {
2018-03-17 18:26:18 +05:30
return this.mr.hasCI;
2017-08-17 22:00:37 +05:30
},
shouldRenderRelatedLinks() {
2018-03-17 18:26:18 +05:30
return !!this.mr.relatedLinks && !this.mr.isNothingToMergeState;
2017-08-17 22:00:37 +05:30
},
2018-05-09 12:01:36 +05:30
shouldRenderSourceBranchRemovalStatus() {
return !this.mr.canRemoveSourceBranch && this.mr.shouldRemoveSourceBranch &&
(!this.mr.isNothingToMergeState && !this.mr.isMergedState);
2017-08-17 22:00:37 +05:30
},
},
2018-11-08 19:23:39 +05:30
created() {
this.initPolling();
this.bindEventHubListeners();
2018-12-05 23:21:45 +05:30
eventHub.$on('mr.discussion.updated', this.checkStatus);
2018-11-08 19:23:39 +05:30
},
mounted() {
this.handleMounted();
},
2018-12-05 23:21:45 +05:30
beforeDestroy() {
eventHub.$off('mr.discussion.updated', this.checkStatus);
this.pollingInterval.destroy();
this.deploymentsInterval.destroy();
},
2017-08-17 22:00:37 +05:30
methods: {
createService(store) {
const endpoints = {
mergePath: store.mergePath,
mergeCheckPath: store.mergeCheckPath,
cancelAutoMergePath: store.cancelAutoMergePath,
removeWIPPath: store.removeWIPPath,
sourceBranchPath: store.sourceBranchPath,
ciEnvironmentsStatusPath: store.ciEnvironmentsStatusPath,
statusPath: store.statusPath,
mergeActionsContentPath: store.mergeActionsContentPath,
2018-03-17 18:26:18 +05:30
rebasePath: store.rebasePath,
2017-08-17 22:00:37 +05:30
};
return new MRWidgetService(endpoints);
},
checkStatus(cb) {
2018-03-17 18:26:18 +05:30
return this.service.checkStatus()
.then(res => res.data)
.then((data) => {
this.handleNotification(data);
this.mr.setData(data);
this.setFaviconHelper();
2017-08-17 22:00:37 +05:30
if (cb) {
2018-03-17 18:26:18 +05:30
cb.call(null, data);
2017-08-17 22:00:37 +05:30
}
})
2018-11-08 19:23:39 +05:30
.catch(() => createFlash('Something went wrong. Please try again.'));
2017-08-17 22:00:37 +05:30
},
initPolling() {
2018-03-17 18:26:18 +05:30
this.pollingInterval = new SmartInterval({
2017-08-17 22:00:37 +05:30
callback: this.checkStatus,
startingInterval: 10000,
maxInterval: 30000,
hiddenInterval: 120000,
incrementByFactorOf: 5000,
});
},
initDeploymentsPolling() {
2018-03-17 18:26:18 +05:30
this.deploymentsInterval = new SmartInterval({
2017-08-17 22:00:37 +05:30
callback: this.fetchDeployments,
startingInterval: 30000,
maxInterval: 120000,
hiddenInterval: 240000,
incrementByFactorOf: 15000,
immediateExecution: true,
});
},
2018-03-17 18:26:18 +05:30
setFaviconHelper() {
2017-08-17 22:00:37 +05:30
if (this.mr.ciStatusFaviconPath) {
2018-11-08 19:23:39 +05:30
return setFaviconOverlay(this.mr.ciStatusFaviconPath);
2017-08-17 22:00:37 +05:30
}
2018-11-08 19:23:39 +05:30
return Promise.resolve();
2017-08-17 22:00:37 +05:30
},
fetchDeployments() {
2018-03-17 18:26:18 +05:30
return this.service.fetchDeployments()
.then(res => res.data)
.then((data) => {
if (data.length) {
this.mr.deployments = data;
2017-08-17 22:00:37 +05:30
}
})
.catch(() => {
2018-11-08 19:23:39 +05:30
createFlash('Something went wrong while fetching the environments for this merge request. Please try again.');
2017-08-17 22:00:37 +05:30
});
},
fetchActionsContent() {
this.service.fetchMergeActionsContent()
.then((res) => {
2018-03-17 18:26:18 +05:30
if (res.data) {
2017-08-17 22:00:37 +05:30
const el = document.createElement('div');
2018-03-17 18:26:18 +05:30
el.innerHTML = res.data;
2017-08-17 22:00:37 +05:30
document.body.appendChild(el);
2018-03-17 18:26:18 +05:30
Project.initRefSwitcher();
2017-08-17 22:00:37 +05:30
}
})
2018-11-08 19:23:39 +05:30
.catch(() => createFlash('Something went wrong. Please try again.'));
2017-08-17 22:00:37 +05:30
},
handleNotification(data) {
if (data.ci_status === this.mr.ciStatus) return;
2018-03-17 18:26:18 +05:30
if (!data.pipeline) return;
2017-08-17 22:00:37 +05:30
2018-11-08 19:23:39 +05:30
const { label } = data.pipeline.details.status;
2017-08-17 22:00:37 +05:30
const title = `Pipeline ${label}`;
const message = `Pipeline ${label} for "${data.title}"`;
notify.notifyMe(title, message, this.mr.gitlabLogo);
},
resumePolling() {
this.pollingInterval.resume();
},
stopPolling() {
this.pollingInterval.stopTimer();
},
bindEventHubListeners() {
eventHub.$on('MRWidgetUpdateRequested', (cb) => {
this.checkStatus(cb);
});
// `params` should be an Array contains a Boolean, like `[true]`
// Passing parameter as Boolean didn't work.
eventHub.$on('SetBranchRemoveFlag', (params) => {
2018-11-08 19:23:39 +05:30
[this.mr.isRemovingSourceBranch] = params;
2017-08-17 22:00:37 +05:30
});
eventHub.$on('FailedToMerge', (mergeError) => {
this.mr.state = 'failedToMerge';
this.mr.mergeError = mergeError;
});
eventHub.$on('UpdateWidgetData', (data) => {
this.mr.setData(data);
});
eventHub.$on('FetchActionsContent', () => {
this.fetchActionsContent();
});
eventHub.$on('EnablePolling', () => {
this.resumePolling();
});
eventHub.$on('DisablePolling', () => {
this.stopPolling();
});
},
handleMounted() {
2018-03-17 18:26:18 +05:30
this.setFaviconHelper();
2017-08-17 22:00:37 +05:30
this.initDeploymentsPolling();
},
},
2018-11-08 19:23:39 +05:30
};
</script>
<template>
<div class="mr-state-widget prepend-top-default">
<mr-widget-header
:mr="mr"
/>
<mr-widget-pipeline
v-if="shouldRenderPipelines"
:pipeline="mr.pipeline"
:ci-status="mr.ciStatus"
:has-ci="mr.hasCI"
2018-11-20 20:47:30 +05:30
:source-branch="mr.sourceBranch"
2018-11-08 19:23:39 +05:30
:source-branch-link="mr.sourceBranchLink"
/>
<deployment
v-for="deployment in mr.deployments"
:key="deployment.id"
:deployment="deployment"
/>
<div class="mr-section-container">
2018-11-18 11:00:15 +05:30
<grouped-test-reports-app
v-if="mr.testResultsPath"
:endpoint="mr.testResultsPath"
/>
2017-09-10 17:25:29 +05:30
<div class="mr-widget-section">
<component
:is="componentName"
:mr="mr"
2018-11-08 19:23:39 +05:30
:service="service"
/>
<section
v-if="mr.allowCollaboration"
class="mr-info-list mr-links"
>
{{ s__("mrWidget|Allows commits from members who can merge to the target branch") }}
</section>
2017-09-10 17:25:29 +05:30
<mr-widget-related-links
v-if="shouldRenderRelatedLinks"
:state="mr.state"
2018-11-08 19:23:39 +05:30
:related-links="mr.relatedLinks"
/>
2018-05-09 12:01:36 +05:30
<source-branch-removal-status
v-if="shouldRenderSourceBranchRemovalStatus"
/>
2017-09-10 17:25:29 +05:30
</div>
<div
2018-11-08 19:23:39 +05:30
v-if="shouldRenderMergeHelp"
2017-09-10 17:25:29 +05:30
class="mr-widget-footer"
2018-11-08 19:23:39 +05:30
>
2017-09-10 17:25:29 +05:30
<mr-widget-merge-help />
</div>
2017-08-17 22:00:37 +05:30
</div>
2018-11-08 19:23:39 +05:30
</div>
</template>