From b0f2cbceb3b881854de8c36be848d43a5b32a484 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Fri, 17 Mar 2017 17:30:32 +0000 Subject: [PATCH] Remove UJS actions from pipelines tables --- .../commit/pipelines/pipelines_bundle.js | 9 +- .../commit/pipelines/pipelines_service.js | 44 -- .../commit/pipelines/pipelines_table.js | 150 +++---- .../environments/components/environment.js | 14 +- .../components/environment_item.js | 8 +- .../components/environments_table.js | 4 +- .../folder/environments_folder_view.js | 15 +- .../services/environments_service.js | 3 + .../environments/stores/environments_store.js | 1 - .../components/async_button.js | 92 +++++ .../components/pipeline_url.js | 56 +++ .../components/pipelines_actions.js | 71 ++++ .../components/pipelines_artifacts.js | 32 ++ .../vue_pipelines_index/components/stage.js | 116 ++++++ .../vue_pipelines_index/components/status.js | 60 +++ .../components/time_ago.js | 71 ++++ .../vue_pipelines_index/event_hub.js | 3 + .../javascripts/vue_pipelines_index/index.js | 23 +- .../vue_pipelines_index/pipeline_actions.js | 123 ------ .../vue_pipelines_index/pipeline_url.js | 63 --- .../vue_pipelines_index/pipelines.js | 190 +++++---- .../services/pipelines_service.js | 44 ++ .../javascripts/vue_pipelines_index/stage.js | 119 ------ .../javascripts/vue_pipelines_index/status.js | 64 --- .../javascripts/vue_pipelines_index/store.js | 31 -- .../stores}/pipelines_store.js | 35 +- .../vue_pipelines_index/time_ago.js | 78 ---- .../vue_shared/components/commit.js | 293 +++++++------- .../vue_shared/components/pipelines_table.js | 80 ++-- .../components/pipelines_table_row.js | 377 ++++++++++-------- .../vue_shared/components/table_pagination.js | 264 ++++++------ .../vue_shared/vue_resource_interceptor.js | 10 +- app/assets/stylesheets/pages/pipelines.scss | 24 +- .../unreleased/fl-remove-ujs-pipelines.yml | 4 + .../merge_requests/created_from_fork_spec.rb | 3 - .../projects/pipelines/pipelines_spec.rb | 32 +- .../javascripts/commit/pipelines/mock_data.js | 5 +- .../commit/pipelines/pipelines_spec.js | 17 +- .../commit/pipelines/pipelines_store_spec.js | 33 -- .../vue_pipelines_index/async_button_spec.js | 93 +++++ .../vue_pipelines_index/pipeline_url_spec.js | 100 +++++ .../pipelines_actions_spec.js | 62 +++ .../pipelines_artifacts_spec.js | 40 ++ .../pipelines_store_spec.js | 72 ++++ .../vue_shared/components/commit_spec.js | 27 +- .../components/pipelines_table_row_spec.js | 14 +- .../components/pipelines_table_spec.js | 31 +- .../components/table_pagination_spec.js | 52 +-- 48 files changed, 1781 insertions(+), 1371 deletions(-) delete mode 100644 app/assets/javascripts/commit/pipelines/pipelines_service.js create mode 100644 app/assets/javascripts/vue_pipelines_index/components/async_button.js create mode 100644 app/assets/javascripts/vue_pipelines_index/components/pipeline_url.js create mode 100644 app/assets/javascripts/vue_pipelines_index/components/pipelines_actions.js create mode 100644 app/assets/javascripts/vue_pipelines_index/components/pipelines_artifacts.js create mode 100644 app/assets/javascripts/vue_pipelines_index/components/stage.js create mode 100644 app/assets/javascripts/vue_pipelines_index/components/status.js create mode 100644 app/assets/javascripts/vue_pipelines_index/components/time_ago.js create mode 100644 app/assets/javascripts/vue_pipelines_index/event_hub.js delete mode 100644 app/assets/javascripts/vue_pipelines_index/pipeline_actions.js delete mode 100644 app/assets/javascripts/vue_pipelines_index/pipeline_url.js create mode 100644 app/assets/javascripts/vue_pipelines_index/services/pipelines_service.js delete mode 100644 app/assets/javascripts/vue_pipelines_index/stage.js delete mode 100644 app/assets/javascripts/vue_pipelines_index/status.js delete mode 100644 app/assets/javascripts/vue_pipelines_index/store.js rename app/assets/javascripts/{commit/pipelines => vue_pipelines_index/stores}/pipelines_store.js (62%) delete mode 100644 app/assets/javascripts/vue_pipelines_index/time_ago.js create mode 100644 changelogs/unreleased/fl-remove-ujs-pipelines.yml delete mode 100644 spec/javascripts/commit/pipelines/pipelines_store_spec.js create mode 100644 spec/javascripts/vue_pipelines_index/async_button_spec.js create mode 100644 spec/javascripts/vue_pipelines_index/pipeline_url_spec.js create mode 100644 spec/javascripts/vue_pipelines_index/pipelines_actions_spec.js create mode 100644 spec/javascripts/vue_pipelines_index/pipelines_artifacts_spec.js create mode 100644 spec/javascripts/vue_pipelines_index/pipelines_store_spec.js diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js index b5a988df897..a9f2d462c31 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js +++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js @@ -1,8 +1,9 @@ -/* eslint-disable no-new, no-param-reassign */ -/* global Vue, CommitsPipelineStore, PipelinesService, Flash */ +/* eslint-disable no-param-reassign */ +import CommitPipelinesTable from './pipelines_table'; window.Vue = require('vue'); -require('./pipelines_table'); +window.Vue.use(require('vue-resource')); + /** * Commits View > Pipelines Tab > Pipelines Table. * Merge Request View > Pipelines Tab > Pipelines Table. @@ -21,7 +22,7 @@ $(() => { } const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view'); - gl.commits.pipelines.PipelinesTableBundle = new gl.commits.pipelines.PipelinesTableView(); + gl.commits.pipelines.PipelinesTableBundle = new CommitPipelinesTable(); if (pipelineTableViewEl && pipelineTableViewEl.dataset.disableInitialization === undefined) { gl.commits.pipelines.PipelinesTableBundle.$mount(pipelineTableViewEl); diff --git a/app/assets/javascripts/commit/pipelines/pipelines_service.js b/app/assets/javascripts/commit/pipelines/pipelines_service.js deleted file mode 100644 index 8ae98f9bf97..00000000000 --- a/app/assets/javascripts/commit/pipelines/pipelines_service.js +++ /dev/null @@ -1,44 +0,0 @@ -/* globals Vue */ -/* eslint-disable no-unused-vars, no-param-reassign */ - -/** - * Pipelines service. - * - * Used to fetch the data used to render the pipelines table. - * Uses Vue.Resource - */ -class PipelinesService { - - /** - * FIXME: The url provided to request the pipelines in the new merge request - * page already has `.json`. - * This should be fixed when the endpoint is improved. - * - * @param {String} root - */ - constructor(root) { - let endpoint; - - if (root.indexOf('.json') === -1) { - endpoint = `${root}.json`; - } else { - endpoint = root; - } - this.pipelines = Vue.resource(endpoint); - } - - /** - * Given the root param provided when the class is initialized, will - * make a GET request. - * - * @return {Promise} - */ - all() { - return this.pipelines.get(); - } -} - -window.gl = window.gl || {}; -gl.commits = gl.commits || {}; -gl.commits.pipelines = gl.commits.pipelines || {}; -gl.commits.pipelines.PipelinesService = PipelinesService; diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js b/app/assets/javascripts/commit/pipelines/pipelines_table.js index 631ed34851c..832c4b1bd2a 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_table.js +++ b/app/assets/javascripts/commit/pipelines/pipelines_table.js @@ -1,13 +1,12 @@ -/* eslint-disable no-new, no-param-reassign */ -/* global Vue, CommitsPipelineStore, PipelinesService, Flash */ - -window.Vue = require('vue'); -window.Vue.use(require('vue-resource')); -require('../../lib/utils/common_utils'); -require('../../vue_shared/vue_resource_interceptor'); -require('../../vue_shared/components/pipelines_table'); -require('./pipelines_service'); -const PipelineStore = require('./pipelines_store'); +/* eslint-disable no-new*/ +/* global Flash */ +import Vue from 'vue'; +import PipelinesTableComponent from '../../vue_shared/components/pipelines_table'; +import PipelinesService from '../../vue_pipelines_index/services/pipelines_service'; +import PipelineStore from '../../vue_pipelines_index/stores/pipelines_store'; +import eventHub from '../../vue_pipelines_index/event_hub'; +import '../../lib/utils/common_utils'; +import '../../vue_shared/vue_resource_interceptor'; /** * @@ -20,48 +19,59 @@ const PipelineStore = require('./pipelines_store'); * as soon as we have Webpack and can load them directly into JS files. */ -(() => { - window.gl = window.gl || {}; - gl.commits = gl.commits || {}; - gl.commits.pipelines = gl.commits.pipelines || {}; +export default Vue.component('pipelines-table', { + components: { + 'pipelines-table-component': PipelinesTableComponent, + }, - gl.commits.pipelines.PipelinesTableView = Vue.component('pipelines-table', { + /** + * Accesses the DOM to provide the needed data. + * Returns the necessary props to render `pipelines-table-component` component. + * + * @return {Object} + */ + data() { + const pipelinesTableData = document.querySelector('#commit-pipeline-table-view').dataset; + const store = new PipelineStore(); - components: { - 'pipelines-table-component': gl.pipelines.PipelinesTableComponent, - }, + return { + endpoint: pipelinesTableData.endpoint, + store, + state: store.state, + isLoading: false, + }; + }, - /** - * Accesses the DOM to provide the needed data. - * Returns the necessary props to render `pipelines-table-component` component. - * - * @return {Object} - */ - data() { - const pipelinesTableData = document.querySelector('#commit-pipeline-table-view').dataset; - const store = new PipelineStore(); + /** + * When the component is about to be mounted, tell the service to fetch the data + * + * 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. + * + */ + beforeMount() { + this.service = new PipelinesService(this.endpoint); - return { - endpoint: pipelinesTableData.endpoint, - store, - state: store.state, - isLoading: false, - }; - }, + this.fetchPipelines(); - /** - * When the component is about to be mounted, tell the service to fetch the data - * - * 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. - * - */ - beforeMount() { - const pipelinesService = new gl.commits.pipelines.PipelinesService(this.endpoint); + eventHub.$on('refreshPipelines', this.fetchPipelines); + }, + beforeUpdate() { + if (this.state.pipelines.length && this.$children) { + this.store.startTimeAgoLoops.call(this, Vue); + } + }, + + beforeDestroyed() { + eventHub.$off('refreshPipelines'); + }, + + methods: { + fetchPipelines() { this.isLoading = true; - return pipelinesService.all() + return this.service.getPipelines() .then(response => response.json()) .then((json) => { // depending of the endpoint the response can either bring a `pipelines` key or not. @@ -71,34 +81,30 @@ const PipelineStore = require('./pipelines_store'); }) .catch(() => { this.isLoading = false; - new Flash('An error occurred while fetching the pipelines, please reload the page again.', 'alert'); + new Flash('An error occurred while fetching the pipelines, please reload the page again.'); }); }, + }, - beforeUpdate() { - if (this.state.pipelines.length && this.$children) { - PipelineStore.startTimeAgoLoops.call(this, Vue); - } - }, - - template: ` -
-
- -
- -
-

- No pipelines to show -

-
- -
- -
+ template: ` +
+
+
- `, - }); -})(); + +
+

+ No pipelines to show +

+
+ +
+ +
+
+ `, +}); diff --git a/app/assets/javascripts/environments/components/environment.js b/app/assets/javascripts/environments/components/environment.js index 0923ce6b550..51aab8460f6 100644 --- a/app/assets/javascripts/environments/components/environment.js +++ b/app/assets/javascripts/environments/components/environment.js @@ -1,21 +1,18 @@ -/* eslint-disable no-param-reassign, no-new */ +/* eslint-disable no-new */ /* global Flash */ +import Vue from 'vue'; import EnvironmentsService from '../services/environments_service'; import EnvironmentTable from './environments_table'; import EnvironmentsStore from '../stores/environments_store'; +import TablePaginationComponent from '../../vue_shared/components/table_pagination'; +import '../../lib/utils/common_utils'; import eventHub from '../event_hub'; -const Vue = window.Vue = require('vue'); -window.Vue.use(require('vue-resource')); -require('../../vue_shared/components/table_pagination'); -require('../../lib/utils/common_utils'); -require('../../vue_shared/vue_resource_interceptor'); - export default Vue.component('environment-component', { components: { 'environment-table': EnvironmentTable, - 'table-pagination': gl.VueGlPagination, + 'table-pagination': TablePaginationComponent, }, data() { @@ -59,7 +56,6 @@ export default Vue.component('environment-component', { canCreateEnvironmentParsed() { return gl.utils.convertPermissionToBoolean(this.canCreateEnvironment); }, - }, /** diff --git a/app/assets/javascripts/environments/components/environment_item.js b/app/assets/javascripts/environments/components/environment_item.js index 93919d41c60..66ed10e19d1 100644 --- a/app/assets/javascripts/environments/components/environment_item.js +++ b/app/assets/javascripts/environments/components/environment_item.js @@ -1,24 +1,22 @@ import Timeago from 'timeago.js'; +import '../../lib/utils/text_utility'; import ActionsComponent from './environment_actions'; import ExternalUrlComponent from './environment_external_url'; import StopComponent from './environment_stop'; import RollbackComponent from './environment_rollback'; import TerminalButtonComponent from './environment_terminal_button'; -import '../../lib/utils/text_utility'; -import '../../vue_shared/components/commit'; +import CommitComponent from '../../vue_shared/components/commit'; /** * Envrionment Item Component * * Renders a table row for each environment. */ - const timeagoInstance = new Timeago(); export default { - components: { - 'commit-component': gl.CommitComponent, + 'commit-component': CommitComponent, 'actions-component': ActionsComponent, 'external-url-component': ExternalUrlComponent, 'stop-component': StopComponent, diff --git a/app/assets/javascripts/environments/components/environments_table.js b/app/assets/javascripts/environments/components/environments_table.js index 5f07b612b91..338dff40bc9 100644 --- a/app/assets/javascripts/environments/components/environments_table.js +++ b/app/assets/javascripts/environments/components/environments_table.js @@ -1,11 +1,11 @@ /** * Render environments table. */ -import EnvironmentItem from './environment_item'; +import EnvironmentTableRowComponent from './environment_item'; export default { components: { - 'environment-item': EnvironmentItem, + 'environment-item': EnvironmentTableRowComponent, }, props: { diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.js b/app/assets/javascripts/environments/folder/environments_folder_view.js index 7abcf6dbbea..8abbcf0c227 100644 --- a/app/assets/javascripts/environments/folder/environments_folder_view.js +++ b/app/assets/javascripts/environments/folder/environments_folder_view.js @@ -1,20 +1,17 @@ -/* eslint-disable no-param-reassign, no-new */ +/* eslint-disable no-new */ /* global Flash */ +import Vue from 'vue'; import EnvironmentsService from '../services/environments_service'; import EnvironmentTable from '../components/environments_table'; import EnvironmentsStore from '../stores/environments_store'; - -const Vue = window.Vue = require('vue'); -window.Vue.use(require('vue-resource')); -require('../../vue_shared/components/table_pagination'); -require('../../lib/utils/common_utils'); -require('../../vue_shared/vue_resource_interceptor'); +import TablePaginationComponent from '../../vue_shared/components/table_pagination'; +import '../../lib/utils/common_utils'; +import '../../vue_shared/vue_resource_interceptor'; export default Vue.component('environment-folder-view', { - components: { 'environment-table': EnvironmentTable, - 'table-pagination': gl.VueGlPagination, + 'table-pagination': TablePaginationComponent, }, data() { diff --git a/app/assets/javascripts/environments/services/environments_service.js b/app/assets/javascripts/environments/services/environments_service.js index 76296c83d11..07040bf0d73 100644 --- a/app/assets/javascripts/environments/services/environments_service.js +++ b/app/assets/javascripts/environments/services/environments_service.js @@ -1,5 +1,8 @@ /* eslint-disable class-methods-use-this */ import Vue from 'vue'; +import VueResource from 'vue-resource'; + +Vue.use(VueResource); export default class EnvironmentsService { constructor(endpoint) { diff --git a/app/assets/javascripts/environments/stores/environments_store.js b/app/assets/javascripts/environments/stores/environments_store.js index d3fe3872c56..3c3084f3b78 100644 --- a/app/assets/javascripts/environments/stores/environments_store.js +++ b/app/assets/javascripts/environments/stores/environments_store.js @@ -1,5 +1,4 @@ import '~/lib/utils/common_utils'; - /** * Environments Store. * diff --git a/app/assets/javascripts/vue_pipelines_index/components/async_button.js b/app/assets/javascripts/vue_pipelines_index/components/async_button.js new file mode 100644 index 00000000000..aaebf29d8ae --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/components/async_button.js @@ -0,0 +1,92 @@ +/* eslint-disable no-new, no-alert */ +/* global Flash */ +import '~/flash'; +import eventHub from '../event_hub'; + +export default { + props: { + endpoint: { + type: String, + required: true, + }, + + service: { + type: Object, + required: true, + }, + + title: { + type: String, + required: true, + }, + + icon: { + type: String, + required: true, + }, + + cssClass: { + type: String, + required: true, + }, + + confirmActionMessage: { + type: String, + required: false, + }, + }, + + data() { + return { + isLoading: false, + }; + }, + + computed: { + iconClass() { + return `fa fa-${this.icon}`; + }, + + buttonClass() { + return `btn has-tooltip ${this.cssClass}`; + }, + }, + + methods: { + onClick() { + if (this.confirmActionMessage && confirm(this.confirmActionMessage)) { + this.makeRequest(); + } else if (!this.confirmActionMessage) { + this.makeRequest(); + } + }, + + makeRequest() { + this.isLoading = true; + + this.service.postAction(this.endpoint) + .then(() => { + this.isLoading = false; + eventHub.$emit('refreshPipelines'); + }) + .catch(() => { + this.isLoading = false; + new Flash('An error occured while making the request.'); + }); + }, + }, + + template: ` +