Commit bc5a9206 authored by Clement Ho's avatar Clement Ho Committed by Filipa Lacerda

Redesign for mr widget info and pipelines section

parent e0c0ce28
...@@ -79,15 +79,11 @@ export default { ...@@ -79,15 +79,11 @@ export default {
</script> </script>
<template> <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-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="media-body">
<div class="deploy-body"> <div class="deploy-body">
<div class="deployment-info">
<template v-if="hasDeploymentMeta"> <template v-if="hasDeploymentMeta">
<span> <span>
Deployed to Deployed to
...@@ -101,23 +97,6 @@ export default { ...@@ -101,23 +97,6 @@ export default {
{{ deployment.name }} {{ deployment.name }}
</a> </a>
</template> </template>
<template v-if="hasExternalUrls">
<span>
on
</span>
<a
:href="deployment.external_url"
target="_blank"
rel="noopener noreferrer nofollow"
class="deploy-link js-deploy-url"
>
{{ deployment.external_url_formatted }}
<icon
:size="16"
name="external-link"
/>
</a>
</template>
<span <span
v-tooltip v-tooltip
v-if="hasDeploymentTime" v-if="hasDeploymentTime"
...@@ -126,20 +105,37 @@ export default { ...@@ -126,20 +105,37 @@ export default {
> >
{{ deployTimeago }} {{ deployTimeago }}
</span> </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"
/>
</div>
<memory-usage <memory-usage
v-if="hasMetrics" v-if="hasMetrics"
:metrics-url="deployment.metrics_url" :metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url" :metrics-monitoring-url="deployment.metrics_monitoring_url"
/> />
</div> </div>
<div>
<a
v-if="hasExternalUrls"
:href="deployment.external_url"
target="_blank"
rel="noopener noreferrer nofollow"
class="deploy-link js-deploy-url btn btn-default btn-sm inline"
>
<span>
View app
<icon name="external-link" />
</span>
</a>
<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>
</div>
</div> </div>
</div> </div>
</template> </template>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
import { n__ } from '~/locale'; import { n__ } from '~/locale';
import { webIDEUrl } from '~/lib/utils/url_utility'; 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'; import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
export default { export default {
...@@ -11,7 +11,7 @@ export default { ...@@ -11,7 +11,7 @@ export default {
tooltip, tooltip,
}, },
components: { components: {
icon, Icon,
clipboardButton, clipboardButton,
}, },
props: { props: {
...@@ -54,7 +54,11 @@ export default { ...@@ -54,7 +54,11 @@ export default {
}; };
</script> </script>
<template> <template>
<div class="mr-source-target"> <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"> <div class="normal">
<strong> <strong>
{{ s__("mrWidget|Request to merge") }} {{ s__("mrWidget|Request to merge") }}
...@@ -91,27 +95,32 @@ export default { ...@@ -91,27 +95,32 @@ export default {
</a> </a>
</span> </span>
</strong> </strong>
<span <div
v-if="shouldShowCommitsBehindText" v-if="shouldShowCommitsBehindText"
class="diverged-commits-count" class="diverged-commits-count"
> >
(<a :href="mr.targetBranchPath">{{ commitsText }}</a>) <span class="monospace">{{ mr.sourceBranch }}</span>
</span> is {{ commitsText }}
<span class="monospace">{{ mr.targetBranch }}</span>
</div>
</div> </div>
<div v-if="mr.isOpen"> <div
v-if="mr.isOpen"
class="branch-actions"
>
<a <a
v-if="!mr.sourceBranchRemoved" v-if="!mr.sourceBranchRemoved"
:href="webIdePath" :href="webIdePath"
class="btn btn-sm btn-default inline js-web-ide" class="btn btn-default inline js-web-ide d-none d-md-inline-block"
> >
{{ s__("mrWidget|Web IDE") }} {{ s__("mrWidget|Open in Web IDE") }}
</a> </a>
<button <button
:disabled="mr.sourceBranchRemoved" :disabled="mr.sourceBranchRemoved"
data-target="#modal_merge_info" data-target="#modal_merge_info"
data-toggle="modal" data-toggle="modal"
class="btn btn-sm btn-default inline js-check-out-branch" class="btn btn-default inline js-check-out-branch"
type="button" type="button"
> >
{{ s__("mrWidget|Check out branch") }} {{ s__("mrWidget|Check out branch") }}
...@@ -119,7 +128,7 @@ export default { ...@@ -119,7 +128,7 @@ export default {
<span class="dropdown prepend-left-10"> <span class="dropdown prepend-left-10">
<button <button
type="button" type="button"
class="btn btn-sm inline dropdown-toggle" class="btn inline dropdown-toggle"
data-toggle="dropdown" data-toggle="dropdown"
aria-label="Download as" aria-label="Download as"
aria-haspopup="true" aria-haspopup="true"
...@@ -154,4 +163,5 @@ export default { ...@@ -154,4 +163,5 @@ export default {
</span> </span>
</div> </div>
</div> </div>
</div>
</template> </template>
...@@ -26,6 +26,10 @@ export default { ...@@ -26,6 +26,10 @@ export default {
type: String, type: String,
required: false, required: false,
}, },
sourceBranchLink: {
type: String,
required: false,
},
}, },
computed: { computed: {
hasPipeline() { hasPipeline() {
...@@ -54,12 +58,18 @@ export default { ...@@ -54,12 +58,18 @@ export default {
<template> <template>
<div <div
v-if="hasPipeline || hasCIError" v-if="hasPipeline || hasCIError"
class="mr-widget-heading" class="mr-widget-heading append-bottom-default"
> >
<div class="ci-widget media"> <div class="ci-widget media">
<template v-if="hasCIError"> <template v-if="hasCIError">
<div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error append-right-10"> <div
<icon name="status_failed" /> 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>
<div class="media-body"> <div class="media-body">
Could not connect to the CI server. Please check your settings and try again Could not connect to the CI server. Please check your settings and try again
...@@ -68,32 +78,51 @@ export default { ...@@ -68,32 +78,51 @@ export default {
<template v-else-if="hasPipeline"> <template v-else-if="hasPipeline">
<a <a
:href="status.details_path" :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> </a>
<div class="ci-widget-container d-flex">
<div class="ci-widget-content">
<div class="media-body"> <div class="media-body">
<div class="font-weight-bold">
Pipeline Pipeline
<a <a
:href="pipeline.path" :href="pipeline.path"
class="pipeline-id" class="pipeline-id font-weight-normal pipeline-number"
> >#{{ pipeline.id }}</a>
#{{ pipeline.id }}
</a>
{{ pipeline.details.status.label }} {{ pipeline.details.status.label }}
<template v-if="hasCommitInfo"> <template v-if="hasCommitInfo">
for for
<a <a
:href="pipeline.commit.commit_path" :href="pipeline.commit.commit_path"
class="commit-sha js-commit-link" class="commit-sha js-commit-link font-weight-normal"
> >
{{ pipeline.commit.short_id }}</a>. {{ pipeline.commit.short_id }}</a>
on
<span
class="label-branch"
v-html="sourceBranchLink"
>
</span>
</template> </template>
</div>
<div
v-if="pipeline.coverage"
class="coverage"
>
Coverage {{ pipeline.coverage }}%
</div>
</div>
</div>
<div>
<span class="mr-widget-pipeline-graph"> <span class="mr-widget-pipeline-graph">
<span <span
v-if="hasStages" v-if="hasStages"
...@@ -102,16 +131,13 @@ export default { ...@@ -102,16 +131,13 @@ export default {
<div <div
v-for="(stage, i) in pipeline.details.stages" v-for="(stage, i) in pipeline.details.stages"
:key="i" :key="i"
class="stage-container dropdown js-mini-pipeline-graph" class="stage-container dropdown js-mini-pipeline-graph mr-widget-pipeline-stages"
> >
<pipeline-stage :stage="stage" /> <pipeline-stage :stage="stage" />
</div> </div>
</span> </span>
</span> </span>
</div>
<template v-if="pipeline.coverage">
Coverage {{ pipeline.coverage }}%
</template>
</div> </div>
</template> </template>
</div> </div>
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
<ci-icon <ci-icon
v-else v-else
:status="statusObj" :status="statusObj"
:size="24"
/> />
<button <button
......
...@@ -252,12 +252,14 @@ export default { ...@@ -252,12 +252,14 @@ export default {
:pipeline="mr.pipeline" :pipeline="mr.pipeline"
:ci-status="mr.ciStatus" :ci-status="mr.ciStatus"
:has-ci="mr.hasCI" :has-ci="mr.hasCI"
:source-branch-link="mr.sourceBranchLink"
/> />
<deployment <deployment
v-for="deployment in mr.deployments" v-for="deployment in mr.deployments"
:key="deployment.id" :key="deployment.id"
:deployment="deployment" :deployment="deployment"
/> />
<div class="mr-section-container">
<div class="mr-widget-section"> <div class="mr-widget-section">
<component <component
:is="componentName" :is="componentName"
...@@ -289,4 +291,5 @@ export default { ...@@ -289,4 +291,5 @@ export default {
<mr-widget-merge-help /> <mr-widget-merge-help />
</div> </div>
</div> </div>
</div>
</template> </template>
...@@ -3,12 +3,20 @@ ...@@ -3,12 +3,20 @@
svg { svg {
fill: $green-500; fill: $green-500;
} }
&.add-border {
@include borderless-status-icon($green-500);
}
} }
.ci-status-icon-failed { .ci-status-icon-failed {
svg { svg {
fill: $gl-danger; fill: $gl-danger;
} }
&.add-border {
@include borderless-status-icon($red-500);
}
} }
.ci-status-icon-pending, .ci-status-icon-pending,
...@@ -17,12 +25,20 @@ ...@@ -17,12 +25,20 @@
svg { svg {
fill: $orange-500; fill: $orange-500;
} }
&.add-border {
@include borderless-status-icon($orange-500);
}
} }
.ci-status-icon-running { .ci-status-icon-running {
svg { svg {
fill: $blue-400; fill: $blue-400;
} }
&.add-border {
@include borderless-status-icon($blue-400);
}
} }
.ci-status-icon-canceled, .ci-status-icon-canceled,
...@@ -30,6 +46,10 @@ ...@@ -30,6 +46,10 @@
svg { svg {
fill: $gl-text-color; fill: $gl-text-color;
} }
&.add-border {
@include borderless-status-icon($gl-text-color);
}
} }
.ci-status-icon-created, .ci-status-icon-created,
...@@ -38,6 +58,10 @@ ...@@ -38,6 +58,10 @@
svg { svg {
fill: $gray-darkest; fill: $gray-darkest;
} }
&.add-border {
@include borderless-status-icon($gray-darkest);
}
} }
.ci-status-icon-manual { .ci-status-icon-manual {
......
...@@ -232,3 +232,10 @@ ...@@ -232,3 +232,10 @@
word-break: break-word; word-break: break-word;
max-width: 100%; max-width: 100%;
} }
@mixin borderless-status-icon($color) {
svg {
border: 1px solid $color;
border-radius: 50%;
}
}
...@@ -350,7 +350,8 @@ code { ...@@ -350,7 +350,8 @@ code {
} }
.commit-sha, .commit-sha,
.ref-name { .ref-name,
.pipeline-number {
@extend .monospace; @extend .monospace;
font-size: 95%; font-size: 95%;
} }
......
...@@ -743,6 +743,7 @@ Pipeline Graph ...@@ -743,6 +743,7 @@ Pipeline Graph
*/ */
$stage-hover-bg: $gray-darker; $stage-hover-bg: $gray-darker;
$ci-action-icon-size: 22px; $ci-action-icon-size: 22px;
$ci-action-icon-size-lg: 24px;
$pipeline-dropdown-line-height: 20px; $pipeline-dropdown-line-height: 20px;
$pipeline-dropdown-status-icon-size: 18px; $pipeline-dropdown-status-icon-size: 18px;
$ci-action-dropdown-button-size: 24px; $ci-action-dropdown-button-size: 24px;
......
...@@ -15,16 +15,38 @@ ...@@ -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 { .mr-state-widget {
color: $gl-text-color; color: $gl-text-color;
border: 1px solid $border-color;
border-radius: 2px;
line-height: 28px;
.mr-widget-heading,
.mr-widget-section, .mr-widget-section,
.mr-widget-footer { .mr-widget-footer {
padding: $gl-padding;
border-top: solid 1px $border-color; border-top: solid 1px $border-color;
} }
...@@ -124,10 +146,17 @@ ...@@ -124,10 +146,17 @@
.ci-widget { .ci-widget {
color: $gl-text-color; color: $gl-text-color;
display: flex; display: flex;
align-items: center;
justify-content: space-between;
@include media-breakpoint-down(xs) { @include media-breakpoint-down(xs) {
flex-wrap: wrap; flex-wrap: wrap;
} }
.ci-widget-content {
display: flex;
align-items: center;
}
} }
.mr-widget-icon { .mr-widget-icon {
...@@ -136,8 +165,6 @@ ...@@ -136,8 +165,6 @@
} }
.ci-status-icon svg { .ci-status-icon svg {
width: $status-icon-size;
height: $status-icon-size;
margin: 3px 0; margin: 3px 0;
position: relative; position: relative;
overflow: visible; overflow: visible;
...@@ -145,8 +172,6 @@ ...@@ -145,8 +172,6 @@
} }
.mr-widget-pipeline-graph { .mr-widget-pipeline-graph {
padding: 0 4px;
.dropdown-menu { .dropdown-menu {
z-index: 300; z-index: 300;
} }
...@@ -157,7 +182,7 @@ ...@@ -157,7 +182,7 @@
} }
.normal { .normal {
line-height: 28px; flex: 1;
} }
.capitalize { .capitalize {
...@@ -168,7 +193,7 @@ ...@@ -168,7 +193,7 @@
@extend .ref-name; @extend .ref-name;
color: $gl-text-color; color: $gl-text-color;
font-weight: $gl-font-weight-bold; font-weight: normal;
overflow: hidden; overflow: hidden;
word-break: break-all; word-break: break-all;
...@@ -192,6 +217,8 @@ ...@@ -192,6 +217,8 @@
} }
.mr-widget-body { .mr-widget-body {
line-height: 28px;
@include clearfix; @include clearfix;
&.media > *:first-child { &.media > *:first-child {
...@@ -474,18 +501,66 @@ ...@@ -474,18 +501,66 @@
} }
} }
.merge-request-details .content-block {
border-bottom: 0;
}
.mr-source-target { .mr-source-target {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; border-radius: $border-radius-default;
padding: $gl-padding;
border: 1px solid $border-color;
min-height: 69px;
@include media-breakpoint-up(md) {
align-items: center; align-items: center;
background-color: $gray-light; }
border-radius: $border-radius-default $border-radius-default 0 0;
padding: $gl-padding / 2 $gl-padding;
.dropdown-toggle .fa { .dropdown-toggle .fa {
color: $gl-text-color; 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 { .card-new-merge-request {
...@@ -720,13 +795,25 @@ ...@@ -720,13 +795,25 @@
} }
.deploy-heading { .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 { .media-body {
min-width: 0; min-width: 0;
font-size: 12px;
margin-left: 48px;
} }
} }
.deploy-body { .deploy-body {
display: flex; display: flex;
align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
@include media-breakpoint-up(xs) { @include media-breakpoint-up(xs) {
...@@ -734,6 +821,15 @@ ...@@ -734,6 +821,15 @@
white-space: nowrap; white-space: nowrap;
} }
@include media-breakpoint-down(md) {
flex-direction: column;
align-items: flex-start;
.deployment-info {
margin-bottom: $gl-padding;
}
}
> *:not(:last-child) { > *:not(:last-child) {
margin-right: .3em; margin-right: .3em;
} }
...@@ -741,19 +837,23 @@ ...@@ -741,19 +837,23 @@
svg { svg {
vertical-align: text-top; vertical-align: text-top;
} }
}
.deploy-link { .deployment-info {
flex: 1;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
min-width: 100px; min-width: 100px;
max-width: 150px;
@include media-breakpoint-up(xs) { @include media-breakpoint-up(xs) {
min-width: 0; min-width: 0;
max-width: 100%; max-width: 100%;
} }
}
.btn svg {
fill: $theme-gray-700;
}
} }
// Hack alert: we've rewritten `btn` class in a way that // Hack alert: we've rewritten `btn` class in a way that
...@@ -772,3 +872,33 @@ ...@@ -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;
}
}
...@@ -301,6 +301,21 @@ ...@@ -301,6 +301,21 @@
border-bottom: 2px solid $border-color; 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;
}
}
}
} }
} }
......
...@@ -153,7 +153,7 @@ describe('Deployment component', () => { ...@@ -153,7 +153,7 @@ describe('Deployment component', () => {
it('renders external URL', () => { it('renders external URL', () => {
expect(el.querySelector('.js-deploy-url').getAttribute('href')).toEqual(deploymentMockData.external_url); expect(el.querySelector('.js-deploy-url').getAttribute('href')).toEqual(deploymentMockData.external_url);
expect(el.querySelector('.js-deploy-url').innerText).toContain(deploymentMockData.external_url_formatted); expect(el.querySelector('.js-deploy-url').innerText).toContain('View app');
}); });
it('renders stop button', () => { it('renders stop button', () => {
......
...@@ -145,7 +145,7 @@ describe('MRWidgetHeader', () => { ...@@ -145,7 +145,7 @@ describe('MRWidgetHeader', () => {
it('renders web ide button', () => { it('renders web ide button', () => {
const button = vm.$el.querySelector('.js-web-ide'); const button = vm.$el.querySelector('.js-web-ide');
expect(button.textContent.trim()).toEqual('Web IDE'); expect(button.textContent.trim()).toEqual('Open in Web IDE');
expect(button.getAttribute('href')).toEqual('/-/ide/projectabc'); expect(button.getAttribute('href')).toEqual('/-/ide/projectabc');
}); });
...@@ -154,7 +154,7 @@ describe('MRWidgetHeader', () => { ...@@ -154,7 +154,7 @@ describe('MRWidgetHeader', () => {
const button = vm.$el.querySelector('.js-web-ide'); const button = vm.$el.querySelector('.js-web-ide');
expect(button.textContent.trim()).toEqual('Web IDE'); expect(button.textContent.trim()).toEqual('Open in Web IDE');
expect(button.getAttribute('href')).toEqual('/-/ide/projectabc'); expect(button.getAttribute('href')).toEqual('/-/ide/projectabc');
}); });
...@@ -253,8 +253,8 @@ describe('MRWidgetHeader', () => { ...@@ -253,8 +253,8 @@ describe('MRWidgetHeader', () => {
}); });
it('renders diverged commits info', () => { it('renders diverged commits info', () => {
expect(vm.$el.querySelector('.diverged-commits-count').textContent.trim()).toEqual( expect(vm.$el.querySelector('.diverged-commits-count').textContent).toMatch(
'(12 commits behind)', /(mr-widget-refactor[\s\S]+?is 12 commits behind[\s\S]+?master)/,
); );
}); });
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment