diff options
Diffstat (limited to 'app')
11 files changed, 444 insertions, 230 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue index 5e464f8a0e2..21f21232596 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue @@ -79,66 +79,62 @@ export default { </script> <template> - <div class="mr-widget-heading deploy-heading"> + <div class="mr-widget-heading deploy-heading append-bottom-default"> <div class="ci-widget media"> - <div class="ci-status-icon ci-status-icon-success"> - <span class="js-icon-link icon-link"> - <status-icon status="success" /> - </span> - </div> <div class="media-body"> <div class="deploy-body"> - <template v-if="hasDeploymentMeta"> - <span> - Deployed to - </span> - <a - :href="deployment.url" - target="_blank" - rel="noopener noreferrer nofollow" - class="deploy-link js-deploy-meta" + <div class="deployment-info"> + <template v-if="hasDeploymentMeta"> + <span> + Deployed to + </span> + <a + :href="deployment.url" + target="_blank" + rel="noopener noreferrer nofollow" + class="deploy-link js-deploy-meta" + > + {{ deployment.name }} + </a> + </template> + <span + v-tooltip + v-if="hasDeploymentTime" + :title="deployment.deployed_at_formatted" + class="js-deploy-time" > - {{ deployment.name }} - </a> - </template> - <template v-if="hasExternalUrls"> - <span> - on + {{ deployTimeago }} </span> + <memory-usage + v-if="hasMetrics" + :metrics-url="deployment.metrics_url" + :metrics-monitoring-url="deployment.metrics_monitoring_url" + /> + </div> + <div> <a + v-if="hasExternalUrls" :href="deployment.external_url" target="_blank" rel="noopener noreferrer nofollow" - class="deploy-link js-deploy-url" + class="deploy-link js-deploy-url btn btn-default btn-sm inline" > - {{ deployment.external_url_formatted }} - <icon - :size="16" - name="external-link" - /> + <span> + View app + <icon name="external-link" /> + </span> </a> - </template> - <span - v-tooltip - v-if="hasDeploymentTime" - :title="deployment.deployed_at_formatted" - class="js-deploy-time" - > - {{ deployTimeago }} - </span> - <loading-button - v-if="deployment.stop_url" - :loading="isStopping" - container-class="btn btn-default btn-sm prepend-left-default" - label="Stop environment" - @click="stopEnvironment" - /> + <loading-button + v-if="deployment.stop_url" + :loading="isStopping" + container-class="btn btn-default btn-sm inline prepend-left-4" + title="Stop environment" + @click="stopEnvironment" + > + <icon name="stop" /> + </loading-button> + </div> </div> - <memory-usage - v-if="hasMetrics" - :metrics-url="deployment.metrics_url" - :metrics-monitoring-url="deployment.metrics_monitoring_url" - /> </div> </div> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue index 3ce9d8dc26a..c18b74743e4 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue @@ -2,7 +2,7 @@ import tooltip from '~/vue_shared/directives/tooltip'; import { n__ } from '~/locale'; import { webIDEUrl } from '~/lib/utils/url_utility'; -import icon from '~/vue_shared/components/icon.vue'; +import Icon from '~/vue_shared/components/icon.vue'; import clipboardButton from '~/vue_shared/components/clipboard_button.vue'; export default { @@ -11,7 +11,7 @@ export default { tooltip, }, components: { - icon, + Icon, clipboardButton, }, props: { @@ -54,104 +54,114 @@ export default { }; </script> <template> - <div class="mr-source-target"> - <div class="normal"> - <strong> - {{ s__("mrWidget|Request to merge") }} - <span - :class="{ 'label-truncated': isSourceBranchLong }" - :title="isSourceBranchLong ? mr.sourceBranch : ''" - :v-tooltip="isSourceBranchLong" - class="label-branch js-source-branch" - data-placement="bottom" - v-html="mr.sourceBranchLink" - > - </span> + <div class="mr-source-target append-bottom-default"> + <div class="git-merge-icon-container append-right-default"> + <icon name="git-merge" /> + </div> + <div class="git-merge-container d-flex"> + <div class="normal"> + <strong> + {{ s__("mrWidget|Request to merge") }} + <span + :class="{ 'label-truncated': isSourceBranchLong }" + :title="isSourceBranchLong ? mr.sourceBranch : ''" + :v-tooltip="isSourceBranchLong" + class="label-branch js-source-branch" + data-placement="bottom" + v-html="mr.sourceBranchLink" + > + </span> - <clipboard-button - :text="branchNameClipboardData" - :title="__('Copy branch name to clipboard')" - css-class="btn-default btn-transparent btn-clipboard" - /> + <clipboard-button + :text="branchNameClipboardData" + :title="__('Copy branch name to clipboard')" + css-class="btn-default btn-transparent btn-clipboard" + /> - {{ s__("mrWidget|into") }} + {{ s__("mrWidget|into") }} - <span - :v-tooltip="isTargetBranchLong" - :class="{ 'label-truncatedtooltip': isTargetBranchLong }" - :title="isTargetBranchLong ? mr.targetBranch : ''" - class="label-branch" - data-placement="bottom" - > - <a - :href="mr.targetBranchTreePath" - class="js-target-branch" + <span + :v-tooltip="isTargetBranchLong" + :class="{ 'label-truncatedtooltip': isTargetBranchLong }" + :title="isTargetBranchLong ? mr.targetBranch : ''" + class="label-branch" + data-placement="bottom" > - {{ mr.targetBranch }} - </a> - </span> - </strong> - <span - v-if="shouldShowCommitsBehindText" - class="diverged-commits-count" - > - (<a :href="mr.targetBranchPath">{{ commitsText }}</a>) - </span> - </div> + <a + :href="mr.targetBranchTreePath" + class="js-target-branch" + > + {{ mr.targetBranch }} + </a> + </span> + </strong> + <div + v-if="shouldShowCommitsBehindText" + class="diverged-commits-count" + > + <span class="monospace">{{ mr.sourceBranch }}</span> + is {{ commitsText }} + <span class="monospace">{{ mr.targetBranch }}</span> + </div> + </div> - <div v-if="mr.isOpen"> - <a - v-if="!mr.sourceBranchRemoved" - :href="webIdePath" - class="btn btn-sm btn-default inline js-web-ide" - > - {{ s__("mrWidget|Web IDE") }} - </a> - <button - :disabled="mr.sourceBranchRemoved" - data-target="#modal_merge_info" - data-toggle="modal" - class="btn btn-sm btn-default inline js-check-out-branch" - type="button" + <div + v-if="mr.isOpen" + class="branch-actions" > - {{ s__("mrWidget|Check out branch") }} - </button> - <span class="dropdown prepend-left-10"> + <a + v-if="!mr.sourceBranchRemoved" + :href="webIdePath" + class="btn btn-default inline js-web-ide d-none d-md-inline-block" + > + {{ s__("mrWidget|Open in Web IDE") }} + </a> <button + :disabled="mr.sourceBranchRemoved" + data-target="#modal_merge_info" + data-toggle="modal" + class="btn btn-default inline js-check-out-branch" type="button" - class="btn btn-sm inline dropdown-toggle" - data-toggle="dropdown" - aria-label="Download as" - aria-haspopup="true" - aria-expanded="false" > - <icon name="download" /> - <i - class="fa fa-caret-down" - aria-hidden="true"> - </i> + {{ s__("mrWidget|Check out branch") }} </button> - <ul class="dropdown-menu dropdown-menu-right"> - <li> - <a - :href="mr.emailPatchesPath" - class="js-download-email-patches" - download - > - {{ s__("mrWidget|Email patches") }} - </a> - </li> - <li> - <a - :href="mr.plainDiffPath" - class="js-download-plain-diff" - download - > - {{ s__("mrWidget|Plain diff") }} - </a> - </li> - </ul> - </span> + <span class="dropdown prepend-left-10"> + <button + type="button" + class="btn inline dropdown-toggle" + data-toggle="dropdown" + aria-label="Download as" + aria-haspopup="true" + aria-expanded="false" + > + <icon name="download" /> + <i + class="fa fa-caret-down" + aria-hidden="true"> + </i> + </button> + <ul class="dropdown-menu dropdown-menu-right"> + <li> + <a + :href="mr.emailPatchesPath" + class="js-download-email-patches" + download + > + {{ s__("mrWidget|Email patches") }} + </a> + </li> + <li> + <a + :href="mr.plainDiffPath" + class="js-download-plain-diff" + download + > + {{ s__("mrWidget|Plain diff") }} + </a> + </li> + </ul> + </span> + </div> </div> </div> </template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue index 2f0b5e12c12..4a3fd01fa39 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue @@ -26,6 +26,10 @@ export default { type: String, required: false, }, + sourceBranchLink: { + type: String, + required: false, + }, }, computed: { hasPipeline() { @@ -54,12 +58,18 @@ export default { <template> <div v-if="hasPipeline || hasCIError" - class="mr-widget-heading" + class="mr-widget-heading append-bottom-default" > <div class="ci-widget media"> <template v-if="hasCIError"> - <div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error append-right-10"> - <icon name="status_failed" /> + <div + class="add-border ci-status-icon ci-status-icon-failed ci-error + js-ci-error append-right-default" + > + <icon + :size="32" + name="status_failed_borderless" + /> </div> <div class="media-body"> Could not connect to the CI server. Please check your settings and try again @@ -68,50 +78,66 @@ export default { <template v-else-if="hasPipeline"> <a :href="status.details_path" - class="append-right-10" + class="align-self-start append-right-default" > - <ci-icon :status="status" /> + <ci-icon + :status="status" + :size="32" + :borderless="true" + class="add-border" + /> </a> + <div class="ci-widget-container d-flex"> + <div class="ci-widget-content"> + <div class="media-body"> + <div class="font-weight-bold"> + Pipeline + <a + :href="pipeline.path" + class="pipeline-id font-weight-normal pipeline-number" + >#{{ pipeline.id }}</a> - <div class="media-body"> - Pipeline - <a - :href="pipeline.path" - class="pipeline-id" - > - #{{ pipeline.id }} - </a> - - {{ pipeline.details.status.label }} + {{ pipeline.details.status.label }} - <template v-if="hasCommitInfo"> - for - - <a - :href="pipeline.commit.commit_path" - class="commit-sha js-commit-link" - > - {{ pipeline.commit.short_id }}</a>. - </template> - - <span class="mr-widget-pipeline-graph"> - <span - v-if="hasStages" - class="stage-cell" - > + <template v-if="hasCommitInfo"> + for + <a + :href="pipeline.commit.commit_path" + class="commit-sha js-commit-link font-weight-normal" + > + {{ pipeline.commit.short_id }}</a> + on + <span + class="label-branch" + v-html="sourceBranchLink" + > + </span> + </template> + </div> <div - v-for="(stage, i) in pipeline.details.stages" - :key="i" - class="stage-container dropdown js-mini-pipeline-graph" + v-if="pipeline.coverage" + class="coverage" > - <pipeline-stage :stage="stage" /> + Coverage {{ pipeline.coverage }}% </div> + </div> + </div> + <div> + <span class="mr-widget-pipeline-graph"> + <span + v-if="hasStages" + class="stage-cell" + > + <div + v-for="(stage, i) in pipeline.details.stages" + :key="i" + class="stage-container dropdown js-mini-pipeline-graph mr-widget-pipeline-stages" + > + <pipeline-stage :stage="stage" /> + </div> + </span> </span> - </span> - - <template v-if="pipeline.coverage"> - Coverage {{ pipeline.coverage }}% - </template> + </div> </div> </template> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue index 53c4dc8c8f4..55b87f3a8ec 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_status_icon.vue @@ -43,6 +43,7 @@ <ci-icon v-else :status="statusObj" + :size="24" /> <button diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue index 09477da40b5..b5de3dd6d73 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue @@ -252,41 +252,44 @@ export default { :pipeline="mr.pipeline" :ci-status="mr.ciStatus" :has-ci="mr.hasCI" + :source-branch-link="mr.sourceBranchLink" /> <deployment v-for="deployment in mr.deployments" :key="deployment.id" :deployment="deployment" /> - <div class="mr-widget-section"> - <component - :is="componentName" - :mr="mr" - :service="service" - /> + <div class="mr-section-container"> + <div class="mr-widget-section"> + <component + :is="componentName" + :mr="mr" + :service="service" + /> - <section - v-if="mr.allowCollaboration" - class="mr-info-list mr-links" - > - {{ s__("mrWidget|Allows commits from members who can merge to the target branch") }} - </section> + <section + v-if="mr.allowCollaboration" + class="mr-info-list mr-links" + > + {{ s__("mrWidget|Allows commits from members who can merge to the target branch") }} + </section> - <mr-widget-related-links - v-if="shouldRenderRelatedLinks" - :state="mr.state" - :related-links="mr.relatedLinks" - /> + <mr-widget-related-links + v-if="shouldRenderRelatedLinks" + :state="mr.state" + :related-links="mr.relatedLinks" + /> - <source-branch-removal-status - v-if="shouldRenderSourceBranchRemovalStatus" - /> - </div> - <div - v-if="shouldRenderMergeHelp" - class="mr-widget-footer" - > - <mr-widget-merge-help /> + <source-branch-removal-status + v-if="shouldRenderSourceBranchRemovalStatus" + /> + </div> + <div + v-if="shouldRenderMergeHelp" + class="mr-widget-footer" + > + <mr-widget-merge-help /> + </div> </div> </div> </template> diff --git a/app/assets/stylesheets/framework/icons.scss b/app/assets/stylesheets/framework/icons.scss index 30314f3d6cb..d1f7ff4438b 100644 --- a/app/assets/stylesheets/framework/icons.scss +++ b/app/assets/stylesheets/framework/icons.scss @@ -3,12 +3,20 @@ svg { fill: $green-500; } + + &.add-border { + @include borderless-status-icon($green-500); + } } .ci-status-icon-failed { svg { fill: $gl-danger; } + + &.add-border { + @include borderless-status-icon($red-500); + } } .ci-status-icon-pending, @@ -17,12 +25,20 @@ svg { fill: $orange-500; } + + &.add-border { + @include borderless-status-icon($orange-500); + } } .ci-status-icon-running { svg { fill: $blue-400; } + + &.add-border { + @include borderless-status-icon($blue-400); + } } .ci-status-icon-canceled, @@ -30,6 +46,10 @@ svg { fill: $gl-text-color; } + + &.add-border { + @include borderless-status-icon($gl-text-color); + } } .ci-status-icon-created, @@ -38,6 +58,10 @@ svg { fill: $gray-darkest; } + + &.add-border { + @include borderless-status-icon($gray-darkest); + } } .ci-status-icon-manual { diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index 0b645eb811b..76ebfc22ef7 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -232,3 +232,10 @@ word-break: break-word; max-width: 100%; } + +@mixin borderless-status-icon($color) { + svg { + border: 1px solid $color; + border-radius: 50%; + } +} diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index 9e77ea03a24..9874c928604 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -350,7 +350,8 @@ code { } .commit-sha, -.ref-name { +.ref-name, +.pipeline-number { @extend .monospace; font-size: 95%; } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 7808f6d3a25..6cfa09b56a7 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -743,6 +743,7 @@ Pipeline Graph */ $stage-hover-bg: $gray-darker; $ci-action-icon-size: 22px; +$ci-action-icon-size-lg: 24px; $pipeline-dropdown-line-height: 20px; $pipeline-dropdown-status-icon-size: 18px; $ci-action-dropdown-button-size: 24px; diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index efd730af558..c32049e1b33 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -15,16 +15,38 @@ } } +.mr-widget-heading { + position: relative; + border: 1px solid $border-color; + border-radius: 4px; + + &:not(.deploy-heading)::before { + content: ''; + border-left: 1px solid $theme-gray-200; + position: absolute; + left: 32px; + top: -17px; + height: 16px; + } +} + +.mr-section-container { + border: 1px solid $border-color; + border-radius: $border-radius-default; + border-top: 0; +} + +.mr-widget-heading, +.mr-widget-section, +.mr-widget-footer { + padding: $gl-padding; +} + .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; } @@ -124,10 +146,17 @@ .ci-widget { color: $gl-text-color; display: flex; + align-items: center; + justify-content: space-between; @include media-breakpoint-down(xs) { flex-wrap: wrap; } + + .ci-widget-content { + display: flex; + align-items: center; + } } .mr-widget-icon { @@ -136,8 +165,6 @@ } .ci-status-icon svg { - width: $status-icon-size; - height: $status-icon-size; margin: 3px 0; position: relative; overflow: visible; @@ -145,8 +172,6 @@ } .mr-widget-pipeline-graph { - padding: 0 4px; - .dropdown-menu { z-index: 300; } @@ -157,7 +182,7 @@ } .normal { - line-height: 28px; + flex: 1; } .capitalize { @@ -168,7 +193,7 @@ @extend .ref-name; color: $gl-text-color; - font-weight: $gl-font-weight-bold; + font-weight: normal; overflow: hidden; word-break: break-all; @@ -192,6 +217,8 @@ } .mr-widget-body { + line-height: 28px; + @include clearfix; &.media > *:first-child { @@ -474,18 +501,66 @@ } } +.merge-request-details .content-block { + border-bottom: 0; +} + .mr-source-target { display: flex; flex-wrap: wrap; - justify-content: space-between; - align-items: center; - background-color: $gray-light; - border-radius: $border-radius-default $border-radius-default 0 0; - padding: $gl-padding / 2 $gl-padding; + border-radius: $border-radius-default; + padding: $gl-padding; + border: 1px solid $border-color; + min-height: 69px; + + @include media-breakpoint-up(md) { + align-items: center; + } .dropdown-toggle .fa { color: $gl-text-color; } + + .git-merge-icon-container { + border: 1px solid $theme-gray-400; + border-radius: 50%; + height: 32px; + width: 32px; + color: $theme-gray-700; + line-height: 28px; + + .ic-git-merge { + vertical-align: middle; + width: 31px; + } + } + + .git-merge-container { + justify-content: space-between; + flex: 1; + flex-direction: row; + align-items: center; + + @include media-breakpoint-down(md) { + flex-direction: column; + align-items: flex-start; + + .branch-actions { + margin-top: 16px; + } + } + + @include media-breakpoint-up(lg) { + .branch-actions { + align-self: center; + } + } + } + + .diverged-commits-count { + color: $gl-text-color-secondary; + font-size: 12px; + } } .card-new-merge-request { @@ -720,13 +795,25 @@ } .deploy-heading { + margin-top: -19px; + border-top-left-radius: 0; + border-top-right-radius: 0; + background-color: $gray-light; + + @include media-breakpoint-up(md) { + padding: $gl-padding-8 $gl-padding; + } + .media-body { min-width: 0; + font-size: 12px; + margin-left: 48px; } } .deploy-body { display: flex; + align-items: center; flex-wrap: wrap; @include media-breakpoint-up(xs) { @@ -734,6 +821,15 @@ white-space: nowrap; } + @include media-breakpoint-down(md) { + flex-direction: column; + align-items: flex-start; + + .deployment-info { + margin-bottom: $gl-padding; + } + } + > *:not(:last-child) { margin-right: .3em; } @@ -741,18 +837,22 @@ svg { vertical-align: text-top; } -} -.deploy-link { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - min-width: 100px; - max-width: 150px; + .deployment-info { + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + min-width: 100px; - @include media-breakpoint-up(xs) { - min-width: 0; - max-width: 100%; + @include media-breakpoint-up(xs) { + min-width: 0; + max-width: 100%; + } + } + + .btn svg { + fill: $theme-gray-700; } } @@ -772,3 +872,33 @@ } } } + +.ci-widget-container { + justify-content: space-between; + flex: 1; + flex-direction: row; + + @include media-breakpoint-down(md) { + flex-direction: column; + + .stage-cell .stage-container { + margin-top: 16px; + } + + .dropdown .mini-pipeline-graph-dropdown-menu.dropdown-menu { + transform: initial; + } + } + + .coverage { + font-size: 12px; + color: $theme-gray-700; + line-height: initial; + } + + .mini-pipeline-graph-dropdown-toggle, + .stage-cell .mini-pipeline-graph-dropdown-toggle svg { + height: $ci-action-icon-size-lg; + width: $ci-action-icon-size-lg; + } +} diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 52332ac97dd..b68c89c25d8 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -301,6 +301,21 @@ border-bottom: 2px solid $border-color; } } + + //delete when all pipelines are updated to new size + &.mr-widget-pipeline-stages { + + .stage-container { + margin-left: 4px; + } + + &:not(:last-child) { + &::after { + width: 4px; + right: -4px; + top: 11px; + } + } + } } } |