diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_author.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_author.js index a01cb8cc202ba0cb08b04bcc3cbb51750b377af2..982b5e8e3731f1da3b29977e47fd4c295739273f 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_author.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_author.js @@ -1,3 +1,5 @@ +import tooltip from '../../vue_shared/directives/tooltip'; + export default { name: 'MRWidgetAuthor', props: { @@ -5,11 +7,14 @@ export default { showAuthorName: { type: Boolean, required: false, default: true }, showAuthorTooltip: { type: Boolean, required: false, default: false }, }, + directives: { + tooltip, + }, template: ` <a :href="author.webUrl || author.web_url" - class="author-link" - :class="{ 'has-tooltip': showAuthorTooltip }" + class="author-link inline" + :v-tooltip="showAuthorTooltip" :title="author.name"> <img :src="author.avatarUrl || author.avatar_url" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js index 744a1cd24fac839a8ac7668c49c6ba6105cb0294..e98d147733c7864cbb2859509c81fd4be492b31c 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js @@ -1,8 +1,8 @@ /* global Flash */ import '~/lib/utils/datetime_utility'; -import { statusIconEntityMap } from '../../vue_shared/ci_status_icons'; import MemoryUsage from './mr_widget_memory_usage'; +import StatusIcon from './mr_widget_status_icon'; import MRWidgetService from '../services/mr_widget_service'; export default { @@ -13,11 +13,7 @@ export default { }, components: { 'mr-widget-memory-usage': MemoryUsage, - }, - computed: { - svg() { - return statusIconEntityMap.icon_status_success; - }, + 'status-icon': StatusIcon, }, methods: { formatDate(date) { @@ -51,51 +47,51 @@ export default { }, }, template: ` - <div class="mr-widget-heading"> + <div class="mr-widget-heading deploy-heading"> <div v-for="deployment in mr.deployments"> - <div class="ci-widget"> + <div class="ci-widget media"> <div class="ci-status-icon ci-status-icon-success"> <span class="js-icon-link icon-link"> - <span class="ci-status-icon" - v-html="svg" - aria-hidden="true"></span> + <status-icon status="success" /> </span> </div> - <span> - <span - v-if="hasDeploymentMeta(deployment)"> - Deployed to - </span> - <a - v-if="hasDeploymentMeta(deployment)" - :href="deployment.url" - target="_blank" - rel="noopener noreferrer nofollow" - class="js-deploy-meta"> - {{deployment.name}} - </a> - <span - v-if="hasExternalUrls(deployment)"> - on - </span> - <a - v-if="hasExternalUrls(deployment)" - :href="deployment.external_url" - target="_blank" - rel="noopener noreferrer nofollow" - class="js-deploy-url"> - <i - class="fa fa-external-link" - aria-hidden="true" /> - {{deployment.external_url_formatted}} - </a> - <span - v-if="hasDeploymentTime(deployment)" - :data-title="deployment.deployed_at_formatted" - class="js-deploy-time" - data-toggle="tooltip" - data-placement="top"> - {{formatDate(deployment.deployed_at)}} + <div class="media-body space-children"> + <span> + <span + v-if="hasDeploymentMeta(deployment)"> + Deployed to + </span> + <a + v-if="hasDeploymentMeta(deployment)" + :href="deployment.url" + target="_blank" + rel="noopener noreferrer nofollow" + class="js-deploy-meta inline"> + {{deployment.name}} + </a> + <span + v-if="hasExternalUrls(deployment)"> + on + </span> + <a + v-if="hasExternalUrls(deployment)" + :href="deployment.external_url" + target="_blank" + rel="noopener noreferrer nofollow" + class="js-deploy-url inline"> + <i + class="fa fa-external-link" + aria-hidden="true" /> + {{deployment.external_url_formatted}} + </a> + <span + v-if="hasDeploymentTime(deployment)" + :data-title="deployment.deployed_at_formatted" + class="js-deploy-time" + data-toggle="tooltip" + data-placement="top"> + {{formatDate(deployment.deployed_at)}} + </span> </span> <button type="button" @@ -104,13 +100,13 @@ export default { class="btn btn-default btn-xs"> Stop environment </button> - </span> + <mr-widget-memory-usage + v-if="deployment.metrics_url" + :metrics-url="deployment.metrics_url" + :metrics-monitoring-url="deployment.metrics_monitoring_url" + /> + </div> </div> - <mr-widget-memory-usage - v-if="deployment.metrics_url" - :metrics-url="deployment.metrics_url" - :metrics-monitoring-url="deployment.metrics_monitoring_url" - /> </div> </div> `, diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js index 8430548903cb022fe071bed0adba1875f94cda17..c05a76a3b4a54d0d57d01bdd0b10589efa43568b 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.js @@ -1,3 +1,4 @@ +import tooltip from '../../vue_shared/directives/tooltip'; import '../../lib/utils/text_utility'; export default { @@ -5,6 +6,9 @@ export default { props: { mr: { type: Object, required: true }, }, + directives: { + tooltip, + }, computed: { shouldShowCommitsBehindText() { return this.mr.divergedCommitsCount > 0; @@ -29,18 +33,51 @@ export default { }, template: ` <div class="mr-source-target"> - <div - v-if="mr.isOpen" - class="pull-right"> + <div class="normal"> + <strong> + Request to merge + <span + class="label-branch" + :class="{'label-truncated': isBranchTitleLong(mr.sourceBranch)}" + :title="isBranchTitleLong(mr.sourceBranch) ? mr.sourceBranch : ''" + data-placement="bottom" + :v-tooltip="isBranchTitleLong(mr.sourceBranch)" + v-html="mr.sourceBranchLink"></span> + <button + v-tooltip + class="btn btn-transparent btn-clipboard" + data-title="Copy branch name to clipboard" + :data-clipboard-text="branchNameClipboardData"> + <i + aria-hidden="true" + class="fa fa-clipboard"></i> + </button> + into + <span + class="label-branch" + :v-tooltip="isBranchTitleLong(mr.sourceBranch)" + :class="{'label-truncatedtooltip': isBranchTitleLong(mr.targetBranch)}" + :title="isBranchTitleLong(mr.targetBranch) ? mr.targetBranch : ''" + data-placement="bottom"> + <a :href="mr.targetBranchTreePath">{{mr.targetBranch}}</a> + </span> + </strong> + <span + v-if="shouldShowCommitsBehindText" + class="diverged-commits-count"> + (<a :href="mr.targetBranchPath">{{mr.divergedCommitsCount}} {{commitsText}} behind</a>) + </span> + </div> + <div v-if="mr.isOpen"> <a href="#modal_merge_info" data-toggle="modal" - class="btn inline btn-grouped btn-sm"> + class="btn btn-small inline"> Check out branch </a> - <span class="dropdown inline prepend-left-5"> + <span class="dropdown inline prepend-left-10"> <a - class="btn btn-sm dropdown-toggle" + class="btn btn-xs dropdown-toggle" data-toggle="dropdown" aria-label="Download as" role="button"> @@ -69,38 +106,6 @@ export default { </ul> </span> </div> - <div class="normal"> - <strong> - Request to merge - <span - class="label-branch" - :class="{'label-truncated has-tooltip': isBranchTitleLong(mr.sourceBranch)}" - :title="isBranchTitleLong(mr.sourceBranch) ? mr.sourceBranch : ''" - data-placement="bottom" - v-html="mr.sourceBranchLink"></span> - <button - class="btn btn-transparent btn-clipboard has-tooltip" - data-title="Copy branch name to clipboard" - :data-clipboard-text="branchNameClipboardData"> - <i - aria-hidden="true" - class="fa fa-clipboard"></i> - </button> - into - <span - class="label-branch" - :class="{'label-truncated has-tooltip': isBranchTitleLong(mr.targetBranch)}" - :title="isBranchTitleLong(mr.targetBranch) ? mr.targetBranch : ''" - data-placement="bottom"> - <a :href="mr.targetBranchTreePath">{{mr.targetBranch}}</a> - </span> - </strong> - <span - v-if="shouldShowCommitsBehindText" - class="diverged-commits-count"> - (<a :href="mr.targetBranchPath">{{mr.divergedCommitsCount}} {{commitsText}} behind</a>) - </span> - </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js index 534e2a88effb06f3169598e15f179d592efb2bb5..a4e34116c3388eceb49be9783d02942e266efb63 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_memory_usage.js @@ -120,13 +120,12 @@ export default { }, template: ` <div class="mr-info-list clearfix mr-memory-usage js-mr-memory-usage"> - <div class="legend"></div> <p v-if="shouldShowLoading" class="usage-info js-usage-info usage-info-loading"> <i class="fa fa-spinner fa-spin usage-info-load-spinner" - aria-hidden="true" />Loading deployment statistics. + aria-hidden="true" />Loading deployment statistics </p> <p v-if="shouldShowMemoryGraph" @@ -136,12 +135,12 @@ export default { <p v-if="shouldShowLoadFailure" class="usage-info js-usage-info usage-info-failed"> - Failed to load deployment statistics. + Failed to load deployment statistics </p> <p v-if="shouldShowMetricsUnavailable" class="usage-info js-usage-info usage-info-unavailable"> - Deployment statistics are not available currently. + Deployment statistics are not available currently </p> <mr-memory-graph v-if="shouldShowMemoryGraph" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.js index 2fecebce7a0f9db5b884c9ab508d54cc816e7e12..1d9f9863dd9b3578988c25d4fa123d64c6b7d58c 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_merge_help.js @@ -16,7 +16,7 @@ export default { <a data-toggle="modal" href="#modal_merge_info"> - command line. + command line </a> </section> `, diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js index c02e10128e2bb22c810b891ed8feaf7bb08e8f96..6c2e9ba1d30c0cea042b25c192ae0d5e3ab53c13 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js @@ -29,58 +29,55 @@ export default { }, template: ` <div class="mr-widget-heading"> - <div class="ci-widget"> + <div class="ci-widget media"> <template v-if="hasCIError"> - <div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error"> - <span class="js-icon-link icon-link"> - <span - v-html="svg" - aria-hidden="true"></span> - </span> + <div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error append-right-10"> + <span + v-html="svg" + aria-hidden="true"></span> + </div> + <div class="media-body"> + Could not connect to the CI server. Please check your settings and try again </div> - <span>Could not connect to the CI server. Please check your settings and try again.</span> </template> <template v-else> - <div> + <div class="ci-status-icon append-right-10"> <a class="icon-link" :href="this.status.details_path"> <ci-icon :status="status" /> </a> </div> - <span> - Pipeline - <a - :href="mr.pipeline.path" - class="pipeline-id">#{{mr.pipeline.id}}</a> - {{mr.pipeline.details.status.label}} - </span> - <span - v-if="mr.pipeline.details.stages.length > 0"> - with {{stageText}} - </span> - <div class="mr-widget-pipeline-graph"> - <div class="stage-cell"> - <div - v-if="mr.pipeline.details.stages.length > 0" - v-for="stage in mr.pipeline.details.stages" - class="stage-container dropdown js-mini-pipeline-graph"> - <pipeline-stage :stage="stage" /> - </div> - </div> + <div class="media-body"> + <span> + Pipeline + <a + :href="mr.pipeline.path" + class="pipeline-id">#{{mr.pipeline.id}}</a> + </span> + <span class="mr-widget-pipeline-graph"> + <span class="stage-cell"> + <div + v-if="mr.pipeline.details.stages.length > 0" + v-for="stage in mr.pipeline.details.stages" + class="stage-container dropdown js-mini-pipeline-graph"> + <pipeline-stage :stage="stage" /> + </div> + </span> + </span> + <span> + {{mr.pipeline.details.status.label}} for + <a + :href="mr.pipeline.commit.commit_path" + class="commit-sha js-commit-link"> + {{mr.pipeline.commit.short_id}}</a>. + </span> + <span + v-if="mr.pipeline.coverage" + class="js-mr-coverage"> + Coverage {{mr.pipeline.coverage}}% + </span> </div> - <span> - for - <a - :href="mr.pipeline.commit.commit_path" - class="commit-sha js-commit-link"> - {{mr.pipeline.commit.short_id}}</a>. - </span> - <span - v-if="mr.pipeline.coverage" - class="js-mr-coverage"> - Coverage {{mr.pipeline.coverage}}%. - </span> </template> </div> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.js index 205804670fa473de6d573ea41d9bbbcb579a946b..563267ad044e7ec7f367d9d49a70c1381c6ed2f4 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.js @@ -2,37 +2,32 @@ export default { name: 'MRWidgetRelatedLinks', props: { relatedLinks: { type: Object, required: true }, + state: { type: String, required: false }, }, computed: { hasLinks() { const { closing, mentioned, assignToMe } = this.relatedLinks; return closing || mentioned || assignToMe; }, - }, - methods: { - hasMultipleIssues(text) { - return !text ? false : text.match(/<\/a> and <a/); - }, - issueLabel(field) { - return this.hasMultipleIssues(this.relatedLinks[field]) ? 'issues' : 'issue'; - }, - verbLabel(field) { - return this.hasMultipleIssues(this.relatedLinks[field]) ? 'are' : 'is'; + closesText() { + if (this.state === 'merged') { + return 'Closed'; + } + if (this.state === 'closed') { + return 'Did not close'; + } + return 'Closes'; }, }, template: ` <section v-if="hasLinks" class="mr-info-list mr-links"> - <div class="legend"></div> <p v-if="relatedLinks.closing"> - Closes {{issueLabel('closing')}} - <span v-html="relatedLinks.closing"></span>. + {{closesText}} <span v-html="relatedLinks.closing"></span> </p> <p v-if="relatedLinks.mentioned"> - <span class="capitalize">{{issueLabel('mentioned')}}</span> - <span v-html="relatedLinks.mentioned"></span> - {{verbLabel('mentioned')}} mentioned but will not be closed. + Mentions <span v-html="relatedLinks.mentioned"></span> </p> <p v-if="relatedLinks.assignToMe"> <span v-html="relatedLinks.assignToMe"></span> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.js new file mode 100644 index 0000000000000000000000000000000000000000..b01c923311b1994b88b27eb158673571b931bb71 --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.js @@ -0,0 +1,36 @@ +import ciIcon from '../../vue_shared/components/ci_icon.vue'; +import loadingIcon from '../../vue_shared/components/loading_icon.vue'; + +export default { + props: { + status: { type: String, required: true }, + showDisabledButton: { type: Boolean, required: false }, + }, + components: { + ciIcon, + loadingIcon, + }, + computed: { + statusObj() { + return { + group: this.status, + icon: `icon_status_${this.status}`, + }; + }, + }, + template: ` + <div class="space-children flex-container-block append-right-10"> + <div v-if="status === 'loading'" class="mr-widget-icon"> + <loading-icon /> + </div> + <ci-icon v-else :status="statusObj" /> + <button + v-if="showDisabledButton" + type="button" + class="btn btn-success btn-small" + disabled="true"> + Merge + </button> + </div> + `, +}; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js index c7f25a1697c358bca012cffb447f06ce755fa5dd..2b16a2d68171f34968b998ae0dcef6c71214d000 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_archived.js @@ -1,16 +1,26 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetArchived', + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge - </button> - <span class="bold"> - This project is archived, write access has been disabled. - </span> + <div class="mr-widget-body media"> + <div class="space-children"> + <status-icon status="failed" /> + <button + type="button" + class="btn btn-success btn-small" + disabled="true"> + Merge + </button> + </div> + <div class="media-body"> + <span class="bold"> + This project is archived, write access has been disabled + </span> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.js index 4063859d5d0b5688610e710e0c29574782ac318f..5648208f7b12abfc9454ca3190201ae6cd4f687f 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.js @@ -1,4 +1,5 @@ import eventHub from '../../event_hub'; +import statusIcon from '../mr_widget_status_icon'; export default { name: 'MRWidgetAutoMergeFailed', @@ -10,6 +11,9 @@ export default { isRefreshing: false, }; }, + components: { + statusIcon, + }, methods: { refreshWidget() { this.isRefreshing = true; @@ -19,18 +23,16 @@ export default { }, }, template: ` - <div class="mr-widget-body"> - <button - class="btn btn-success btn-small" - disabled="true" - type="button"> - Merge - </button> - <span class="bold danger"> - This merge request failed to be merged automatically. + <div class="mr-widget-body media"> + <status-icon status="failed" /> + <div class="media-body space-children"> + <span class="bold"> + <template v-if="mr.mergeError">{{mr.mergeError}}.</template> + This merge request failed to be merged automatically + </span> <button @click="refreshWidget" - :class="{ disabled: isRefreshing }" + :disabled="isRefreshing" type="button" class="btn btn-xs btn-default"> <i @@ -39,9 +41,6 @@ export default { aria-hidden="true" /> Refresh </button> - </span> - <div class="merge-error-text danger bold"> - {{mr.mergeError}} </div> </div> `, diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.js index 8515b54e62dc540803f197b78f90b1bb64c19f97..aaf9d3304a43cd1a74ee1336dcb5156edc9544fd 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_checking.js @@ -1,19 +1,18 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetChecking', + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge - </button> - <span class="bold"> - Checking ability to merge automatically. - <i - class="fa fa-spinner fa-spin" - aria-hidden="true" /> - </span> + <div class="mr-widget-body media"> + <status-icon status="loading" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold"> + Checking ability to merge automatically + </span> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.js index fc2e42c6821def001ae01e6b02ef40476865972a..4078aad7f83c8055f3e8a9df7d9f92d64cf86e22 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_closed.js @@ -1,4 +1,5 @@ import mrWidgetAuthorTime from '../../components/mr_widget_author_time'; +import statusIcon from '../mr_widget_status_icon'; export default { name: 'MRWidgetClosed', @@ -7,24 +8,28 @@ export default { }, components: { 'mr-widget-author-and-time': mrWidgetAuthorTime, + statusIcon, }, template: ` - <div class="mr-widget-body"> - <mr-widget-author-and-time - actionText="Closed by" - :author="mr.closedBy" - :dateTitle="mr.updatedAt" - :dateReadable="mr.closedAt" - /> - <section> - <p> - The changes were not merged into - <a - :href="mr.targetBranchPath" - class="label-branch"> - {{mr.targetBranch}}</a>. - </p> - </section> + <div class="mr-widget-body media"> + <status-icon status="failed" /> + <div class="media-body"> + <mr-widget-author-and-time + actionText="Closed by" + :author="mr.closedBy" + :dateTitle="mr.updatedAt" + :dateReadable="mr.closedAt" + /> + <section class="mr-info-list"> + <p> + The changes were not merged into + <a + :href="mr.targetBranchPath" + class="label-branch"> + {{mr.targetBranch}}</a> + </p> + </section> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js index 36596c6f37e753c63fabafeeacd7a1516229b5c6..f9cb79a0bc12d47b5da9ec3be8764a4208d42c2f 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.js @@ -1,27 +1,25 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetConflicts', props: { mr: { type: Object, required: true }, }, + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge - </button> - <span class="bold"> - There are merge conflicts. - <span v-if="!mr.canMerge"> - Resolve these conflicts or ask someone with write access to this repository to merge it locally. + <div class="mr-widget-body media"> + <status-icon status="failed" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold"> + There are merge conflicts<span v-if="!mr.canMerge">.</span> + <span v-if="!mr.canMerge"> + Resolve these conflicts or ask someone with write access to this repository to merge it locally + </span> </span> - </span> - <div - v-if="mr.canMerge" - class="btn-group"> <a - v-if="mr.conflictResolutionPath" + v-if="mr.canMerge && mr.conflictResolutionPath" :href="mr.conflictResolutionPath" class="btn btn-default btn-xs js-resolve-conflicts-button"> Resolve conflicts diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.js index 600b4d42e3d445ec89ff6c0c800a2ef7597efcf9..1cb24549d53cf6ec3153752c0f0d0b2a8dcd8a96 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.js @@ -1,3 +1,4 @@ +import statusIcon from '../mr_widget_status_icon'; import eventHub from '../../event_hub'; export default { @@ -38,39 +39,40 @@ export default { } }, }, + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - class="btn btn-success btn-small" - disabled="true" - type="button"> - Merge - </button> - <span - v-if="!isRefreshing" - class="bold danger"> - <span - class="has-error-message" - v-if="mr.mergeError"> - {{mr.mergeError}} - </span> - <span v-else>Merge failed.</span> - <span - :class="{ 'has-custom-error': mr.mergeError }"> - Refreshing in {{timerText}} to show the updated status... + <div class="mr-widget-body media"> + <template v-if="isRefreshing"> + <status-icon status="loading" /> + <span class="media-body bold js-refresh-label"> + Refreshing now </span> - <button - @click="refresh" - class="btn btn-default btn-xs js-refresh-button" - type="button"> - Refresh now - </button> - </span> - <span - v-if="isRefreshing" - class="bold js-refresh-label"> - Refreshing now... - </span> + </template> + <template v-else> + <status-icon status="failed" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold"> + <span + class="has-error-message" + v-if="mr.mergeError"> + {{mr.mergeError}}. + </span> + <span v-else>Merge failed.</span> + <span + :class="{ 'has-custom-error': mr.mergeError }"> + Refreshing in {{timerText}} to show the updated status... + </span> + </span> + <button + @click="refresh" + class="btn btn-default btn-xs js-refresh-button" + type="button"> + Refresh now + </button> + </div> + </template> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_locked.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_locked.js index 0bd31731a0b051f5faf8d192d8730d76bd3bc5bc..a12f418e1af73ef7154b021c34f7dffb5624e915 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_locked.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_locked.js @@ -1,24 +1,29 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetLocked', props: { mr: { type: Object, required: true }, }, + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body mr-state-locked"> - <span class="state-label">Locked</span> - This merge request is in the process of being merged, during which time it is locked and cannot be closed. - <i - class="fa fa-spinner fa-spin" - aria-hidden="true" /> - <section class="mr-info-list mr-links"> - <div class="legend"></div> - <p> - The changes will be merged into - <span class="label-branch"> - <a :href="mr.targetBranchPath">{{mr.targetBranch}}</a> - </span>. - </p> - </section> + <div class="mr-widget-body mr-state-locked media"> + <status-icon status="loading" /> + <div class="media-body"> + <h4> + This merge request is in the process of being merged, during which time it is locked and cannot be closed + </h4> + <section class="mr-info-list"> + <p> + The changes will be merged into + <span class="label-branch"> + <a :href="mr.targetBranchPath">{{mr.targetBranch}}</a> + </span> + </p> + </section> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.js index 419d174f3ff5ea90f52c107a4beef374520079fd..bdfd4d9667cbfd1561776c74dd1708f1f9d28a12 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.js @@ -1,5 +1,5 @@ /* global Flash */ - +import statusIcon from '../mr_widget_status_icon'; import MRWidgetAuthor from '../../components/mr_widget_author'; import eventHub from '../../event_hub'; @@ -11,6 +11,7 @@ export default { }, components: { 'mr-widget-author': MRWidgetAuthor, + statusIcon, }, data() { return { @@ -61,56 +62,56 @@ export default { }, }, template: ` - <div class="mr-widget-body"> - <h4> - Set by - <mr-widget-author :author="mr.setToMWPSBy" /> - to be merged automatically when the pipeline succeeds. - <a - v-if="mr.canCancelAutomaticMerge" - @click.prevent="cancelAutomaticMerge" - :disabled="isCancellingAutoMerge" - role="button" - href="#" - class="btn btn-xs btn-default js-cancel-auto-merge"> - <i - v-if="isCancellingAutoMerge" - class="fa fa-spinner fa-spin" - aria-hidden="true" /> - Cancel automatic merge - </a> - </h4> - <section class="mr-info-list"> - <div class="legend"></div> - <p>The changes will be merged into - <a - :href="mr.targetBranchPath" - class="label-branch"> - {{mr.targetBranch}} - </a>. - </p> - <p v-if="mr.shouldRemoveSourceBranch"> - The source branch will be removed. - </p> - <p - v-else - class="with-button"> - The source branch will not be removed. + <div class="mr-widget-body media"> + <status-icon status="success" /> + <div class="media-body"> + <h4> + Set by + <mr-widget-author :author="mr.setToMWPSBy" /> + to be merged automatically when the pipeline succeeds <a - v-if="canRemoveSourceBranch" - :disabled="isRemovingSourceBranch" - @click.prevent="removeSourceBranch" + v-if="mr.canCancelAutomaticMerge" + @click.prevent="cancelAutomaticMerge" + :disabled="isCancellingAutoMerge" role="button" - class="btn btn-xs btn-default js-remove-source-branch" - href="#"> + href="#" + class="btn btn-xs btn-default js-cancel-auto-merge"> <i - v-if="isRemovingSourceBranch" - class="fa fa-spinner fa-spin" - aria-hidden="true" /> - Remove source branch + v-if="isCancellingAutoMerge" + class="fa fa-spinner fa-spin" + aria-hidden="true" /> + Cancel automatic merge </a> - </p> - </section> + </h4> + <section class="mr-info-list"> + <p>The changes will be merged into + <a + :href="mr.targetBranchPath" + class="label-branch"> + {{mr.targetBranch}} + </a> + </p> + <p v-if="mr.shouldRemoveSourceBranch"> + The source branch will be removed + </p> + <p v-else> + The source branch will not be removed + <a + v-if="canRemoveSourceBranch" + :disabled="isRemovingSourceBranch" + @click.prevent="removeSourceBranch" + role="button" + class="btn btn-xs btn-default js-remove-source-branch" + href="#"> + <i + v-if="isRemovingSourceBranch" + class="fa fa-spinner fa-spin" + aria-hidden="true" /> + Remove source branch + </a> + </p> + </section> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.js index c7d32d181411a90a048e25b73862619c576625f9..e452260a4d0cccd932473cd1a9f840e52c07713f 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merged.js @@ -1,6 +1,9 @@ /* global Flash */ import mrWidgetAuthorTime from '../../components/mr_widget_author_time'; +import tooltip from '../../../vue_shared/directives/tooltip'; +import loadingIcon from '../../../vue_shared/components/loading_icon.vue'; +import statusIcon from '../mr_widget_status_icon'; import eventHub from '../../event_hub'; export default { @@ -9,14 +12,19 @@ export default { mr: { type: Object, required: true }, service: { type: Object, required: true }, }, - components: { - 'mr-widget-author-and-time': mrWidgetAuthorTime, - }, data() { return { isMakingRequest: false, }; }, + directives: { + tooltip, + }, + components: { + 'mr-widget-author-and-time': mrWidgetAuthorTime, + loadingIcon, + statusIcon, + }, computed: { shouldShowRemoveSourceBranch() { const { sourceBranchRemoved, isRemovingSourceBranch, canRemoveSourceBranch } = this.mr; @@ -55,75 +63,77 @@ export default { }, }, template: ` - <div class="mr-widget-body"> - <mr-widget-author-and-time - actionText="Merged by" - :author="mr.mergedBy" - :dateTitle="mr.updatedAt" - :dateReadable="mr.mergedAt" /> - <section class="mr-info-list"> - <div class="legend"></div> - <p> - The changes were merged into - <span class="label-branch"> - <a :href="mr.targetBranchPath">{{mr.targetBranch}}</a> - </span> - </p> - <p v-if="mr.sourceBranchRemoved">The source branch has been removed.</p> - <p v-if="shouldShowRemoveSourceBranch"> - You can remove source branch now. - <button - @click="removeSourceBranch" - :class="{ disabled: isMakingRequest }" - type="button" - class="btn btn-xs btn-default js-remove-branch-button"> - Remove Source Branch - </button> - </p> - <p v-if="shouldShowSourceBranchRemoving"> - <i - class="fa fa-spinner fa-spin" - aria-hidden="true" /> - The source branch is being removed. - </p> - </section> - <div - v-if="shouldShowMergedButtons" - class="merged-buttons clearfix"> - <a - v-if="mr.canRevertInCurrentMR" - class="btn btn-close btn-sm has-tooltip" - href="#modal-revert-commit" - data-toggle="modal" - data-container="body" - title="Revert this merge request in a new merge request"> - Revert - </a> - <a - v-else-if="mr.revertInForkPath" - class="btn btn-close btn-sm has-tooltip" - data-method="post" - :href="mr.revertInForkPath" - title="Revert this merge request in a new merge request"> - Revert - </a> - <a - v-if="mr.canCherryPickInCurrentMR" - class="btn btn-default btn-sm has-tooltip" - href="#modal-cherry-pick-commit" - data-toggle="modal" - data-container="body" - title="Cherry-pick this merge request in a new merge request"> - Cherry-pick - </a> - <a - v-else-if="mr.cherryPickInForkPath" - class="btn btn-default btn-sm has-tooltip" - data-method="post" - :href="mr.cherryPickInForkPath" - title="Cherry-pick this merge request in a new merge request"> - Cherry-pick - </a> + <div class="mr-widget-body media"> + <status-icon status="success" /> + <div class="media-body"> + <div class="space-children"> + <mr-widget-author-and-time + actionText="Merged by" + :author="mr.mergedBy" + :dateTitle="mr.updatedAt" + :dateReadable="mr.mergedAt" /> + <a + v-if="mr.canRevertInCurrentMR" + v-tooltip + class="btn btn-close btn-xs" + href="#modal-revert-commit" + data-toggle="modal" + data-container="body" + title="Revert this merge request in a new merge request"> + Revert + </a> + <a + v-else-if="mr.revertInForkPath" + v-tooltip + class="btn btn-close btn-xs" + data-method="post" + :href="mr.revertInForkPath" + title="Revert this merge request in a new merge request"> + Revert + </a> + <a + v-if="mr.canCherryPickInCurrentMR" + v-tooltip + class="btn btn-default btn-xs" + href="#modal-cherry-pick-commit" + data-toggle="modal" + data-container="body" + title="Cherry-pick this merge request in a new merge request"> + Cherry-pick + </a> + <a + v-else-if="mr.cherryPickInForkPath" + v-tooltip + class="btn btn-default btn-xs" + data-method="post" + :href="mr.cherryPickInForkPath" + title="Cherry-pick this merge request in a new merge request"> + Cherry-pick + </a> + </div> + <section class="mr-info-list"> + <p> + The changes were merged into + <span class="label-branch"> + <a :href="mr.targetBranchPath">{{mr.targetBranch}}</a> + </span> + </p> + <p v-if="mr.sourceBranchRemoved">The source branch has been removed</p> + <p v-if="shouldShowRemoveSourceBranch" class="space-children"> + <span>You can remove source branch now</span> + <button + @click="removeSourceBranch" + :disabled="isMakingRequest" + type="button" + class="btn btn-xs btn-default js-remove-branch-button"> + Remove Source Branch + </button> + </p> + <p v-if="shouldShowSourceBranchRemoving"> + <loading-icon inline /> + <span>The source branch is being removed</span> + </p> + </section> </div> </div> `, diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.js index 328382485f65a1b1949c0337e356707554c4ee98..9f0a359d01a06ce86e5ebab84a3465d3f2c47674 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_missing_branch.js @@ -1,3 +1,5 @@ +import statusIcon from '../mr_widget_status_icon'; +import tooltip from '../../../vue_shared/directives/tooltip'; import mrWidgetMergeHelp from '../../components/mr_widget_merge_help'; export default { @@ -5,30 +7,37 @@ export default { props: { mr: { type: Object, required: true }, }, + directives: { + tooltip, + }, components: { 'mr-widget-merge-help': mrWidgetMergeHelp, + statusIcon, }, computed: { missingBranchName() { return this.mr.sourceBranchRemoved ? 'source' : 'target'; }, + message() { + return `If the ${this.missingBranchName} branch exists in your local repository, you can merge this merge request manually using the command line`; + }, }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge - </button> - <span class="bold js-branch-text"> - <span class="capitalize"> - {{missingBranchName}} - </span> branch does not exist. - Please restore the {{missingBranchName}} branch or use a different {{missingBranchName}} branch. - </span> - <mr-widget-merge-help - :missing-branch="missingBranchName" /> + <div class="mr-widget-body media"> + <status-icon status="failed" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold js-branch-text"> + <span class="capitalize"> + {{missingBranchName}} + </span> branch does not exist. + Please restore it or use a different {{missingBranchName}} branch + <i + v-tooltip + class="fa fa-question-circle" + :title="message" + :aria-label="message"></i> + </span> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_not_allowed.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_not_allowed.js index 07169b349be4e9a0d9da1e7d85b6bf753f33d3a5..797511d4e3a40c84ef8af2ab9d08eb20bdd1b321 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_not_allowed.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_not_allowed.js @@ -1,17 +1,19 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetNotAllowed', + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge - </button> - <span class="bold"> - Ready to be merged automatically. - Ask someone with write access to this repository to merge this request. - </span> + <div class="mr-widget-body media"> + <status-icon status="success" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold"> + Ready to be merged automatically. + Ask someone with write access to this repository to merge this request + </span> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_nothing_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_nothing_to_merge.js index 375a382615aeece6a7a4732fce4cac14d0be36ff..ebfd6765934a5fe61bc23bc60c1526bfb2b09406 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_nothing_to_merge.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_nothing_to_merge.js @@ -12,7 +12,7 @@ export default { return { emptyStateSVG }; }, template: ` - <div class="mr-widget-body empty-state"> + <div class="mr-widget-body mr-widget-empty-state"> <div class="row"> <div class="artwork col-sm-5 col-sm-push-7 col-xs-12 text-center"> <span v-html="emptyStateSVG"></span> @@ -29,12 +29,14 @@ export default { Currently there are no changes in this merge request's source branch. Please push new commits or use a different branch. </p> - <a - v-if="mr.newBlobPath" - :href="mr.newBlobPath" - class="btn btn-inverted btn-save"> - Create file - </a> + <div> + <a + v-if="mr.newBlobPath" + :href="mr.newBlobPath" + class="btn btn-inverted btn-save"> + Create file + </a> + </div> </div> </div> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.js index 31c53b679edb58129445b20026dfaa9d048ea0c9..167a0d4613aae041e72f26f20f6d0c5602727842 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_blocked.js @@ -1,16 +1,18 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetPipelineBlocked', + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge - </button> - <span class="bold"> - Pipeline blocked. The pipeline for this merge request requires a manual action to proceed. - </span> + <div class="mr-widget-body media"> + <status-icon status="failed" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold"> + Pipeline blocked. The pipeline for this merge request requires a manual action to proceed + </span> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_failed.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_failed.js index 002820123ca17ce7957dc14255dcfe632c115ecc..c5be9a0530a89a8d4cf3248ce4066e9f733b8f82 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_failed.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_pipeline_failed.js @@ -1,16 +1,18 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetPipelineBlocked', + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - class="btn btn-success btn-small" - disabled="true" - type="button"> - Merge - </button> - <span class="bold"> - The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure. - </span> + <div class="mr-widget-body media"> + <status-icon status="failed" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold"> + The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure + </span> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js index fcd4fdaf09f64a97dd1e74939c52a2677e3980ae..651877540096e5ce3bc7c6a95f2a29067e835438 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_ready_to_merge.js @@ -1,8 +1,8 @@ /* global Flash */ - import successSvg from 'icons/_icon_status_success.svg'; import warningSvg from 'icons/_icon_status_warning.svg'; import simplePoll from '~/lib/utils/simple_poll'; +import statusIcon from '../mr_widget_status_icon'; import eventHub from '../../event_hub'; export default { @@ -25,6 +25,9 @@ export default { warningSvg, }; }, + components: { + statusIcon, + }, computed: { commitMessageLinkTitle() { const withDesc = 'Include description in commit message'; @@ -196,84 +199,98 @@ export default { }, }, template: ` - <div class="mr-widget-body"> - <span class="btn-group"> - <button - @click="handleMergeButtonClick()" - :disabled="isMergeButtonDisabled" - :class="mergeButtonClass" - type="button"> - <i - v-if="isMakingRequest" - class="fa fa-spinner fa-spin" - aria-hidden="true" /> - {{mergeButtonText}} - </button> - <button - v-if="shouldShowMergeOptionsDropdown" - :disabled="isMergeButtonDisabled" - type="button" - class="btn btn-small btn-info dropdown-toggle" - data-toggle="dropdown"> - <i - class="fa fa-caret-down" - aria-hidden="true" /> - <span class="sr-only"> - Select merge moment + <div class="mr-widget-body media"> + <status-icon status="success" /> + <div class="media-body"> + <div class="media space-children"> + <span class="btn-group"> + <button + @click="handleMergeButtonClick()" + :disabled="isMergeButtonDisabled" + :class="mergeButtonClass" + type="button"> + <i + v-if="isMakingRequest" + class="fa fa-spinner fa-spin" + aria-hidden="true" /> + {{mergeButtonText}} + </button> + <button + v-if="shouldShowMergeOptionsDropdown" + :disabled="isMergeButtonDisabled" + type="button" + class="btn btn-small btn-info dropdown-toggle js-merge-moment" + data-toggle="dropdown" + aria-label="Select merge moment"> + <i + class="fa fa-chevron-down" + aria-hidden="true" /> + </button> + <ul + v-if="shouldShowMergeOptionsDropdown" + class="dropdown-menu dropdown-menu-right" + role="menu"> + <li> + <a + @click.prevent="handleMergeButtonClick(true)" + class="merge_when_pipeline_succeeds" + href="#"> + <span class="media"> + <span + v-html="successSvg" + class="merge-opt-icon" + aria-hidden="true"></span> + <span class="media-body merge-opt-title">Merge when pipeline succeeds</span> + </span> + </a> + </li> + <li> + <a + @click.prevent="handleMergeButtonClick(false, true)" + class="accept-merge-request" + href="#"> + <span class="media"> + <span + v-html="warningSvg" + class="merge-opt-icon" + aria-hidden="true"></span> + <span class="media-body merge-opt-title">Merge immediately</span> + </span> + </a> + </li> + </ul> </span> - </button> - <ul - v-if="shouldShowMergeOptionsDropdown" - class="dropdown-menu dropdown-menu-right" - role="menu"> - <li> - <a - @click.prevent="handleMergeButtonClick(true)" - class="merge_when_pipeline_succeeds" - href="#"> - <span - v-html="successSvg" - class="merge-opt-icon" - aria-hidden="true"></span> - <span class="merge-opt-title">Merge when pipeline succeeds</span> - </a> - </li> - <li> - <a - @click.prevent="handleMergeButtonClick(false, true)" - class="accept-merge-request" - href="#"> - <span - v-html="warningSvg" - class="merge-opt-icon" - aria-hidden="true"></span> - <span class="merge-opt-title">Merge immediately</span> - </a> - </li> - </ul> - </span> - <template v-if="isMergeAllowed()"> - <label class="spacing"> - <input - id="remove-source-branch-input" - v-model="removeSourceBranch" - :disabled="isRemoveSourceBranchButtonDisabled" - type="checkbox"/> Remove source branch - </label> + <div class="media-body space-children"> + <template v-if="isMergeAllowed()"> + <label> + <input + id="remove-source-branch-input" + v-model="removeSourceBranch" + :disabled="isRemoveSourceBranchButtonDisabled" + type="checkbox"/> Remove source branch + </label> - <!-- Placeholder for EE extension of this component --> - <squash-before-merge - v-if="shouldShowSquashBeforeMerge" - :mr="mr" - :is-merge-button-disabled="isMergeButtonDisabled" /> + <!-- Placeholder for EE extension of this component --> + <squash-before-merge + v-if="shouldShowSquashBeforeMerge" + :mr="mr" + :is-merge-button-disabled="isMergeButtonDisabled" /> - <button - @click="toggleCommitMessageEditor" - :disabled="isMergeButtonDisabled" - class="btn btn-default btn-xs" - type="button"> - Modify commit message - </button> + <button + @click="toggleCommitMessageEditor" + :disabled="isMergeButtonDisabled" + class="btn btn-default btn-xs" + type="button"> + Modify commit message + </button> + </template> + <template v-else> + <span class="bold"> + The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure + </span> + </template> + </div> + </div> <div v-if="showCommitMessageEditor" class="prepend-top-default commit-message-editor"> @@ -293,7 +310,7 @@ export default { rows="14" name="Commit message"></textarea> </div> - <p class="hint">Try to keep the first line under 52 characters and the others under 72.</p> + <p class="hint">Try to keep the first line under 52 characters and the others under 72</p> <div class="hint"> <a @click.prevent="updateCommitMessage" @@ -302,12 +319,7 @@ export default { </div> </div> </div> - </template> - <template v-else> - <span class="bold"> - The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure. - </span> - </template> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_sha_mismatch.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_sha_mismatch.js index 79f8ef408e6860c568cb0bc82b6ea7c0000feb1f..89f38e5bd2a02019b9e43952c3c2f765e390e957 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_sha_mismatch.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_sha_mismatch.js @@ -1,16 +1,18 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetSHAMismatch', + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge - </button> - <span class="bold"> - The source branch HEAD has recently changed. Please reload the page and review the changes before merging. - </span> + <div class="mr-widget-body media"> + <status-icon status="failed" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold"> + The source branch HEAD has recently changed. Please reload the page and review the changes before merging + </span> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_unresolved_discussions.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_unresolved_discussions.js index f4ab2d9fa5825b8c3919b6ce1f913c31c1a8f960..d762ca6e640c1ce2378855726c9ed1bd7e50216b 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_unresolved_discussions.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_unresolved_discussions.js @@ -1,27 +1,27 @@ +import statusIcon from '../mr_widget_status_icon'; + export default { name: 'MRWidgetUnresolvedDiscussions', props: { mr: { type: Object, required: true }, }, + components: { + statusIcon, + }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge - </button> - <span class="bold"> - There are unresolved discussions. Please resolve these discussions - <span v-if="mr.canCreateIssue">or</span> - <span v-else>.</span> - </span> - <a - v-if="mr.createIssueToResolveDiscussionsPath" - :href="mr.createIssueToResolveDiscussionsPath" - class="btn btn-default btn-xs js-create-issue"> - Create an issue to resolve them later - </a> + <div class="mr-widget-body media"> + <status-icon status="failed" showDisabledButton /> + <div class="media-body space-children"> + <span class="bold"> + There are unresolved discussions. Please resolve these discussions + </span> + <a + v-if="mr.createIssueToResolveDiscussionsPath" + :href="mr.createIssueToResolveDiscussionsPath" + class="btn btn-default btn-xs js-create-issue"> + Create an issue to resolve them later + </a> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_wip.js b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_wip.js index cb02ffe93bd970c04d6bd4cc3ce5e3362b469d0f..b11a06899cfc85b1dd321717866ce75eb756d277 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_wip.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_wip.js @@ -1,4 +1,6 @@ /* global Flash */ +import statusIcon from '../mr_widget_status_icon'; +import tooltip from '../../../vue_shared/directives/tooltip'; import eventHub from '../../event_hub'; export default { @@ -7,11 +9,17 @@ export default { mr: { type: Object, required: true }, service: { type: Object, required: true }, }, + directives: { + tooltip, + }, data() { return { isMakingRequest: false, }; }, + components: { + statusIcon, + }, methods: { removeWIP() { this.isMakingRequest = true; @@ -29,20 +37,20 @@ export default { }, }, template: ` - <div class="mr-widget-body"> - <button - type="button" - class="btn btn-success btn-small" - disabled="true"> - Merge</button> - <span class="bold"> - This merge request is currently Work In Progress and therefore unable to merge - </span> - <template v-if="mr.removeWIPPath"> - <i - class="fa fa-question-circle has-tooltip" - title="When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged." /> + <div class="mr-widget-body media"> + <status-icon status="failed" :showDisabledButton="Boolean(mr.removeWIPPath)" /> + <div class="media-body space-children"> + <span class="bold"> + This is a Work in Progress + <i + v-tooltip + class="fa fa-question-circle" + title="When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged" + aria-label="When this merge request is ready, remove the WIP: prefix from the title to allow it to be merged"> + </i> + </span> <button + v-if="mr.removeWIPPath" @click="removeWIP" :disabled="isMakingRequest" type="button" @@ -53,7 +61,7 @@ export default { aria-hidden="true" /> Resolve WIP status </button> - </template> + </div> </div> `, }; diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js index 2339a00ddd03384b3a3534dee903deb5247ef5b2..577d77f09a69ebee7129f6dd5365f45446e7b9a8 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js @@ -35,8 +35,14 @@ import { export default { el: '#js-vue-mr-widget', name: 'MRWidget', + props: { + mrData: { + type: Object, + required: false, + }, + }, data() { - const store = new MRWidgetStore(gl.mrWidgetData); + const store = new MRWidgetStore(this.mrData || window.gl.mrWidgetData); const service = this.createService(store); return { mr: store, @@ -234,14 +240,21 @@ export default { v-if="shouldRenderDeployments" :mr="mr" :service="service" /> - <component - :is="componentName" - :mr="mr" - :service="service" /> - <mr-widget-related-links - v-if="shouldRenderRelatedLinks" - :related-links="mr.relatedLinks" /> - <mr-widget-merge-help v-if="shouldRenderMergeHelp" /> + <div class="mr-widget-section"> + <component + :is="componentName" + :mr="mr" + :service="service" /> + <mr-widget-related-links + v-if="shouldRenderRelatedLinks" + :state="mr.state" + :related-links="mr.relatedLinks" /> + </div> + <div + class="mr-widget-footer" + v-if="shouldRenderMergeHelp"> + <mr-widget-merge-help /> + </div> </div> `, }; diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss index 6ce331a9129ee4abe9072e7bcfd9e37f90480be8..b2b3297e880ea1eb552dd918486866242bece373 100644 --- a/app/assets/stylesheets/framework.scss +++ b/app/assets/stylesheets/framework.scss @@ -26,6 +26,7 @@ @import "framework/lists"; @import "framework/logo"; @import "framework/markdown_area"; +@import "framework/media_object"; @import "framework/mobile"; @import "framework/modal"; @import "framework/nav"; diff --git a/app/assets/stylesheets/framework/media_object.scss b/app/assets/stylesheets/framework/media_object.scss new file mode 100644 index 0000000000000000000000000000000000000000..b573052c14affa5bdca02ac9e3e7a4168768925b --- /dev/null +++ b/app/assets/stylesheets/framework/media_object.scss @@ -0,0 +1,8 @@ +.media { + display: flex; + align-items: flex-start; +} + +.media-body { + flex: 1; +} diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 0df6f24bfe6e86bd8355fd65649967cb5a9ff1d7..1d0f10d6a326da8cc54155f9867fc58bacfdf9b9 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -206,7 +206,6 @@ $general-hover-transition-curve: linear; $highlight-changes-color: rgb(235, 255, 232); $performance-bar-height: 35px; - /* * Common component specific colors */ @@ -315,6 +314,12 @@ $btn-white-active: #848484; $badge-bg: rgba(0, 0, 0, 0.07); $badge-color: $gl-text-color-secondary; +/* + * Status icons + */ +$status-icon-size: 22px; +$status-icon-margin: $gl-btn-padding; + /* * Award emoji */ diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index a4e190945088c063dcccc827afccad5ffb46ca09..6bb013cca85655f2f4bc02f1a2d27beda82932d3 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -2,10 +2,35 @@ * MR -> show: Automerge widget * */ + +.space-children { + @include clearfix; + + > * { + float: left; + } + + > *:not(:last-child) { + margin-right: 10px; + } +} + .mr-state-widget { color: $gl-text-color; border: 1px solid $border-color; border-radius: 2px; + line-height: 28px; + + .mr-widget-heading, + .mr-widget-section, + .mr-widget-footer { + padding: $gl-padding; + border-top: solid 1px $border-color; + } + + .mr-widget-footer { + padding: 0; + } form { margin-bottom: 0; @@ -15,15 +40,35 @@ } } + label { + margin-bottom: 0; + } + + .btn { + font-size: $gl-font-size; + + &[disabled] { + opacity: 0.3; + } + + &.btn-xs { + line-height: 1; + padding: 5px 10px; + margin-top: 1px; + } + + &.dropdown-toggle { + .fa { + color: inherit; + } + } + } + .accept-merge-holder { .accept-action { display: inline-block; float: left; - .btn-success.dropdown-toggle .fa { - color: inherit; - } - .accept-merge-request { &.ci-pending, &.ci-running { @@ -84,77 +129,64 @@ .ci-widget { color: $gl-text-color; - display: -webkit-flex; display: flex; - -webkit-align-items: center; - align-items: center; - padding: $gl-padding-top $gl-padding 0; - - svg { - position: relative; - top: 1px; - overflow: visible; - } - - > span { - padding-right: 4px; - } @media (max-width: $screen-xs-max) { flex-wrap: wrap; } + } - .icon-link > .ci-status-icon > svg { - width: 22px; - height: 22px; - margin-right: 8px; - } + .mr-widget-icon { + font-size: 22px; + margin-right: $status-icon-margin; + } - .ci-error { - margin-right: $btn-side-margin; - } + .ci-status-icon svg { + width: $status-icon-size; + height: $status-icon-size; + margin: 3px 0; + position: relative; + overflow: visible; + display: block; } - .mr-widget-body, - .mr-widget-footer { - margin: 16px; + .mr-widget-body { + @include clearfix; + + &.media > *:first-child { + margin-right: 10px; + } } .mr-widget-pipeline-graph { - flex-shrink: 0; + padding: 0 4px; .dropdown-menu { - margin-top: 11px; z-index: 300; } .ci-action-icon-wrapper { line-height: 16px; } + } - @media (max-width: $screen-xs-max) { - order: 1; - margin-top: $gl-padding-top; - border-radius: 3px; - background-color: $white-light; - border: 1px solid $gray-darker; - width: 100%; - text-align: center; + .mini-pipeline-graph-dropdown-toggle { + vertical-align: top; + } - .dropdown-menu { - margin-left: -97.5px; - } + .mini-pipeline-graph-dropdown-menu .mini-pipeline-graph-dropdown-item { + display: flex; + align-items: center; - .arrow-up::before, - .arrow-up::after, { - margin-left: 97.5px; - } + .ci-status-text, + .ci-status-icon { + top: 0; + margin-right: 10px; } } .normal { - color: $gl-text-color; - font-size: 15px; + line-height: 28px; } .capitalize { @@ -165,9 +197,8 @@ @extend .ref-name; color: $gl-text-color; - font-weight: bold; + font-weight: 600; overflow: hidden; - margin: 0 3px; word-break: break-all; &.label-truncated { @@ -189,52 +220,19 @@ } } - .js-deployment-link { - display: inline-block; - } - .mr-widget-help { - margin: $gl-padding; - color: $ci-skipped-color; - } - - .mr-info-list { - - &.mr-links { - margin-left: 28px; - } - - &.mr-memory-usage { - margin: 5px 0 10px 25px; - } - } - - .mr-widget-heading { - .btn-default.btn-xs { - margin-left: 5px; - } - } - - .mr-widget-body { - .btn { - font-size: 15px; - } - - .btn-group .btn { - padding: 5px 10px; - - &.dropdown-toggle { - padding: 5px 7px; - } - } + padding: 10px 16px 10px 48px; + font-style: italic; } .mr-widget-body { h4 { - font-weight: bold; - font-size: 15px; - margin: 5px 0; - color: $gl-text-color; + float: left; + font-weight: 600; + font-size: 14px; + line-height: inherit; + margin-top: 0; + margin-bottom: 0; &.has-conflicts .fa-exclamation-triangle { color: $gl-warning; @@ -255,18 +253,16 @@ } .spacing { - margin: 0 $gl-padding; + margin: 0 0 0 10px; } .bold { - font-weight: bold; - font-size: 15px; + font-weight: 600; color: $gl-gray-light; } .state-label { - font-size: 16px; - font-weight: bold; + font-weight: 600; padding-right: 10px; } @@ -274,16 +270,6 @@ color: $gl-danger; } - .mr-widget-help { - margin: $gl-padding 0; - } - - .with-button { - position: relative; - top: 6px; - margin-bottom: 24px; - } - .spacing, .bold { vertical-align: middle; @@ -294,15 +280,8 @@ padding: 5px; } - .merge-opt-icon, - .merge-opt-title { - display: inline-block; - float: left; - } - - .merge-opt-icon svg { - height: 15px; - width: 15px; + .merge-opt-icon { + line-height: 1.5; } .merge-opt-title { @@ -316,34 +295,15 @@ } } - .has-error-message + .has-custom-error { - margin-left: 0; - } - .has-custom-error { display: inline-block; - margin-left: 70px; - } - - .merge-error-text { - margin-left: 70px; } @media (max-width: $screen-xs-max) { - h4 { - font-size: 14px; - } - p { font-size: 13px; } - .btn, - .btn-group, - .accept-action { - margin-bottom: 4px; - } - .btn-grouped { float: none; margin-right: 0; @@ -367,19 +327,16 @@ } } - &.mr-state-locked .mr-info-list { - margin-top: 10px; - margin-left: 12px; - } + &.mr-widget-empty-state { + line-height: 20px; - &.empty-state { .artwork { margin-bottom: $gl-padding; } .text { span { - font-weight: bold; + font-weight: 600; } p { @@ -389,10 +346,6 @@ } } - .mr-widget-footer { - border-top: 1px solid $gray-darker; - } - .ci-coverage { float: right; } @@ -497,8 +450,6 @@ } .btn-clipboard { - @extend .pull-right; - margin-right: 20px; margin-top: 5px; position: absolute; @@ -506,56 +457,29 @@ } } +.mr-links { + padding-left: $status-icon-size + $status-icon-margin; +} + .mr-info-list { + clear: left; position: relative; - margin: 10px 0 $gl-padding 12px; + padding-top: 4px; p { - margin: 6px 0; + margin: 0; position: relative; - padding-left: 15px; - - &::before { - content: ''; - position: absolute; - border-top: 2px solid $border-color; - height: 1px; - top: 9px; - width: 8px; - left: 0; - } + padding: 4px 0; &:last-child { - margin-bottom: 0; + padding-bottom: 0; } } - - .legend { - height: 100%; - width: 2px; - background: $border-color; - position: absolute; - top: -9px; - } } .mr-info-list.mr-memory-usage { - .legend { - height: 65%; - top: 0; - - @media (max-width: $screen-xs-max) { - height: 20px; - } - } - p { float: left; - padding-left: 21px; - - &::before { - top: 13px; - } } .memory-graph-container { @@ -565,12 +489,13 @@ } .mr-source-target { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; background-color: $gray-light; - border-radius: 3px 3px 0 0; - border-bottom: 1px solid $border-color; - padding: 0 $gl-padding; - margin-bottom: 6px; - line-height: 44px; + border-radius: $border-radius-default $border-radius-default 0 0; + padding: $gl-padding / 2 $gl-padding; .dropdown-toggle .fa { color: $gl-text-color; @@ -679,14 +604,8 @@ } .merged-buttons { - margin-top: 20px; - .btn { float: left; - - &:not(:last-child) { - margin-right: 10px; - } } } @@ -803,20 +722,8 @@ } .mr-memory-usage { - p.usage-info-loading, - p.usage-info-unavailable, - p.usage-info-failed { - margin-bottom: 5px; - } - p.usage-info-loading .usage-info-load-spinner { margin-right: 10px; font-size: 16px; } - - @media (max-width: $screen-md-min) { - .mr-info-list.mr-memory-usage .legend { - height: 80%; - } - } } diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index d3862df20d397cc3a995808e95442a8ccbfc7b09..6185342b495d9ad84395d01a1676810fc2b2ac46 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -220,7 +220,11 @@ position: relative; vertical-align: middle; height: 22px; - margin: 3px 6px 3px 0; + margin: 3px 0; + + + .stage-container { + margin-left: 6px; + } // Hack to show a button tooltip inline button.has-tooltip + .tooltip { diff --git a/changelogs/unreleased/33095-mr-widget-ui.yml b/changelogs/unreleased/33095-mr-widget-ui.yml new file mode 100644 index 0000000000000000000000000000000000000000..9ce3086df27705a44c23440a069eaebf1904ac01 --- /dev/null +++ b/changelogs/unreleased/33095-mr-widget-ui.yml @@ -0,0 +1,4 @@ +--- +title: clean up merge request widget UI +merge_request: +author: diff --git a/spec/features/merge_requests/closes_issues_spec.rb b/spec/features/merge_requests/closes_issues_spec.rb index 0e97254eada02846f5c925769a591917f2963b08..299b4f5708a147328da383336a3cc7472bbeb12e 100644 --- a/spec/features/merge_requests/closes_issues_spec.rb +++ b/spec/features/merge_requests/closes_issues_spec.rb @@ -26,17 +26,11 @@ feature 'Merge Request closing issues message', js: true do wait_for_requests end - context 'not closing or mentioning any issue' do - it 'does not display closing issue message' do - expect(page).not_to have_css('.mr-widget-footer') - end - end - context 'closing issues but not mentioning any other issue' do let(:merge_request_description) { "Description\n\nclosing #{issue_1.to_reference}, #{issue_2.to_reference}" } it 'does not display closing issue message' do - expect(page).to have_content("Closes issues #{issue_1.to_reference} and #{issue_2.to_reference}") + expect(page).to have_content("Closes #{issue_1.to_reference} and #{issue_2.to_reference}") end end @@ -44,7 +38,7 @@ feature 'Merge Request closing issues message', js: true do let(:merge_request_description) { "Description\n\nRefers to #{issue_1.to_reference} and #{issue_2.to_reference}" } it 'does not display closing issue message' do - expect(page).to have_content("Issues #{issue_1.to_reference} and #{issue_2.to_reference} are mentioned but will not be closed.") + expect(page).to have_content("Mentions #{issue_1.to_reference} and #{issue_2.to_reference}") end end @@ -52,8 +46,8 @@ feature 'Merge Request closing issues message', js: true do let(:merge_request_title) { "closes #{issue_1.to_reference}\n\n refers to #{issue_2.to_reference}" } it 'does not display closing issue message' do - expect(page).to have_content("Closes issue #{issue_1.to_reference}.") - expect(page).to have_content("Issue #{issue_2.to_reference} is mentioned but will not be closed.") + expect(page).to have_content("Closes #{issue_1.to_reference}") + expect(page).to have_content("Mentions #{issue_2.to_reference}") end end @@ -61,7 +55,7 @@ feature 'Merge Request closing issues message', js: true do let(:merge_request_title) { "closing #{issue_1.to_reference}, #{issue_2.to_reference}" } it 'does not display closing issue message' do - expect(page).to have_content("Closes issues #{issue_1.to_reference} and #{issue_2.to_reference}") + expect(page).to have_content("Closes #{issue_1.to_reference} and #{issue_2.to_reference}") end end @@ -69,7 +63,7 @@ feature 'Merge Request closing issues message', js: true do let(:merge_request_title) { "Refers to #{issue_1.to_reference} and #{issue_2.to_reference}" } it 'does not display closing issue message' do - expect(page).to have_content("Issues #{issue_1.to_reference} and #{issue_2.to_reference} are mentioned but will not be closed.") + expect(page).to have_content("Mentions #{issue_1.to_reference} and #{issue_2.to_reference}") end end @@ -77,8 +71,8 @@ feature 'Merge Request closing issues message', js: true do let(:merge_request_title) { "closes #{issue_1.to_reference}\n\n refers to #{issue_2.to_reference}" } it 'does not display closing issue message' do - expect(page).to have_content("Closes issue #{issue_1.to_reference}. Issue #{issue_2.to_reference} is mentioned but will not be closed.") - expect(page).to have_content("Issue #{issue_2.to_reference} is mentioned but will not be closed.") + expect(page).to have_content("Closes #{issue_1.to_reference}") + expect(page).to have_content("Mentions #{issue_2.to_reference}") end end end diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb index 574f5fe353edd9d0a2851523c5f15da14e65a475..ac46cc1f0e46f38854e1cc82eb5ede5a5821a38b 100644 --- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb @@ -41,8 +41,8 @@ feature 'Merge When Pipeline Succeeds', :js do it 'activates the Merge when pipeline succeeds feature' do click_button "Merge when pipeline succeeds" - expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds." - expect(page).to have_content "The source branch will not be removed." + expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds" + expect(page).to have_content "The source branch will not be removed" expect(page).to have_selector ".js-cancel-auto-merge" visit_merge_request(merge_request) # Needed to refresh the page expect(page).to have_content /enabled an automatic merge when the pipeline for \h{8} succeeds/i @@ -97,11 +97,11 @@ feature 'Merge When Pipeline Succeeds', :js do describe 'enabling Merge when pipeline succeeds via dropdown' do it 'activates the Merge when pipeline succeeds feature' do - click_button 'Select merge moment' + find('.js-merge-moment').click click_link 'Merge when pipeline succeeds' - expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds." - expect(page).to have_content "The source branch will not be removed." + expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds" + expect(page).to have_content "The source branch will not be removed" expect(page).to have_link "Cancel automatic merge" end end diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index 5c6eec44ff76bd2a868d15eba6bf0b467e61ceae..59e6742033351a0eef4eb3ed08c9897d7068bc0c 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -43,7 +43,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', js: t wait_for_requests expect(page).to have_button 'Merge when pipeline succeeds' - expect(page).not_to have_button 'Select merge moment' + expect(page).not_to have_button '.js-merge-moment' end end @@ -56,7 +56,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', js: t wait_for_requests expect(page).to have_css('button[disabled="disabled"]', text: 'Merge') - expect(page).to have_content('Please retry the job or push a new commit to fix the failure.') + expect(page).to have_content('Please retry the job or push a new commit to fix the failure') end end @@ -69,7 +69,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', js: t wait_for_requests expect(page).not_to have_button 'Merge' - expect(page).to have_content('Please retry the job or push a new commit to fix the failure.') + expect(page).to have_content('Please retry the job or push a new commit to fix the failure') end end @@ -113,7 +113,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', js: t expect(page).to have_button 'Merge when pipeline succeeds' - click_button 'Select merge moment' + page.find('.js-merge-moment').click expect(page).to have_content 'Merge immediately' end end diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js index ab8a3f6c64c3a5bcda49ac3961bbaaa3f1b9cf45..7ee998c8fce96e317c3bbdaba7a8f21b1428aea7 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js @@ -1,7 +1,6 @@ import Vue from 'vue'; import deploymentComponent from '~/vue_merge_request_widget/components/mr_widget_deployment'; import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service'; -import { statusIconEntityMap } from '~/vue_shared/ci_status_icons'; const deploymentMockData = [ { @@ -43,15 +42,6 @@ describe('MRWidgetDeployment', () => { }); }); - describe('computed', () => { - describe('svg', () => { - it('should have the proper SVG icon', () => { - const vm = createComponent(deploymentMockData); - expect(vm.svg).toEqual(statusIconEntityMap.icon_status_success); - }); - }); - }); - describe('methods', () => { let vm = createComponent(); const deployment = deploymentMockData[0]; diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js index 6adcbc73ed7a25f415ca544a559b02eb89cad0c0..2ae3adc1f93fa3b3a35b0b09175da84c18110af2 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js @@ -52,10 +52,10 @@ const createComponent = () => { }; const messages = { - loadingMetrics: 'Loading deployment statistics.', + loadingMetrics: 'Loading deployment statistics', hasMetrics: 'Memory usage unchanged from 0MB to 0MB', - loadFailed: 'Failed to load deployment statistics.', - metricsUnavailable: 'Deployment statistics are not available currently.', + loadFailed: 'Failed to load deployment statistics', + metricsUnavailable: 'Deployment statistics are not available currently', }; describe('MemoryUsage', () => { diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js index 647b59520f8a1779ba35072082dbc03fe7efe0d8..c763487d12f39d3704c8e7ffbaa5c6ad983544fc 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js @@ -81,13 +81,12 @@ describe('MRWidgetPipeline', () => { expect(el.querySelectorAll('.ci-status-icon.ci-status-icon-success').length).toEqual(1); expect(el.querySelector('.pipeline-id').textContent).toContain(`#${pipeline.id}`); expect(el.innerText).toContain('passed'); - expect(el.innerText).toContain('with stages'); expect(el.querySelector('.pipeline-id').getAttribute('href')).toEqual(pipeline.path); expect(el.querySelectorAll('.stage-container').length).toEqual(2); expect(el.querySelector('.js-ci-error')).toEqual(null); expect(el.querySelector('.js-commit-link').getAttribute('href')).toEqual(pipeline.commit.commit_path); expect(el.querySelector('.js-commit-link').textContent).toContain(pipeline.commit.short_id); - expect(el.querySelector('.js-mr-coverage').textContent).toContain(`Coverage ${pipeline.coverage}%.`); + expect(el.querySelector('.js-mr-coverage').textContent).toContain(`Coverage ${pipeline.coverage}%`); }); it('should list single stage', (done) => { @@ -95,7 +94,6 @@ describe('MRWidgetPipeline', () => { Vue.nextTick(() => { expect(el.querySelectorAll('.stage-container button').length).toEqual(1); - expect(el.innerText).toContain('with stage'); done(); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js index f6e0c3dfb746cf946e837f9a6b35036fa0d43a6c..f86fb6a0b4b2d3d98a96958dfb7c2402c5281b8c 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js @@ -22,15 +22,16 @@ describe('MRWidgetRelatedLinks', () => { }); describe('computed', () => { + const data = { + relatedLinks: { + closing: '/foo', + mentioned: '/foo', + assignToMe: '/foo', + }, + }; + describe('hasLinks', () => { it('should return correct value when we have links reference', () => { - const data = { - relatedLinks: { - closing: '/foo', - mentioned: '/foo', - assignToMe: '/foo', - }, - }; const vm = createComponent(data); expect(vm.hasLinks).toBeTruthy(); @@ -44,44 +45,24 @@ describe('MRWidgetRelatedLinks', () => { expect(vm.hasLinks).toBeFalsy(); }); }); - }); - - describe('methods', () => { - const data = { - relatedLinks: { - closing: '<a href="#">#23</a> and <a>#42</a>', - mentioned: '<a href="#">#7</a>', - }, - }; - const vm = createComponent(data); - - describe('hasMultipleIssues', () => { - it('should return true if the given text has multiple issues', () => { - expect(vm.hasMultipleIssues(data.relatedLinks.closing)).toBeTruthy(); - }); - - it('should return false if the given text has one issue', () => { - expect(vm.hasMultipleIssues(data.relatedLinks.mentioned)).toBeFalsy(); - }); - }); - describe('issueLabel', () => { - it('should return true if the given text has multiple issues', () => { - expect(vm.issueLabel('closing')).toEqual('issues'); - }); - - it('should return false if the given text has one issue', () => { - expect(vm.issueLabel('mentioned')).toEqual('issue'); + describe('closesText', () => { + it('returns correct text for open merge request', () => { + data.state = 'open'; + const vm = createComponent(data); + expect(vm.closesText).toEqual('Closes'); }); - }); - describe('verbLabel', () => { - it('should return true if the given text has multiple issues', () => { - expect(vm.verbLabel('closing')).toEqual('are'); + it('returns correct text for closed merge request', () => { + data.state = 'closed'; + const vm = createComponent(data); + expect(vm.closesText).toEqual('Did not close'); }); - it('should return false if the given text has one issue', () => { - expect(vm.verbLabel('mentioned')).toEqual('is'); + it('returns correct tense for merged request', () => { + data.state = 'merged'; + const vm = createComponent(data); + expect(vm.closesText).toEqual('Closed'); }); }); }); @@ -95,8 +76,8 @@ describe('MRWidgetRelatedLinks', () => { }); const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim(); - expect(content).toContain('Closes issues #23 and #42'); - expect(content).not.toContain('mentioned'); + expect(content).toContain('Closes #23 and #42'); + expect(content).not.toContain('Mentions'); }); it('should have only have mentioned issues text', () => { @@ -106,8 +87,7 @@ describe('MRWidgetRelatedLinks', () => { }, }); - expect(vm.$el.innerText).toContain('issue #7'); - expect(vm.$el.innerText).toContain('is mentioned but will not be closed.'); + expect(vm.$el.innerText).toContain('Mentions #7'); expect(vm.$el.innerText).not.toContain('Closes'); }); @@ -120,9 +100,8 @@ describe('MRWidgetRelatedLinks', () => { }); const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim(); - expect(content).toContain('Closes issue #7.'); - expect(content).toContain('issues #23 and #42'); - expect(content).toContain('are mentioned but will not be closed.'); + expect(content).toContain('Closes #7'); + expect(content).toContain('Mentions #23 and #42'); }); it('should have assing issues link', () => { diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js index cac2f561a0b373b0f2786c6f738a3db2e4ec9d86..4869fb17d96c7e604ef2944e9997978c11e2b91b 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js @@ -12,7 +12,7 @@ describe('MRWidgetArchived', () => { expect(el.classList.contains('mr-widget-body')).toBeTruthy(); expect(el.querySelector('button').classList.contains('btn-success')).toBeTruthy(); expect(el.querySelector('button').disabled).toBeTruthy(); - expect(el.innerText).toContain('This project is archived, write access has been disabled.'); + expect(el.innerText).toContain('This project is archived, write access has been disabled'); }); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js index 47b4ba893e0247ef284477716edaf278fb6762a5..6042d7384d581e4141dd5bc78f76d23b38d1538b 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js @@ -24,8 +24,8 @@ describe('MRWidgetAutoMergeFailed', () => { it('should have correct elements', () => { expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy(); - expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy(); - expect(vm.$el.innerText).toContain('This merge request failed to be merged automatically.'); + expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeFalsy(); + expect(vm.$el.innerText).toContain('This merge request failed to be merged automatically'); expect(vm.$el.innerText).toContain(mergeError); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js index 3be11d47227fe95fe9f20c72bf8c1c7530e57b88..6b7aa935ad34a001f5432ba61d5b12e978ee6907 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js @@ -12,7 +12,7 @@ describe('MRWidgetChecking', () => { expect(el.classList.contains('mr-widget-body')).toBeTruthy(); expect(el.querySelector('button').classList.contains('btn-success')).toBeTruthy(); expect(el.querySelector('button').disabled).toBeTruthy(); - expect(el.innerText).toContain('Checking ability to merge automatically.'); + expect(el.innerText).toContain('Checking ability to merge automatically'); expect(el.querySelector('i')).toBeDefined(); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js index e7ae85caec4cca9a5af55e5eb7691c5c65ffb43b..3b7b7d936624df7b44c67cbc435f97fbd2ed85d5 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js @@ -29,15 +29,16 @@ describe('MRWidgetConflicts', () => { describe('template', () => { it('should have correct elements', () => { const el = createComponent().$el; - const resolveButton = el.querySelectorAll('.btn-group .btn')[0]; - const mergeLocallyButton = el.querySelectorAll('.btn-group .btn')[1]; + const resolveButton = el.querySelector('.js-resolve-conflicts-button'); + const mergeButton = el.querySelector('.mr-widget-body .btn'); + const mergeLocallyButton = el.querySelector('.js-merge-locally-button'); - expect(el.textContent).toContain('There are merge conflicts.'); + expect(el.textContent).toContain('There are merge conflicts'); expect(el.textContent).not.toContain('ask someone with write access'); expect(el.querySelector('.btn-success').disabled).toBeTruthy(); - expect(el.querySelectorAll('.btn-group .btn').length).toBe(2); expect(resolveButton.textContent).toContain('Resolve conflicts'); expect(resolveButton.getAttribute('href')).toEqual(path); + expect(mergeButton.textContent).toContain('Merge'); expect(mergeLocallyButton.textContent).toContain('Merge locally'); }); @@ -59,8 +60,8 @@ describe('MRWidgetConflicts', () => { it('should not have action buttons', (done) => { Vue.nextTick(() => { expect(vm.$el.querySelectorAll('.btn').length).toBe(1); - expect(vm.$el.querySelector('a.js-resolve-conflicts-button')).toEqual(null); - expect(vm.$el.querySelector('a.js-merge-locally-button')).toEqual(null); + expect(vm.$el.querySelector('.js-resolve-conflicts-button')).toEqual(null); + expect(vm.$el.querySelector('.js-merge-locally-button')).toEqual(null); done(); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js index 587b83430d9fe18276ff77821f2c43fc811e8e39..cef365eec8a5faa0ed83efeeb08720fc9395d556 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js @@ -94,7 +94,7 @@ describe('MRWidgetFailedToMerge', () => { expect(el.querySelector('button').innerText).toContain('Merge'); expect(el.querySelector('.js-refresh-button').innerText).toContain('Refresh now'); expect(el.querySelector('.js-refresh-label')).toEqual(null); - expect(el.innerText).not.toContain('Refreshing now...'); + expect(el.innerText).not.toContain('Refreshing now'); setTimeout(() => { expect(el.innerText).toContain('Refreshing in 9 seconds'); done(); @@ -115,7 +115,7 @@ describe('MRWidgetFailedToMerge', () => { vm.refresh(); Vue.nextTick(() => { expect(el.innerText).not.toContain('Merge failed. Refreshing'); - expect(el.innerText).toContain('Refreshing now...'); + expect(el.innerText).toContain('Refreshing now'); }); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js index 8d8b90cea168de9af431cf1ab313d31d3a1924ba..9a71d0b47d79bbdeecf98edc02994d6491bf234c 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js @@ -162,10 +162,10 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => { it('should have correct elements', () => { expect(el.classList.contains('mr-widget-body')).toBeTruthy(); - expect(el.innerText).toContain('to be merged automatically when the pipeline succeeds.'); + expect(el.innerText).toContain('to be merged automatically when the pipeline succeeds'); expect(el.innerText).toContain('The changes will be merged into'); expect(el.innerText).toContain(targetBranch); - expect(el.innerText).toContain('The source branch will not be removed.'); + expect(el.innerText).toContain('The source branch will not be removed'); expect(el.querySelector('.js-cancel-auto-merge').innerText).toContain('Cancel automatic merge'); expect(el.querySelector('.js-cancel-auto-merge').getAttribute('disabled')).toBeFalsy(); expect(el.querySelector('.js-remove-source-branch').innerText).toContain('Remove source branch'); @@ -186,8 +186,8 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => { Vue.nextTick(() => { const normalizedText = el.innerText.replace(/\s+/g, ' '); - expect(normalizedText).toContain('The source branch will be removed.'); - expect(normalizedText).not.toContain('The source branch will not be removed.'); + expect(normalizedText).toContain('The source branch will be removed'); + expect(normalizedText).not.toContain('The source branch will not be removed'); done(); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js index 6628010112d4c3c02e09848ac465e5e50877bfc7..afaa750199a5e932c1e0e8f74a50242a479822a1 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js @@ -142,19 +142,19 @@ describe('MRWidgetMerged', () => { expect(el.querySelector('.js-mr-widget-author')).toBeDefined(); expect(el.innerText).toContain('The changes were merged into'); expect(el.innerText).toContain(targetBranch); - expect(el.innerText).toContain('The source branch has been removed.'); + expect(el.innerText).toContain('The source branch has been removed'); expect(el.innerText).toContain('Revert'); expect(el.innerText).toContain('Cherry-pick'); - expect(el.innerText).not.toContain('You can remove source branch now.'); - expect(el.innerText).not.toContain('The source branch is being removed.'); + expect(el.innerText).not.toContain('You can remove source branch now'); + expect(el.innerText).not.toContain('The source branch is being removed'); }); it('should not show source branch removed text', (done) => { vm.mr.sourceBranchRemoved = false; Vue.nextTick(() => { - expect(el.innerText).toContain('You can remove source branch now.'); - expect(el.innerText).not.toContain('The source branch has been removed.'); + expect(el.innerText).toContain('You can remove source branch now'); + expect(el.innerText).not.toContain('The source branch has been removed'); done(); }); }); @@ -164,9 +164,9 @@ describe('MRWidgetMerged', () => { vm.mr.sourceBranchRemoved = false; Vue.nextTick(() => { - expect(el.innerText).toContain('The source branch is being removed.'); - expect(el.innerText).not.toContain('You can remove source branch now.'); - expect(el.innerText).not.toContain('The source branch has been removed.'); + expect(el.innerText).toContain('The source branch is being removed'); + expect(el.innerText).not.toContain('You can remove source branch now'); + expect(el.innerText).not.toContain('The source branch has been removed'); done(); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js index 98674d12afb4bbc8f5f6ccafb3b37a252c210ddd..720effb5c1cb6a85877810bee3c6bfb885f26c5c 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js @@ -49,7 +49,7 @@ describe('MRWidgetMissingBranch', () => { expect(el.classList.contains('mr-widget-body')).toBeTruthy(); expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy(); expect(content).toContain('source branch does not exist.'); - expect(content).toContain('Please restore the source branch or use a different source branch.'); + expect(content).toContain('Please restore it or use a different source branch'); }); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js index 61e00f4cf79c4a940a4c6bef343cf24302dbebbf..33f20ab132de48ee6d1b17fbeddd3fd9058ec20b 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js @@ -11,7 +11,7 @@ describe('MRWidgetNotAllowed', () => { expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy(); expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy(); expect(vm.$el.innerText).toContain('Ready to be merged automatically.'); - expect(vm.$el.innerText).toContain('Ask someone with write access to this repository to merge this request.'); + expect(vm.$el.innerText).toContain('Ask someone with write access to this repository to merge this request'); }); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js index b293d1185710b7e1d57bdcf50753cf882d1f0c7d..d0702f9f50338ebc2051b2e3704a7ed8e0fb0000 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js @@ -10,7 +10,7 @@ describe('MRWidgetPipelineBlocked', () => { it('should have correct elements', () => { expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy(); expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy(); - expect(vm.$el.innerText).toContain('Pipeline blocked. The pipeline for this merge request requires a manual action to proceed.'); + expect(vm.$el.innerText).toContain('Pipeline blocked. The pipeline for this merge request requires a manual action to proceed'); }); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js index 807fba705d41a2be24ea491eab85aa9699ef36e4..78bac1c61a5f6c272a9454eb2ddade457ec4ab32 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js @@ -10,7 +10,7 @@ describe('MRWidgetPipelineFailed', () => { it('should have correct elements', () => { expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy(); expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy(); - expect(vm.$el.innerText).toContain('The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure.'); + expect(vm.$el.innerText).toContain('The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure'); }); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js index 732b516badd301a9c038fe1c5019dbf52f2eb175..c607c9746a4c210376a9fd951547bb0e21a090bc 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -72,7 +72,7 @@ describe('MRWidgetReadyToMerge', () => { const withDesc = 'Include description in commit message'; const withoutDesc = "Don't include description in commit message"; - it('should return message wit description', () => { + it('should return message with description', () => { expect(vm.commitMessageLinkTitle).toEqual(withDesc); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js index 5fb1d69a8b364d76f4c7ddcbb888b7ecfe18d4bc..4c67504b642af7bac340d25c58215dbbe8e1f072 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js @@ -10,7 +10,7 @@ describe('MRWidgetSHAMismatch', () => { it('should have correct elements', () => { expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy(); expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy(); - expect(vm.$el.innerText).toContain('The source branch HEAD has recently changed. Please reload the page and review the changes before merging.'); + expect(vm.$el.innerText).toContain('The source branch HEAD has recently changed. Please reload the page and review the changes before merging'); }); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js index 45bd1a6996454b1cb6e832f55f63a705f7b06797..2cb3aaa6951e0e99a743601d3fbb3e9eed3b2aa2 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js @@ -78,7 +78,7 @@ describe('MRWidgetWIP', () => { it('should have correct elements', () => { expect(el.classList.contains('mr-widget-body')).toBeTruthy(); - expect(el.innerText).toContain('This merge request is currently Work In Progress and therefore unable to merge'); + expect(el.innerText).toContain('This is a Work in Progress'); expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy(); expect(el.querySelector('button').innerText).toContain('Merge'); expect(el.querySelector('.js-remove-wip').innerText).toContain('Resolve WIP status'); diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js index e6f96d5588ba4a33c670c1fcc02bcb47f51c72b4..ad2f28b24f02cb39286f772bee661cf993a2c57a 100644 --- a/spec/javascripts/vue_mr_widget/mock_data.js +++ b/spec/javascripts/vue_mr_widget/mock_data.js @@ -30,6 +30,7 @@ export default { "merge_user_id": null, "merge_when_pipeline_succeeds": false, "source_branch": "daaaa", + "source_branch_link": "daaaa", "source_project_id": 19, "target_branch": "master", "target_project_id": 19,