diff options
Diffstat (limited to 'app/assets/javascripts/vue_merge_request_widget/components')
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" |