summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_merge_request_widget/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget/components')
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue23
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue58
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/report_widget_container.vue10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/state_container.vue8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue21
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue22
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue5
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue41
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue7
11 files changed, 112 insertions, 95 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index e8cc9b2eb2a..7cfc9431c2a 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -69,7 +69,7 @@ export default {
isCollapsible() {
if (!this.isLoadingSummary && this.loadingState !== LOADING_STATES.collapsedError) {
if (this.shouldCollapse) {
- return this.shouldCollapse();
+ return this.shouldCollapse(this.collapsedData);
}
return true;
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue
index 6475def461a..e435dc56503 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue
@@ -1,12 +1,10 @@
<script>
-import { GlButton, GlLoadingIcon, GlIcon } from '@gitlab/ui';
+import { GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
export default {
components: {
GlButton,
- GlLoadingIcon,
- GlIcon,
},
props: {
title: {
@@ -32,7 +30,7 @@ export default {
computed: {
arrowIconName() {
- return this.isCollapsed ? 'chevron-lg-right' : 'chevron-lg-down';
+ return this.isCollapsed ? 'chevron-right' : 'chevron-down';
},
ariaLabel() {
return this.isCollapsed ? __('Expand') : __('Collapse');
@@ -47,7 +45,7 @@ export default {
</script>
<template>
<div class="mr-widget-extension">
- <div class="d-flex align-items-center pl-3">
+ <div class="d-flex align-items-center pl-3 gl-py-3">
<div v-if="hasError" class="ci-widget media">
<div class="media-body">
<span class="gl-font-sm mr-widget-margin-left gl-line-height-24 js-error-state">
@@ -57,16 +55,15 @@ export default {
</div>
<template v-else>
- <button
- class="btn-blank btn s32 square"
- type="button"
+ <gl-button
+ class="gl-mr-3"
+ size="small"
:aria-label="ariaLabel"
- :disabled="isLoading"
+ :loading="isLoading"
+ :icon="arrowIconName"
+ category="tertiary"
@click="toggleCollapsed"
- >
- <gl-loading-icon v-if="isLoading" size="sm" />
- <gl-icon v-else :name="arrowIconName" class="js-icon" />
- </button>
+ />
<template v-if="isCollapsed">
<slot name="header"></slot>
<gl-button
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
index c2a3ae361ca..20284c4a3d8 100644
--- 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
@@ -19,20 +19,18 @@ export default {
},
step3: {
label: __('Step 3.'),
- help: __(
- 'Merge the feature branch into the target branch and fix any conflicts. %{linkStart}How do I fix them?%{linkEnd}',
- ),
+ help: __('Resolve any conflicts. %{linkStart}How do I fix them?%{linkEnd}'),
},
step4: {
label: __('Step 4.'),
- help: __('Push the target branch up to GitLab.'),
+ help: __('Push the source branch up to GitLab.'),
},
},
copyCommands: __('Copy commands'),
tip: __(
- '%{strongStart}Tip:%{strongEnd} You can also check out merge requests locally. %{linkStart}Learn more.%{linkEnd}',
+ '%{strongStart}Tip:%{strongEnd} You can also %{linkStart}check out with merge request ID%{linkEnd}.',
),
- title: __('Check out, review, and merge locally'),
+ title: __('Check out, review, and resolve locally'),
},
components: {
GlModal,
@@ -93,21 +91,11 @@ export default {
: `git fetch origin\ngit checkout -b ${this.escapedSourceBranch} ${escapedOriginBranch}`;
},
mergeInfo2() {
- return this.isFork
- ? `git fetch origin\ngit checkout ${this.escapedTargetBranch}\ngit merge --no-ff ${this.escapedForkBranch}`
- : `git fetch origin\ngit checkout ${this.escapedTargetBranch}\ngit merge --no-ff ${this.escapedSourceBranch}`;
- },
- mergeInfo3() {
- return this.canMerge
- ? `git push origin ${this.escapedTargetBranch}`
- : __('Note that pushing to GitLab requires write access to this repository.');
+ return `git push origin ${this.escapedSourceBranch}`;
},
escapedForkBranch() {
return escapeShellString(`${this.sourceProjectPath}-${this.sourceBranch}`);
},
- escapedTargetBranch() {
- return escapeShellString(this.targetBranch);
- },
escapedSourceBranch() {
return escapeShellString(this.sourceBranch);
},
@@ -145,6 +133,18 @@ export default {
class="gl-shadow-none! gl-bg-transparent! gl-flex-shrink-0"
/>
</div>
+ <p v-if="reviewingDocsPath">
+ <gl-sprintf data-testid="docs-tip" :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>
<p>
<strong>
@@ -164,14 +164,6 @@ export default {
</template>
</gl-sprintf>
</p>
- <div class="gl-display-flex">
- <pre class="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 }}
@@ -179,24 +171,12 @@ export default {
{{ $options.i18n.steps.step4.help }}
</p>
<div class="gl-display-flex">
- <pre class="gl-w-full" data-testid="how-to-merge-instructions">{{ mergeInfo3 }}</pre>
+ <pre class="gl-w-full" data-testid="how-to-merge-instructions">{{ mergeInfo2 }}</pre>
<clipboard-button
- :text="mergeInfo3"
+ :text="mergeInfo2"
:title="$options.i18n.copyCommands"
class="gl-shadow-none! gl-bg-transparent! gl-flex-shrink-0"
/>
</div>
- <p v-if="reviewingDocsPath">
- <gl-sprintf data-testid="docs-tip" :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/report_widget_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/report_widget_container.vue
index 2683956e603..ecf08f78f57 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/report_widget_container.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/report_widget_container.vue
@@ -6,7 +6,15 @@ export default {
};
},
updated() {
- this.hasChildren = this.$scopedSlots.default?.()?.some((c) => c.tag);
+ this.hasChildren = this.checkSlots();
+ },
+ mounted() {
+ this.hasChildren = this.checkSlots();
+ },
+ methods: {
+ checkSlots() {
+ return this.$scopedSlots.default?.()?.some((c) => c.tag);
+ },
},
};
</script>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/state_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/state_container.vue
index 9a3555d3e11..f7d6f7b4345 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/state_container.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/state_container.vue
@@ -76,17 +76,17 @@ export default {
<div
:class="{
'gl-display-flex gl-align-items-center': actions.length,
- 'gl-md-display-flex gl-align-items-center': !actions.length,
+ 'gl-md-display-flex gl-align-items-center gl-flex-wrap gl-gap-3': !actions.length,
}"
- class="media-body"
+ class="media-body gl-line-height-24"
>
<slot></slot>
<div
:class="{
- 'state-container-action-buttons gl-flex-direction-column gl-flex-wrap gl-justify-content-end': !actions.length,
+ 'state-container-action-buttons gl-flex-wrap gl-lg-justify-content-end': !actions.length,
'gl-md-pt-0 gl-pt-3': hasActionsSlot,
}"
- class="gl-display-flex gl-font-size-0 gl-ml-auto gl-gap-3"
+ class="gl-display-flex gl-font-size-0 gl-gap-3"
>
<slot name="actions">
<actions v-if="actions.length" :tertiary-buttons="actions" />
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 8e1b18c63a4..a5d982fe221 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
@@ -88,25 +88,24 @@ export default {
</template>
<template v-if="!isLoading && !state.shouldBeRebased" #actions>
<gl-button
- v-if="userPermissions.canMerge"
+ v-if="showResolveButton"
+ :href="mr.conflictResolutionPath"
size="small"
variant="confirm"
- category="secondary"
- data-testid="merge-locally-button"
- class="js-check-out-modal-trigger gl-align-self-start"
- :class="{ 'gl-mr-2': showResolveButton }"
+ class="gl-align-self-start"
+ data-testid="resolve-conflicts-button"
>
- {{ s__('mrWidget|Resolve locally') }}
+ {{ s__('mrWidget|Resolve conflicts') }}
</gl-button>
<gl-button
- v-if="showResolveButton"
- :href="mr.conflictResolutionPath"
+ v-if="userPermissions.canMerge"
size="small"
variant="confirm"
- class="gl-mb-2 gl-md-mb-0 gl-align-self-start"
- data-testid="resolve-conflicts-button"
+ category="secondary"
+ data-testid="merge-locally-button"
+ class="js-check-out-modal-trigger gl-align-self-start"
>
- {{ s__('mrWidget|Resolve conflicts') }}
+ {{ s__('mrWidget|Resolve locally') }}
</gl-button>
</template>
</state-container>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
index 4ae4edf02c3..d687f0346c7 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue
@@ -179,27 +179,27 @@ export default {
</template>
<template v-if="!isLoading" #actions>
<gl-button
- v-if="showRebaseWithoutPipeline"
:loading="isMakingRequest"
variant="confirm"
size="small"
- category="secondary"
- data-testid="rebase-without-ci-button"
- class="gl-align-self-start gl-mr-2"
- @click="rebaseWithoutCi"
+ data-qa-selector="mr_rebase_button"
+ data-testid="standard-rebase-button"
+ class="gl-align-self-start"
+ @click="rebase"
>
- {{ __('Rebase without pipeline') }}
+ {{ __('Rebase') }}
</gl-button>
<gl-button
+ v-if="showRebaseWithoutPipeline"
:loading="isMakingRequest"
variant="confirm"
size="small"
- data-qa-selector="mr_rebase_button"
- data-testid="standard-rebase-button"
- class="gl-mb-2 gl-md-mb-0 gl-align-self-start"
- @click="rebase"
+ category="secondary"
+ data-testid="rebase-without-ci-button"
+ class="gl-align-self-start gl-mr-2"
+ @click="rebaseWithoutCi"
>
- {{ __('Rebase') }}
+ {{ __('Rebase without pipeline') }}
</gl-button>
</template>
</state-container>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
index 01f9b4757a0..211fbba305f 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue
@@ -1,7 +1,6 @@
<script>
import { GlButton } from '@gitlab/ui';
import { produce } from 'immer';
-import $ from 'jquery';
import { createAlert } from '~/flash';
import toast from '~/vue_shared/plugins/global_toast';
import { __ } from '~/locale';
@@ -111,7 +110,9 @@ export default {
},
}) => {
toast(__('Marked as ready. Merging is now allowed.'));
- $('.merge-request .detail-page-description .title').text(title);
+ document.querySelector(
+ '.merge-request .detail-page-description .title',
+ ).textContent = title;
if (!window.gon?.features?.realtimeMrStatusChange) {
eventHub.$emit('MRWidgetUpdateRequested');
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue
index 18aa85484ea..5db5f1f8dcf 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/app.vue
@@ -1,5 +1,11 @@
<script>
export default {
+ components: {
+ MrSecurityWidget: () =>
+ import(
+ '~/vue_merge_request_widget/extensions/security_reports/mr_widget_security_reports.vue'
+ ),
+ },
props: {
mr: {
type: Object,
@@ -8,7 +14,9 @@ export default {
},
computed: {
widgets() {
- return [].filter((w) => w);
+ return [window.gon?.features?.refactorSecurityExtension && 'MrSecurityWidget'].filter(
+ (w) => w,
+ );
},
},
};
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
index cdf35033021..7343c98938c 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget.vue
@@ -42,7 +42,8 @@ export default {
*/
value: {
type: Object,
- required: true,
+ required: false,
+ default: () => ({}),
},
loadingText: {
type: String,
@@ -56,7 +57,8 @@ export default {
},
fetchCollapsedData: {
type: Function,
- required: true,
+ required: false,
+ default: undefined,
},
fetchExpandedData: {
type: Function,
@@ -119,6 +121,12 @@ export default {
required: false,
default: null,
},
+ // When this is provided, the widget will display an error message in the summary section.
+ hasError: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -138,8 +146,17 @@ export default {
summaryStatusIcon() {
return this.summaryError ? this.$options.failedStatusIcon : this.statusIconName;
},
+ hasActionButtons() {
+ return this.actionButtons.length > 0 || Boolean(this.$scopedSlots['action-buttons']);
+ },
},
watch: {
+ hasError: {
+ handler(newValue) {
+ this.summaryError = newValue ? this.errorText : null;
+ },
+ immediate: true,
+ },
isLoading(newValue) {
this.$emit('is-loading', newValue);
},
@@ -154,7 +171,9 @@ export default {
this.telemetryHub?.viewed();
try {
- await this.fetch(this.fetchCollapsedData, FETCH_TYPE_COLLAPSED);
+ if (this.fetchCollapsedData) {
+ await this.fetch(this.fetchCollapsedData, FETCH_TYPE_COLLAPSED);
+ }
} catch {
this.summaryError = this.errorText;
}
@@ -258,7 +277,7 @@ export default {
v-if="helpPopover"
icon="information-o"
:options="helpPopover.options"
- :class="{ 'gl-mr-3': actionButtons.length > 0 }"
+ :class="{ 'gl-mr-3': hasActionButtons }"
>
<template v-if="helpPopover.content">
<p
@@ -275,12 +294,14 @@ export default {
>
</template>
</help-popover>
- <action-buttons
- v-if="actionButtons.length > 0"
- :widget="widgetName"
- :tertiary-buttons="actionButtons"
- @clickedAction="onActionClick"
- />
+ <slot name="action-buttons">
+ <action-buttons
+ v-if="actionButtons.length > 0"
+ :widget="widgetName"
+ :tertiary-buttons="actionButtons"
+ @clickedAction="onActionClick"
+ />
+ </slot>
</div>
<div
v-if="isCollapsible"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue
index 543136dc659..b64f9c148d1 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue
@@ -79,8 +79,11 @@ export default {
</script>
<template>
<div
- class="gl-w-full gl-display-flex gl-align-items-baseline"
- :class="{ 'gl-border-t gl-py-3 gl-pl-7': level === 2 }"
+ class="gl-w-full gl-display-flex"
+ :class="{
+ 'gl-border-t gl-py-3 gl-pl-7 gl-align-items-baseline': level === 2,
+ 'gl-align-items-center': level === 3,
+ }"
>
<status-icon
v-if="statusIconName && !header"