Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment/constants.js1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue11
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue20
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue166
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue3
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue19
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue20
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue28
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue7
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js6
10 files changed, 236 insertions, 45 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/constants.js b/app/assets/javascripts/vue_merge_request_widget/components/deployment/constants.js
index 66de4f8b682..29d067a46a6 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/constants.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/constants.js
@@ -6,6 +6,7 @@ export const RUNNING = 'running';
export const SUCCESS = 'success';
export const FAILED = 'failed';
export const CANCELED = 'canceled';
+export const SKIPPED = 'skipped';
// ACTION STATUSES
export const STOPPING = 'stopping';
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue
index 2f922b990d9..390469dec24 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_info.vue
@@ -4,7 +4,15 @@ import { __ } from '~/locale';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import MemoryUsage from './memory_usage.vue';
-import { MANUAL_DEPLOY, WILL_DEPLOY, RUNNING, SUCCESS, FAILED, CANCELED } from './constants';
+import {
+ MANUAL_DEPLOY,
+ WILL_DEPLOY,
+ RUNNING,
+ SUCCESS,
+ FAILED,
+ CANCELED,
+ SKIPPED,
+} from './constants';
export default {
name: 'DeploymentInfo',
@@ -38,6 +46,7 @@ export default {
[SUCCESS]: __('Deployed to'),
[FAILED]: __('Failed to deploy to'),
[CANCELED]: __('Canceled deployment to'),
+ [SKIPPED]: __('Skipped deployment to'),
},
computed: {
deployTimeago() {
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
index d5fdbe726e9..6628ab7be83 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
@@ -7,12 +7,14 @@ import {
GlDropdownSectionHeader,
GlDropdownItem,
GlTooltipDirective,
+ GlModalDirective,
} from '@gitlab/ui';
import { n__, s__, sprintf } from '~/locale';
import { mergeUrlParams, webIDEUrl } from '~/lib/utils/url_utility';
import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
import MrWidgetIcon from './mr_widget_icon.vue';
+import MrWidgetHowToMergeModal from './mr_widget_how_to_merge_modal.vue';
export default {
name: 'MRWidgetHeader',
@@ -20,6 +22,7 @@ export default {
clipboardButton,
TooltipOnTruncate,
MrWidgetIcon,
+ MrWidgetHowToMergeModal,
GlButton,
GlDropdown,
GlDropdownSectionHeader,
@@ -27,6 +30,7 @@ export default {
},
directives: {
GlTooltip: GlTooltipDirective,
+ GlModalDirective,
},
props: {
mr: {
@@ -82,6 +86,9 @@ export default {
)
: '';
},
+ isFork() {
+ return this.mr.sourceProjectFullPath !== this.mr.targetProjectFullPath;
+ },
},
};
</script>
@@ -140,13 +147,22 @@ export default {
</gl-button>
</span>
<gl-button
+ v-gl-modal-directive="'modal-merge-info'"
:disabled="mr.sourceBranchRemoved"
- data-target="#modal_merge_info"
- data-toggle="modal"
class="js-check-out-branch gl-mr-3"
>
{{ s__('mrWidget|Check out branch') }}
</gl-button>
+ <mr-widget-how-to-merge-modal
+ :is-fork="isFork"
+ :can-merge="mr.canMerge"
+ :source-branch="mr.sourceBranch"
+ :source-project="mr.sourceProject"
+ :source-project-path="mr.sourceProjectFullPath"
+ :target-branch="mr.targetBranch"
+ :source-project-default-url="mr.sourceProjectDefaultUrl"
+ :reviewing-docs-path="mr.reviewingDocsPath"
+ />
</template>
<gl-dropdown
v-gl-tooltip
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
new file mode 100644
index 00000000000..957356eab27
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
@@ -0,0 +1,166 @@
+<script>
+/* eslint-disable @gitlab/require-i18n-strings */
+import { GlModal, GlLink, GlSprintf } from '@gitlab/ui';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import { __ } from '~/locale';
+
+export default {
+ i18n: {
+ steps: {
+ step1: {
+ label: __('Step 1.'),
+ help: __('Fetch and check out the branch for this merge request'),
+ },
+ step2: {
+ label: __('Step 2.'),
+ help: __('Review the changes locally'),
+ },
+ step3: {
+ label: __('Step 3.'),
+ help: __('Merge the branch and fix any conflicts that come up'),
+ },
+ step4: {
+ label: __('Step 4.'),
+ help: __('Push the result of the merge to GitLab'),
+ },
+ },
+ copyCommands: __('Copy commands'),
+ tip: __(
+ '%{strongStart}Tip:%{strongEnd} You can also checkout merge requests locally by %{linkStart}following these guidelines%{linkEnd}',
+ ),
+ title: __('Check out, review, and merge locally'),
+ },
+ components: {
+ GlModal,
+ ClipboardButton,
+ GlLink,
+ GlSprintf,
+ },
+ props: {
+ canMerge: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isFork: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ sourceBranch: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ sourceProjectPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ targetBranch: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ sourceProjectDefaultUrl: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ reviewingDocsPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+ computed: {
+ mergeInfo1() {
+ return this.isFork
+ ? `git fetch "${this.sourceProjectDefaultUrl}" ${this.sourceBranch}\ngit checkout -b "${this.sourceProjectPath}-${this.sourceBranch}" FETCH_HEAD`
+ : `git fetch origin\ngit checkout -b "${this.sourceBranch}" "origin/${this.sourceBranch}"`;
+ },
+ mergeInfo2() {
+ return this.isFork
+ ? `git fetch origin\ngit checkout "${this.targetBranch}"\ngit merge --no-ff "${this.sourceProjectPath}-${this.sourceBranch}"`
+ : `git fetch origin\ngit checkout "${this.targetBranch}"\ngit merge --no-ff " ${this.sourceBranch}"`;
+ },
+ mergeInfo3() {
+ return this.canMerge
+ ? `git push origin "${this.targetBranch}"`
+ : __('Note that pushing to GitLab requires write access to this repository.');
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-modal modal-id="modal-merge-info" :title="$options.i18n.title" no-fade hide-footer>
+ <p>
+ <strong>
+ {{ $options.i18n.steps.step1.label }}
+ </strong>
+ {{ $options.i18n.steps.step1.help }}
+ </p>
+ <div class="gl-display-flex">
+ <pre class="gl-overflow-scroll gl-w-full" data-testid="how-to-merge-instructions">{{
+ mergeInfo1
+ }}</pre>
+ <clipboard-button
+ :text="mergeInfo1"
+ :title="$options.i18n.copyCommands"
+ class="gl-shadow-none! gl-bg-transparent! gl-flex-shrink-0"
+ />
+ </div>
+
+ <p>
+ <strong>
+ {{ $options.i18n.steps.step2.label }}
+ </strong>
+ {{ $options.i18n.steps.step2.help }}
+ </p>
+ <p>
+ <strong>
+ {{ $options.i18n.steps.step3.label }}
+ </strong>
+ {{ $options.i18n.steps.step3.help }}
+ </p>
+ <div class="gl-display-flex">
+ <pre class="gl-overflow-scroll gl-w-full" data-testid="how-to-merge-instructions">{{
+ mergeInfo2
+ }}</pre>
+ <clipboard-button
+ :text="mergeInfo2"
+ :title="$options.i18n.copyCommands"
+ class="gl-shadow-none! gl-bg-transparent! gl-flex-shrink-0"
+ />
+ </div>
+ <p>
+ <strong>
+ {{ $options.i18n.steps.step4.label }}
+ </strong>
+ {{ $options.i18n.steps.step4.help }}
+ </p>
+ <div class="gl-display-flex">
+ <pre class="gl-overflow-scroll gl-w-full" data-testid="how-to-merge-instructions">{{
+ mergeInfo3
+ }}</pre>
+ <clipboard-button
+ :text="mergeInfo3"
+ :title="$options.i18n.copyCommands"
+ class="gl-shadow-none! gl-bg-transparent! gl-flex-shrink-0"
+ />
+ </div>
+ <p v-if="reviewingDocsPath">
+ <gl-sprintf :message="$options.i18n.tip">
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ <template #link="{ content }">
+ <gl-link class="gl-display-inline-block" :href="reviewingDocsPath" target="_blank">{{
+ content
+ }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue
index 55efd7e7d3b..dffe3cab904 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue
@@ -1,7 +1,6 @@
<script>
import { isNumber } from 'lodash';
import ArtifactsApp from './artifacts_list_app.vue';
-import Deployment from './deployment/deployment.vue';
import MrWidgetContainer from './mr_widget_container.vue';
import MrWidgetPipeline from './mr_widget_pipeline.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -18,7 +17,7 @@ export default {
name: 'MrWidgetPipelineContainer',
components: {
ArtifactsApp,
- Deployment,
+ Deployment: () => import('./deployment/deployment.vue'),
MrWidgetContainer,
MrWidgetPipeline,
MergeTrainPositionIndicator: () =>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
index 82566682bca..bc23ca6b1fc 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue
@@ -1,10 +1,11 @@
<script>
-import { GlLoadingIcon } from '@gitlab/ui';
+import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import ciIcon from '../../vue_shared/components/ci_icon.vue';
export default {
components: {
ciIcon,
+ GlButton,
GlLoadingIcon,
},
props: {
@@ -32,21 +33,23 @@ export default {
};
</script>
<template>
- <div class="d-flex align-self-start">
+ <div class="gl-display-flex gl-align-self-start">
<div class="square s24 h-auto d-flex-center gl-mr-3">
- <div v-if="isLoading" class="mr-widget-icon d-inline-flex">
- <gl-loading-icon size="md" class="mr-loading-icon d-inline-flex" />
+ <div v-if="isLoading" class="mr-widget-icon gl-display-inline-flex">
+ <gl-loading-icon size="md" class="mr-loading-icon gl-display-inline-flex" />
</div>
<ci-icon v-else :status="statusObj" :size="24" />
</div>
- <button
+ <gl-button
v-if="showDisabledButton"
type="button"
- class="js-disabled-merge-button btn btn-success btn-sm"
- disabled="true"
+ category="primary"
+ variant="success"
+ class="js-disabled-merge-button"
+ :disabled="true"
>
{{ s__('mrWidget|Merge') }}
- </button>
+ </gl-button>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
index d421b744fa1..2df03fbc679 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
@@ -1,6 +1,7 @@
<script>
import $ from 'jquery';
import { escape } from 'lodash';
+import { GlButton, GlModalDirective } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
import { mouseenter, debouncedMouseleave, togglePopover } from '~/shared/popover';
import StatusIcon from '../mr_widget_status_icon.vue';
@@ -9,6 +10,10 @@ export default {
name: 'MRWidgetConflicts',
components: {
StatusIcon,
+ GlButton,
+ },
+ directives: {
+ GlModalDirective,
},
props: {
/* TODO: This is providing all store and service down when it
@@ -89,22 +94,21 @@ To merge this request, first rebase locally.`)
</span>
</span>
<span v-if="showResolveButton" ref="popover">
- <a
+ <gl-button
:href="mr.conflictResolutionPath"
:disabled="mr.sourceBranchProtected"
- class="js-resolve-conflicts-button btn btn-default btn-sm"
+ class="js-resolve-conflicts-button"
>
{{ s__('mrWidget|Resolve conflicts') }}
- </a>
+ </gl-button>
</span>
- <button
+ <gl-button
v-if="mr.canMerge"
- class="js-merge-locally-button btn btn-default btn-sm"
- data-toggle="modal"
- data-target="#modal_merge_info"
+ v-gl-modal-directive="'modal-merge-info'"
+ class="js-merge-locally-button"
>
{{ s__('mrWidget|Merge locally') }}
- </button>
+ </gl-button>
</template>
</div>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
index ff0d065c71d..1c9909e7178 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/squash_before_merge.vue
@@ -1,10 +1,11 @@
<script>
-import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { GlIcon, GlTooltipDirective, GlFormCheckbox } from '@gitlab/ui';
import { SQUASH_BEFORE_MERGE } from '../../i18n';
export default {
components: {
GlIcon,
+ GlFormCheckbox,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -32,32 +33,23 @@ export default {
tooltipTitle() {
return this.isDisabled ? this.$options.i18n.tooltipTitle : null;
},
- tooltipFocusable() {
- return this.isDisabled ? '0' : null;
- },
},
};
</script>
<template>
- <div class="inline">
- <label
+ <div class="gl-display-flex gl-align-items-center">
+ <gl-form-checkbox
v-gl-tooltip
- :class="{ 'gl-text-gray-400': isDisabled }"
- :tabindex="tooltipFocusable"
- data-testid="squashLabel"
+ :checked="value"
+ :disabled="isDisabled"
+ name="squash"
+ class="qa-squash-checkbox js-squash-checkbox gl-mb-0 gl-mr-2"
:title="tooltipTitle"
+ @change="checked => $emit('input', checked)"
>
- <input
- :checked="value"
- :disabled="isDisabled"
- type="checkbox"
- name="squash"
- class="qa-squash-checkbox js-squash-checkbox"
- @change="$emit('input', $event.target.checked)"
- />
{{ $options.i18n.checkboxLabel }}
- </label>
+ </gl-form-checkbox>
<a
v-if="helpPath"
v-gl-tooltip
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index 190d790f584..433dcf2e219 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -16,7 +16,6 @@ import WidgetHeader from './components/mr_widget_header.vue';
import WidgetSuggestPipeline from './components/mr_widget_suggest_pipeline.vue';
import WidgetMergeHelp from './components/mr_widget_merge_help.vue';
import MrWidgetPipelineContainer from './components/mr_widget_pipeline_container.vue';
-import Deployment from './components/deployment/deployment.vue';
import WidgetRelatedLinks from './components/mr_widget_related_links.vue';
import MrWidgetAlertMessage from './components/mr_widget_alert_message.vue';
import MergedState from './components/states/mr_widget_merged.vue';
@@ -63,7 +62,6 @@ export default {
'mr-widget-suggest-pipeline': WidgetSuggestPipeline,
'mr-widget-merge-help': WidgetMergeHelp,
MrWidgetPipelineContainer,
- Deployment,
'mr-widget-related-links': WidgetRelatedLinks,
MrWidgetAlertMessage,
'mr-widget-merged': MergedState,
@@ -155,10 +153,7 @@ export default {
},
shouldSuggestPipelines() {
return (
- gon.features?.suggestPipeline &&
- !this.mr.hasCI &&
- this.mr.mergeRequestAddCiConfigPath &&
- !this.mr.isDismissedSuggestPipeline
+ !this.mr.hasCI && this.mr.mergeRequestAddCiConfigPath && !this.mr.isDismissedSuggestPipeline
);
},
shouldRenderCodeQuality() {
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 8b235b20ad4..f50b6caf0f5 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -220,6 +220,7 @@ export default class MergeRequestStore {
this.sourceProjectFullPath = data.source_project_full_path;
this.mergeRequestPipelinesHelpPath = data.merge_request_pipelines_docs_path;
this.conflictsDocsPath = data.conflicts_docs_path;
+ this.reviewingDocsPath = data.reviewing_and_managing_merge_requests_docs_path;
this.ciEnvironmentsStatusPath = data.ci_environments_status_path;
this.securityApprovalsHelpPagePath = data.security_approvals_help_page_path;
this.eligibleApproversDocsPath = data.eligible_approvers_docs_path;
@@ -229,6 +230,7 @@ export default class MergeRequestStore {
this.pipelinesEmptySvgPath = data.pipelines_empty_svg_path;
this.humanAccess = data.human_access;
this.newPipelinePath = data.new_project_pipeline_path;
+ this.sourceProjectDefaultUrl = data.source_project_default_url;
this.userCalloutsPath = data.user_callouts_path;
this.suggestPipelineFeatureId = data.suggest_pipeline_feature_id;
this.isDismissedSuggestPipeline = data.is_dismissed_suggest_pipeline;
@@ -240,6 +242,10 @@ export default class MergeRequestStore {
this.baseBlobPath = blobPath.base_path || '';
this.codequalityHelpPath = data.codequality_help_path;
this.codeclimate = data.codeclimate;
+
+ // Security reports
+ this.sastComparisonPath = data.sast_comparison_path;
+ this.secretScanningComparisonPath = data.secret_scanning_comparison_path;
}
get isNothingToMergeState() {