Commit f17109c0 authored by Filipa Lacerda's avatar Filipa Lacerda

Load SVGs into Pipelines

parent e5037529
...@@ -11,15 +11,10 @@ $(() => new Vue({ ...@@ -11,15 +11,10 @@ $(() => new Vue({
data() { data() {
const project = document.querySelector('.pipelines'); const project = document.querySelector('.pipelines');
const svgs = document.querySelector('.pipeline-svgs').dataset;
// Transform svgs DOMStringMap to a plain Object.
const svgsObject = gl.utils.DOMStringMapToObject(svgs);
return { return {
scope: project.dataset.url, scope: project.dataset.url,
store: new gl.PipelineStore(), store: new gl.PipelineStore(),
svgs: svgsObject,
}; };
}, },
components: { components: {
...@@ -27,10 +22,8 @@ $(() => new Vue({ ...@@ -27,10 +22,8 @@ $(() => new Vue({
}, },
template: ` template: `
<vue-pipelines <vue-pipelines
:scope='scope' :scope="scope"
:store='store' :store="store">
:svgs='svgs'
>
</vue-pipelines> </vue-pipelines>
`, `,
})); }));
/* global Vue, Flash, gl */ /* global Vue, Flash, gl */
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
const playIconSvg = require('../../../views/shared/icons/_icon_play.svg');
((gl) => { ((gl) => {
gl.VuePipelineActions = Vue.extend({ gl.VuePipelineActions = Vue.extend({
props: ['pipeline', 'svgs'], props: ['pipeline'],
computed: { computed: {
actions() { actions() {
return this.pipeline.details.manual_actions.length > 0; return this.pipeline.details.manual_actions.length > 0;
...@@ -17,6 +18,11 @@ ...@@ -17,6 +18,11 @@
return `Download ${name} artifacts`; return `Download ${name} artifacts`;
}, },
}, },
data() {
return { playIconSvg };
},
template: ` template: `
<td class="pipeline-actions hidden-xs"> <td class="pipeline-actions hidden-xs">
<div class="controls pull-right"> <div class="controls pull-right">
...@@ -30,7 +36,7 @@ ...@@ -30,7 +36,7 @@
data-placement="top" data-placement="top"
aria-label="Manual job" aria-label="Manual job"
> >
<span v-html='svgs.iconPlay' aria-hidden="true"></span> <span v-html="playIconSvg" aria-hidden="true"></span>
<i class="fa fa-caret-down" aria-hidden="true"></i> <i class="fa fa-caret-down" aria-hidden="true"></i>
</button> </button>
<ul class="dropdown-menu dropdown-menu-align-right"> <ul class="dropdown-menu dropdown-menu-align-right">
...@@ -40,7 +46,7 @@ ...@@ -40,7 +46,7 @@
data-method="post" data-method="post"
:href='action.path' :href='action.path'
> >
<span v-html='svgs.iconPlay' aria-hidden="true"></span> <span v-html="playIconSvg" aria-hidden="true"></span>
<span>{{action.name}}</span> <span>{{action.name}}</span>
</a> </a>
</li> </li>
......
...@@ -27,7 +27,7 @@ const CommitPipelinesStoreWithTimeAgo = require('../commit/pipelines/pipelines_s ...@@ -27,7 +27,7 @@ const CommitPipelinesStoreWithTimeAgo = require('../commit/pipelines/pipelines_s
pageRequest: false, pageRequest: false,
}; };
}, },
props: ['scope', 'store', 'svgs'], props: ['scope', 'store'],
created() { created() {
const pagenum = gl.utils.getParameterByName('page'); const pagenum = gl.utils.getParameterByName('page');
const scope = gl.utils.getParameterByName('scope'); const scope = gl.utils.getParameterByName('scope');
...@@ -73,10 +73,7 @@ const CommitPipelinesStoreWithTimeAgo = require('../commit/pipelines/pipelines_s ...@@ -73,10 +73,7 @@ const CommitPipelinesStoreWithTimeAgo = require('../commit/pipelines/pipelines_s
</div> </div>
<div class="table-holder" v-if='!pageRequest && pipelines.length'> <div class="table-holder" v-if='!pageRequest && pipelines.length'>
<pipelines-table-component <pipelines-table-component :pipelines='pipelines'/>
:pipelines='pipelines'
:svgs='svgs'>
</pipelines-table-component>
</div> </div>
<gl-pagination <gl-pagination
......
/* global Vue, Flash, gl */ /* global Vue, Flash, gl */
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
import canceledSvg from '../../../views/shared/icons/_icon_status_canceled_borderless.svg';
import createdSvg from '../../../views/shared/icons/_icon_status_created_borderless.svg';
import failedSvg from '../../../views/shared/icons/_icon_status_failed_borderless.svg';
import manualSvg from '../../../views/shared/icons/_icon_status_manual_borderless.svg';
import pendingSvg from '../../../views/shared/icons/_icon_status_pending_borderless.svg';
import runningSvg from '../../../views/shared/icons/_icon_status_running_borderless.svg';
import skippedSvg from '../../../views/shared/icons/_icon_status_skipped_borderless.svg';
import successSvg from '../../../views/shared/icons/_icon_status_success_borderless.svg';
import warningSvg from '../../../views/shared/icons/_icon_status_warning_borderless.svg';
((gl) => { ((gl) => {
gl.VueStage = Vue.extend({ gl.VueStage = Vue.extend({
data() { data() {
const svgsDictionary = {
icon_status_canceled: canceledSvg,
icon_status_created: createdSvg,
icon_status_failed: failedSvg,
icon_status_manual: manualSvg,
icon_status_pending: pendingSvg,
icon_status_running: runningSvg,
icon_status_skipped: skippedSvg,
icon_status_success: successSvg,
icon_status_warning: warningSvg,
};
return { return {
builds: '', builds: '',
spinner: '<span class="fa fa-spinner fa-spin"></span>', spinner: '<span class="fa fa-spinner fa-spin"></span>',
svg: svgsDictionary[this.stage.status.icon],
}; };
}, },
props: { props: {
stage: { stage: {
type: Object, type: Object,
required: true, required: true,
}, },
svgs: {
type: Object,
required: true,
},
match: {
type: Function,
required: true,
},
}, },
updated() { updated() {
...@@ -73,11 +88,6 @@ ...@@ -73,11 +88,6 @@
tooltip() { tooltip() {
return `has-tooltip ci-status-icon ci-status-icon-${this.stage.status.group}`; return `has-tooltip ci-status-icon ci-status-icon-${this.stage.status.group}`;
}, },
svg() {
const { icon } = this.stage.status;
const stageIcon = icon.replace(/icon/i, 'stage_icon');
return this.svgs[this.match(stageIcon)];
},
triggerButtonClass() { triggerButtonClass() {
return `mini-pipeline-graph-dropdown-toggle has-tooltip js-builds-dropdown-button ci-status-icon-${this.stage.status.group}`; return `mini-pipeline-graph-dropdown-toggle has-tooltip js-builds-dropdown-button ci-status-icon-${this.stage.status.group}`;
}, },
...@@ -91,8 +101,7 @@ ...@@ -91,8 +101,7 @@
data-placement="top" data-placement="top"
data-toggle="dropdown" data-toggle="dropdown"
type="button" type="button"
:aria-label="stage.title" :aria-label="stage.title">
>
<span v-html="svg" aria-hidden="true"></span> <span v-html="svg" aria-hidden="true"></span>
<i class="fa fa-caret-down" aria-hidden="true"></i> <i class="fa fa-caret-down" aria-hidden="true"></i>
</button> </button>
...@@ -101,8 +110,7 @@ ...@@ -101,8 +110,7 @@
<div <div
:class="dropdownClass" :class="dropdownClass"
class="js-builds-dropdown-list scrollable-menu" class="js-builds-dropdown-list scrollable-menu"
v-html="buildsOrSpinner" v-html="buildsOrSpinner">
>
</div> </div>
</ul> </ul>
</div> </div>
......
/* global Vue, gl */ /* global Vue, gl */
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
import canceledSvg from '../../../views/shared/icons/_icon_status_canceled.svg';
import createdSvg from '../../../views/shared/icons/_icon_status_created.svg';
import failedSvg from '../../../views/shared/icons/_icon_status_failed.svg';
import manualSvg from '../../../views/shared/icons/_icon_status_manual.svg';
import pendingSvg from '../../../views/shared/icons/_icon_status_pending.svg';
import runningSvg from '../../../views/shared/icons/_icon_status_running.svg';
import skippedSvg from '../../../views/shared/icons/_icon_status_skipped.svg';
import successSvg from '../../../views/shared/icons/_icon_status_success.svg';
import warningSvg from '../../../views/shared/icons/_icon_status_warning.svg';
((gl) => { ((gl) => {
gl.VueStatusScope = Vue.extend({ gl.VueStatusScope = Vue.extend({
props: [ props: [
'pipeline', 'svgs', 'match', 'pipeline',
], ],
data() {
const svgsDictionary = {
icon_status_canceled: canceledSvg,
icon_status_created: createdSvg,
icon_status_failed: failedSvg,
icon_status_manual: manualSvg,
icon_status_pending: pendingSvg,
icon_status_running: runningSvg,
icon_status_skipped: skippedSvg,
icon_status_success: successSvg,
icon_status_warning: warningSvg,
};
return {
svg: svgsDictionary[this.pipeline.details.status.icon],
};
},
computed: { computed: {
cssClasses() { cssClasses() {
const cssObject = { 'ci-status': true }; const cssObject = { 'ci-status': true };
cssObject[`ci-${this.pipeline.details.status.group}`] = true; cssObject[`ci-${this.pipeline.details.status.group}`] = true;
return cssObject; return cssObject;
}, },
svg() {
return this.svgs[this.match(this.pipeline.details.status.icon)];
},
detailsPath() { detailsPath() {
const { status } = this.pipeline.details; const { status } = this.pipeline.details;
return status.has_details ? status.details_path : false; return status.has_details ? status.details_path : false;
...@@ -25,8 +52,7 @@ ...@@ -25,8 +52,7 @@
<a <a
:class='cssClasses' :class='cssClasses'
:href='detailsPath' :href='detailsPath'
v-html='svg + pipeline.details.status.text' v-html="svg + pipeline.details.status.text">
>
</a> </a>
</td> </td>
`, `,
......
...@@ -4,14 +4,17 @@ ...@@ -4,14 +4,17 @@
window.Vue = require('vue'); window.Vue = require('vue');
require('../lib/utils/datetime_utility'); require('../lib/utils/datetime_utility');
const iconTimerSvg = require('../../../views/shared/icons/_icon_timer.svg');
((gl) => { ((gl) => {
gl.VueTimeAgo = Vue.extend({ gl.VueTimeAgo = Vue.extend({
data() { data() {
return { return {
currentTime: new Date(), currentTime: new Date(),
iconTimerSvg,
}; };
}, },
props: ['pipeline', 'svgs'], props: ['pipeline'],
computed: { computed: {
timeAgo() { timeAgo() {
return gl.utils.getTimeago(); return gl.utils.getTimeago();
...@@ -56,7 +59,7 @@ require('../lib/utils/datetime_utility'); ...@@ -56,7 +59,7 @@ require('../lib/utils/datetime_utility');
template: ` template: `
<td> <td>
<p class="duration" v-if='duration'> <p class="duration" v-if='duration'>
<span v-html='svgs.iconTimer'></span> <span v-html="iconTimerSvg"></span>
{{duration}} {{duration}}
</p> </p>
<p class="finished-at" v-if='timeStopped'> <p class="finished-at" v-if='timeStopped'>
......
...@@ -21,14 +21,6 @@ require('./pipelines_table_row'); ...@@ -21,14 +21,6 @@ require('./pipelines_table_row');
default: () => ([]), default: () => ([]),
}, },
/**
* TODO: Remove this when we have webpack.
*/
svgs: {
type: Object,
required: true,
default: () => ({}),
},
}, },
components: { components: {
...@@ -51,8 +43,7 @@ require('./pipelines_table_row'); ...@@ -51,8 +43,7 @@ require('./pipelines_table_row');
<template v-for="model in pipelines" <template v-for="model in pipelines"
v-bind:model="model"> v-bind:model="model">
<tr is="pipelines-table-row-component" <tr is="pipelines-table-row-component"
:pipeline="model" :pipeline="model"></tr>
:svgs="svgs"></tr>
</template> </template>
</tbody> </tbody>
</table> </table>
......
...@@ -25,14 +25,6 @@ require('./commit'); ...@@ -25,14 +25,6 @@ require('./commit');
default: () => ({}), default: () => ({}),
}, },
/**
* TODO: Remove this when we have webpack;
*/
svgs: {
type: Object,
required: true,
default: () => ({}),
},
}, },
components: { components: {
...@@ -174,30 +166,9 @@ require('./commit'); ...@@ -174,30 +166,9 @@ require('./commit');
}, },
}, },
methods: {
/**
* FIXME: This should not be in this component but in the components that
* need this function.
*
* Used to render SVGs in the following components:
* - status-scope
* - dropdown-stage
*
* @param {String} string
* @return {String}
*/
match(string) {
return string.replace(/_([a-z])/g, (m, w) => w.toUpperCase());
},
},
template: ` template: `
<tr class="commit"> <tr class="commit">
<status-scope <status-scope :pipeline="pipeline"/>
:pipeline="pipeline"
:svgs="svgs"
:match="match">
</status-scope>
<pipeline-url :pipeline="pipeline"></pipeline-url> <pipeline-url :pipeline="pipeline"></pipeline-url>
...@@ -208,26 +179,20 @@ require('./commit'); ...@@ -208,26 +179,20 @@ require('./commit');
:commit-url="commitUrl" :commit-url="commitUrl"
:short-sha="commitShortSha" :short-sha="commitShortSha"
:title="commitTitle" :title="commitTitle"
:author="commitAuthor" :author="commitAuthor"/>
:commit-icon-svg="svgs.commitIconSvg">
</commit-component>
</td> </td>
<td class="stage-cell"> <td class="stage-cell">
<div class="stage-container dropdown js-mini-pipeline-graph" <div class="stage-container dropdown js-mini-pipeline-graph"
v-if="pipeline.details.stages.length > 0" v-if="pipeline.details.stages.length > 0"
v-for="stage in pipeline.details.stages"> v-for="stage in pipeline.details.stages">
<dropdown-stage <dropdown-stage :stage="stage"/>
:stage="stage"
:svgs="svgs"
:match="match">
</dropdown-stage>
</div> </div>
</td> </td>
<time-ago :pipeline="pipeline" :svgs="svgs"></time-ago> <time-ago :pipeline="pipeline"/>
<pipeline-actions :pipeline="pipeline" :svgs="svgs"></pipeline-actions> <pipeline-actions :pipeline="pipeline" />
</tr> </tr>
`, `,
}); });
......
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