summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2017-01-28 20:06:15 +0000
committerFilipa Lacerda <filipa@gitlab.com>2017-02-03 09:43:54 +0000
commit7ef21460d1ad47c1e140b5cf2977ebc90f8c6dd1 (patch)
tree1f757b363eea8f8db08c37d482bcb07deb78d255
parent7ad626e348faaea6f186759dada36079d531f6fd (diff)
downloadgitlab-ce-7ef21460d1ad47c1e140b5cf2977ebc90f8c6dd1.tar.gz
Transform vue_pipelines index into a non-dependent table component.
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es685
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_service.js.es645
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_store.js.es612
-rw-r--r--app/assets/javascripts/vue_pipelines_index/stage.js.es61
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table.js.es6277
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6192
-rw-r--r--app/views/projects/commit/pipelines.html.haml6
7 files changed, 306 insertions, 312 deletions
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6
index d2547f0b4a8..d42f2d15f19 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6
+++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6
@@ -1,11 +1,10 @@
/* eslint-disable no-new */
-/* global Vue, VueResource */
+/* global Vue, CommitsPipelineStore, PipelinesService, Flash */
//= require vue
+//= require_tree .
+//= require vue
//= require vue-resource
-//= require ./pipelines_store
-//= require ./pipelines_service
-//= require vue_shared/components/commit
//= require vue_shared/vue_resource_interceptor
//= require vue_shared/components/pipelines_table
@@ -21,18 +20,23 @@
* Necessary SVG in the table are provided as props. This should be refactored
* as soon as we have Webpack and can load them directly into JS files.
*/
-(() => {
+$(() => {
window.gl = window.gl || {};
- gl.Commits = gl.Commits || {};
+ gl.commits = gl.commits || {};
+ gl.commits.pipelines = gl.commits.pipelines || {};
- if (gl.Commits.PipelinesTableView) {
- gl.Commits.PipelinesTableView.$destroy(true);
+ if (gl.commits.PipelinesTableView) {
+ gl.commits.PipelinesTableView.$destroy(true);
}
- gl.Commits.PipelinesTableView = new Vue({
+ gl.commits.pipelines.PipelinesTableView = new Vue({
el: document.querySelector('#commit-pipeline-table-view'),
+ components: {
+ 'pipelines-table-component': gl.pipelines.PipelinesTableComponent,
+ },
+
/**
* Accesses the DOM to provide the needed data.
* Returns the necessary props to render `pipelines-table-component` component.
@@ -41,21 +45,70 @@
*/
data() {
const pipelinesTableData = document.querySelector('#commit-pipeline-table-view').dataset;
+ const svgsData = document.querySelector('.pipeline-svgs').dataset;
+ const store = gl.commits.pipelines.PipelinesStore.create();
+
+ // Transform svgs DOMStringMap to a plain Object.
+ const svgsObject = Object.keys(svgsData).reduce((acc, element) => {
+ acc[element] = svgsData[element];
+ return acc;
+ }, {});
return {
- scope: pipelinesTableData.pipelinesData,
- store: new CommitsPipelineStore(),
- service: new PipelinesService(),
- svgs: pipelinesTableData,
+ endpoint: pipelinesTableData.pipelinesData,
+ svgs: svgsObject,
+ store,
+ state: store.state,
+ isLoading: false,
};
},
- components: {
- 'pipelines-table-component': gl.pipelines.PipelinesTableComponent,
+ /**
+ * When the component is created the service to fetch the data will be
+ * initialized with the correct endpoint.
+ *
+ * A request to fetch the pipelines will be made.
+ * In case of a successfull response we will store the data in the provided
+ * store, in case of a failed response we need to warn the user.
+ *
+ */
+ created() {
+ gl.pipelines.pipelinesService = new PipelinesService(this.endpoint);
+
+ this.isLoading = true;
+
+ return gl.pipelines.pipelinesService.all()
+ .then(response => response.json())
+ .then((json) => {
+ this.store.store(json);
+ this.isLoading = false;
+ }).catch(() => {
+ this.isLoading = false;
+ new Flash('An error occurred while fetching the pipelines.', 'alert');
+ });
},
template: `
- <pipelines-table-component :scope='scope' :store='store' :svgs='svgs'></pipelines-table-component>
+ <div>
+ <div class="pipelines realtime-loading" v-if='isLoading'>
+ <i class="fa fa-spinner fa-spin"></i>
+ </div>
+
+ <div class="blank-state blank-state-no-icon"
+ v-if="!isLoading && state.pipelines.length === 0">
+ <h2 class="blank-state-title js-blank-state-title">
+ You don't have any pipelines.
+ </h2>
+ Put get started with pipelines button here!!!
+ </div>
+
+ <div class="table-holder" v-if='!isLoading && state.pipelines.length > 0'>
+ <pipelines-table-component
+ :pipelines='state.pipelines'
+ :svgs='svgs'>
+ </pipelines-table-component>
+ </div>
+ </div>
`,
});
});
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_service.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_service.js.es6
index 7d773e0d361..1e6aa73d9cf 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_service.js.es6
+++ b/app/assets/javascripts/commit/pipelines/pipelines_service.js.es6
@@ -5,12 +5,8 @@
* Pipelines service.
*
* Used to fetch the data used to render the pipelines table.
- * Used Vue.Resource
+ * Uses Vue.Resource
*/
-
-window.gl = window.gl || {};
-gl.pipelines = gl.pipelines || {};
-
class PipelinesService {
constructor(root) {
Vue.http.options.root = root;
@@ -36,42 +32,3 @@ class PipelinesService {
return this.pipelines.get();
}
}
-
-gl.pipelines.PipelinesService = PipelinesService;
-
-// const pageValues = (headers) => {
-// const normalized = gl.utils.normalizeHeaders(headers);
-//
-// const paginationInfo = {
-// perPage: +normalized['X-PER-PAGE'],
-// page: +normalized['X-PAGE'],
-// total: +normalized['X-TOTAL'],
-// totalPages: +normalized['X-TOTAL-PAGES'],
-// nextPage: +normalized['X-NEXT-PAGE'],
-// previousPage: +normalized['X-PREV-PAGE'],
-// };
-//
-// return paginationInfo;
-// };
-
-// gl.PipelineStore = class {
-// fetchDataLoop(Vue, pageNum, url, apiScope) {
-// const goFetch = () =>
-// this.$http.get(`${url}?scope=${apiScope}&page=${pageNum}`)
-// .then((response) => {
-// const pageInfo = pageValues(response.headers);
-// this.pageInfo = Object.assign({}, this.pageInfo, pageInfo);
-//
-// const res = JSON.parse(response.body);
-// this.count = Object.assign({}, this.count, res.count);
-// this.pipelines = Object.assign([], this.pipelines, res);
-//
-// this.pageRequest = false;
-// }, () => {
-// this.pageRequest = false;
-// return new Flash('Something went wrong on our end.');
-// });
-//
-// goFetch();
-// }
-// };
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_store.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_store.js.es6
index bc748bece5d..5c2e1b33cd1 100644
--- a/app/assets/javascripts/commit/pipelines/pipelines_store.js.es6
+++ b/app/assets/javascripts/commit/pipelines/pipelines_store.js.es6
@@ -6,12 +6,14 @@
* Pipelines' Store for commits view.
*
* Used to store the Pipelines rendered in the commit view in the pipelines table.
- *
- * TODO: take care of timeago instances in here
*/
(() => {
- const CommitPipelineStore = {
+ window.gl = window.gl || {};
+ gl.commits = gl.commits || {};
+ gl.commits.pipelines = gl.commits.pipelines || {};
+
+ gl.commits.pipelines.PipelinesStore = {
state: {},
create() {
@@ -20,11 +22,9 @@
return this;
},
- storePipelines(pipelines = []) {
+ store(pipelines = []) {
this.state.pipelines = pipelines;
return pipelines;
},
};
-
- return CommitPipelineStore;
})();
diff --git a/app/assets/javascripts/vue_pipelines_index/stage.js.es6 b/app/assets/javascripts/vue_pipelines_index/stage.js.es6
index 496df9aaced..572644c8e6e 100644
--- a/app/assets/javascripts/vue_pipelines_index/stage.js.es6
+++ b/app/assets/javascripts/vue_pipelines_index/stage.js.es6
@@ -14,6 +14,7 @@
type: Object,
required: true,
},
+ //FIXME: DOMStringMap is non standard, let's use a plain object.
svgs: {
type: DOMStringMap,
required: true,
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 b/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6
index f602a0c44c2..e606632306f 100644
--- a/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6
+++ b/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6
@@ -1,14 +1,14 @@
-/* eslint-disable no-param-reassign, no-new */
+/* eslint-disable no-param-reassign */
/* global Vue */
-/* global PipelinesService */
-/* global Flash */
-//= require vue_pipelines_index/status.js.es6
-//= require vue_pipelines_index/pipeline_url.js.es6
-//= require vue_pipelines_index/stage.js.es6
-//= require vue_pipelines_index/pipeline_actions.js.es6
-//= require vue_pipelines_index/time_ago.js.es6
-//= require vue_pipelines_index/pipelines.js.es6
+//=require ./pipelines_table_row
+
+/**
+ * Pipelines Table Component
+ *
+ * Given an array of pipelines, renders a table.
+ *
+ */
(() => {
window.gl = window.gl || {};
@@ -17,31 +17,10 @@
gl.pipelines.PipelinesTableComponent = Vue.component('pipelines-table-component', {
props: {
-
- /**
- * Object used to store the Pipelines to render.
- * It's passed as a prop to allow different stores to use this Component.
- * Different API calls can result in different responses, using a custom
- * store allows us to use the same pipeline component.
- *
- * Note: All provided stores need to have a `storePipelines` method.
- * Find a better way to do this.
- */
- store: {
- type: Object,
- required: true,
- default: () => ({}),
- },
-
- /**
- * Will be used to fetch the needed data.
- * This component is used in different and therefore different API calls
- * to different endpoints will be made. To guarantee this is a reusable
- * component, the endpoint must be provided.
- */
- endpoint: {
- type: String,
+ pipelines: {
+ type: Array,
required: true,
+ default: [],
},
/**
@@ -55,219 +34,31 @@
},
components: {
- 'commit-component': gl.CommitComponent,
- runningPipeline: gl.VueRunningPipeline,
- pipelineActions: gl.VuePipelineActions,
- 'vue-stage': gl.VueStage,
- pipelineUrl: gl.VuePipelineUrl,
- pipelineHead: gl.VuePipelineHead,
- statusScope: gl.VueStatusScope,
+ 'pipelines-table-row-component': gl.pipelines.PipelinesTableRowComponent,
},
- data() {
- return {
- state: this.store.state,
- isLoading: false,
- };
- },
-
- computed: {
- /**
- * If provided, returns the commit tag.
- *
- * @returns {Object|Undefined}
- */
- commitAuthor() {
- if (this.pipeline &&
- this.pipeline.commit &&
- this.pipeline.commit.author) {
- return this.pipeline.commit.author;
- }
-
- return undefined;
- },
-
- /**
- * If provided, returns the commit tag.
- *
- * @returns {String|Undefined}
- */
- commitTag() {
- if (this.model.last_deployment &&
- this.model.last_deployment.tag) {
- return this.model.last_deployment.tag;
- }
- return undefined;
- },
-
- /**
- * If provided, returns the commit ref.
- *
- * @returns {Object|Undefined}
- */
- commitRef() {
- if (this.pipeline.ref) {
- return Object.keys(this.pipeline.ref).reduce((accumulator, prop) => {
- if (prop === 'url') {
- accumulator.path = this.pipeline.ref[prop];
- } else {
- accumulator[prop] = this.pipeline.ref[prop];
- }
- return accumulator;
- }, {});
- }
-
- return undefined;
- },
-
- /**
- * If provided, returns the commit url.
- *
- * @returns {String|Undefined}
- */
- commitUrl() {
- if (this.pipeline.commit &&
- this.pipeline.commit.commit_path) {
- return this.pipeline.commit.commit_path;
- }
- return undefined;
- },
-
- /**
- * If provided, returns the commit short sha.
- *
- * @returns {String|Undefined}
- */
- commitShortSha() {
- if (this.pipeline.commit &&
- this.pipeline.commit.short_id) {
- return this.pipeline.commit.short_id;
- }
- return undefined;
- },
-
- /**
- * If provided, returns the commit title.
- *
- * @returns {String|Undefined}
- */
- commitTitle() {
- if (this.pipeline.commit &&
- this.pipeline.commit.title) {
- return this.pipeline.commit.title;
- }
- return undefined;
- },
-
- /**
- * Figure this out!
- */
- author(pipeline) {
- if (!pipeline.commit) return { avatar_url: '', web_url: '', username: '' };
- if (pipeline.commit.author) return pipeline.commit.author;
- return {
- avatar_url: pipeline.commit.author_gravatar_url,
- web_url: `mailto:${pipeline.commit.author_email}`,
- username: pipeline.commit.author_name,
- };
- },
-
- /**
- * Figure this out
- */
- match(string) {
- return string.replace(/_([a-z])/g, (m, w) => w.toUpperCase());
- },
- },
-
- /**
- * When the component is created the service to fetch the data will be
- * initialized with the correct endpoint.
- *
- * A request to fetch the pipelines will be made.
- * In case of a successfull response we will store the data in the provided
- * store, in case of a failed response we need to warn the user.
- *
- */
- created() {
- gl.pipelines.pipelinesService = new PipelinesService(this.endpoint);
-
- this.isLoading = true;
-
- return gl.pipelines.pipelinesService.all()
- .then(resp => resp.json())
- .then((json) => {
- this.store.storePipelines(json);
- this.isLoading = false;
- }).catch(() => {
- this.isLoading = false;
- new Flash('An error occurred while fetching the pipelines.', 'alert');
- });
- },
- // this need to be reusable between the 3 tables :/
template: `
- <div>
- <div class="pipelines realtime-loading" v-if='isLoading'>
- <i class="fa fa-spinner fa-spin"></i>
- </div>
-
-
- <div class="blank-state blank-state-no-icon"
- v-if="!isLoading && state.pipelines.length === 0">
- <h2 class="blank-state-title js-blank-state-title">
- You don't have any pipelines.
- </h2>
- Put get started with pipelines button here!!!
- </div>
-
- <div class="table-holder" v-if='!isLoading state.pipelines.length > 0'>
- <table class="table ci-table">
- <thead>
- <tr>
- <th class="pipeline-status">Status</th>
- <th class="pipeline-info">Pipeline</th>
- <th class="pipeline-commit">Commit</th>
- <th class="pipeline-stages">Stages</th>
- <th class="pipeline-date"></th>
- <th class="pipeline-actions hidden-xs"></th>
- </tr>
- </thead>
- <tbody>
- <tr class="commit" v-for='pipeline in state.pipelines'>
- <status-scope
- :pipeline='pipeline'
- :match='match'
- :svgs='svgs'>
- </status-scope>
-
- <pipeline-url :pipeline='pipeline'></pipeline-url>
-
- <td>
- <commit-component
- :tag="commitTag"
- :commit-ref="commitRef"
- :commit-url="commitUrl"
- :short-sha="commitShortSha"
- :title="commitTitle"
- :author="commitAuthor"
- :commit-icon-svg="commitIconSvg">
- </commit-component>
- </td>
-
- <td class="stage-cell">
- <div class="stage-container dropdown js-mini-pipeline-graph" v-for='stage in pipeline.details.stages'>
- <vue-stage :stage='stage' :svgs='svgs' :match='match'></vue-stage>
- </div>
- </td>
-
- <time-ago :pipeline='pipeline' :svgs='svgs'></time-ago>
-
- <pipeline-actions :pipeline='pipeline' :svgs='svgs'></pipeline-actions>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
+ <table class="table ci-table">
+ <thead>
+ <tr>
+ <th class="pipeline-status">Status</th>
+ <th class="pipeline-info">Pipeline</th>
+ <th class="pipeline-commit">Commit</th>
+ <th class="pipeline-stages">Stages</th>
+ <th class="pipeline-date"></th>
+ <th class="pipeline-actions hidden-xs"></th>
+ </tr>
+ </thead>
+ <tbody>
+ <template v-for="model in pipelines"
+ v-bind:model="model">
+ <tr
+ is="pipelines-table-row-component"
+ :pipeline="model"
+ :svgs="svgs"></tr>
+ </template>
+ </tbody>
+ </table>
`,
});
})();
diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6 b/app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6
new file mode 100644
index 00000000000..1e55cce1c41
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6
@@ -0,0 +1,192 @@
+/* eslint-disable no-param-reassign */
+/* global Vue */
+
+//= require vue_pipelines_index/status
+//= require vue_pipelines_index/pipeline_url
+//= require vue_pipelines_index/stage
+//= require vue_shared/components/commit
+//= require vue_pipelines_index/pipeline_actions
+//= require vue_pipelines_index/time_ago
+(() => {
+ window.gl = window.gl || {};
+ gl.pipelines = gl.pipelines || {};
+
+ gl.pipelines.PipelinesTableRowComponent = Vue.component('pipelines-table-row-component', {
+
+ props: {
+ pipeline: {
+ type: Object,
+ required: true,
+ default: () => ({}),
+ },
+
+ /**
+ * Remove this. Find a better way to do this. don't want to provide this 3 times.
+ */
+ svgs: {
+ type: Object,
+ required: true,
+ default: () => ({}),
+ },
+ },
+
+ components: {
+ 'commit-component': gl.CommitComponent,
+ runningPipeline: gl.VueRunningPipeline,
+ pipelineActions: gl.VuePipelineActions,
+ 'vue-stage': gl.VueStage,
+ pipelineUrl: gl.VuePipelineUrl,
+ pipelineHead: gl.VuePipelineHead,
+ statusScope: gl.VueStatusScope,
+ },
+
+ computed: {
+ /**
+ * If provided, returns the commit tag.
+ * Needed to render the commit component column.
+ *
+ * @returns {Object|Undefined}
+ */
+ commitAuthor() {
+ if (this.pipeline &&
+ this.pipeline.commit &&
+ this.pipeline.commit.author) {
+ return this.pipeline.commit.author;
+ }
+
+ return undefined;
+ },
+
+ /**
+ * If provided, returns the commit tag.
+ * Needed to render the commit component column.
+ *
+ * @returns {String|Undefined}
+ */
+ commitTag() {
+ // if (this.model.last_deployment &&
+ // this.model.last_deployment.tag) {
+ // return this.model.last_deployment.tag;
+ // }
+ return undefined;
+ },
+
+ /**
+ * If provided, returns the commit ref.
+ * Needed to render the commit component column.
+ *
+ * @returns {Object|Undefined}
+ */
+ commitRef() {
+ if (this.pipeline.ref) {
+ return Object.keys(this.pipeline.ref).reduce((accumulator, prop) => {
+ if (prop === 'url') {
+ accumulator.path = this.pipeline.ref[prop];
+ } else {
+ accumulator[prop] = this.pipeline.ref[prop];
+ }
+ return accumulator;
+ }, {});
+ }
+
+ return undefined;
+ },
+
+ /**
+ * If provided, returns the commit url.
+ * Needed to render the commit component column.
+ *
+ * @returns {String|Undefined}
+ */
+ commitUrl() {
+ if (this.pipeline.commit &&
+ this.pipeline.commit.commit_path) {
+ return this.pipeline.commit.commit_path;
+ }
+ return undefined;
+ },
+
+ /**
+ * If provided, returns the commit short sha.
+ * Needed to render the commit component column.
+ *
+ * @returns {String|Undefined}
+ */
+ commitShortSha() {
+ if (this.pipeline.commit &&
+ this.pipeline.commit.short_id) {
+ return this.pipeline.commit.short_id;
+ }
+ return undefined;
+ },
+
+ /**
+ * If provided, returns the commit title.
+ * Needed to render the commit component column.
+ *
+ * @returns {String|Undefined}
+ */
+ commitTitle() {
+ if (this.pipeline.commit &&
+ this.pipeline.commit.title) {
+ return this.pipeline.commit.title;
+ }
+ return undefined;
+ },
+
+ /**
+ * Figure this out!
+ * Needed to render the commit component column.
+ */
+ author(pipeline) {
+ if (!pipeline.commit) return { avatar_url: '', web_url: '', username: '' };
+ if (pipeline.commit.author) return pipeline.commit.author;
+ return {
+ avatar_url: pipeline.commit.author_gravatar_url,
+ web_url: `mailto:${pipeline.commit.author_email}`,
+ username: pipeline.commit.author_name,
+ };
+ },
+ },
+
+ methods: {
+ match(string) {
+ return string.replace(/_([a-z])/g, (m, w) => w.toUpperCase());
+ },
+ },
+
+ template: `
+ <tr class="commit">
+ <status-scope
+ :pipeline='pipeline'
+ :svgs='svgs'
+ :match="match">
+ </status-scope>
+
+ <pipeline-url :pipeline='pipeline'></pipeline-url>
+
+ <td>
+ <commit-component
+ :tag="commitTag"
+ :commit-ref="commitRef"
+ :commit-url="commitUrl"
+ :short-sha="commitShortSha"
+ :title="commitTitle"
+ :author="commitAuthor"
+ :commit-icon-svg="svgs.commitIconSvg">
+ </commit-component>
+ </td>
+
+ <td class="stage-cell">
+ <div class="stage-container dropdown js-mini-pipeline-graph" v-for='stage in pipeline.details.stages'>
+ <vue-stage :stage='stage' :svgs='svgs' :match='match'></vue-stage>
+ </div>
+ </td>
+
+ <time-ago :pipeline='pipeline' :svgs='svgs'></time-ago>
+
+ <pipeline-actions :pipeline='pipeline' :svgs='svgs'></pipeline-actions>
+ </tr>
+ `,
+ });
+})();
diff --git a/app/views/projects/commit/pipelines.html.haml b/app/views/projects/commit/pipelines.html.haml
index 09bd4288b9c..f62fbe4d9cd 100644
--- a/app/views/projects/commit/pipelines.html.haml
+++ b/app/views/projects/commit/pipelines.html.haml
@@ -3,9 +3,6 @@
= render 'commit_box'
= render 'ci_menu'
-- content_for :page_specific_javascripts do
- = page_specific_javascript_tag("commit/pipelines/pipelines_bundle.js")
-
#commit-pipeline-table-view{ data: { pipelines_data: pipelines_namespace_project_commit_path(@project.namespace, @project, @commit.id)}}
.pipeline-svgs{ data: { "commit_icon_svg" => custom_icon("icon_commit"),
"icon_status_canceled" => custom_icon("icon_status_canceled"),
@@ -28,3 +25,6 @@
"icon_timer" => custom_icon("icon_timer"),
"icon_status_manual" => custom_icon("icon_status_manual"),
} }
+
+- content_for :page_specific_javascripts do
+ = page_specific_javascript_tag('commit/pipelines/pipelines_bundle.js')