From 0af391d2f45f23fb806584a5c80747145a07b7c0 Mon Sep 17 00:00:00 2001 From: Constance Okoghenun Date: Thu, 15 Feb 2018 12:26:38 +0100 Subject: Refactored use of boards/boards_bundle.js, created a dipatcher import --- app/assets/javascripts/boards/boards_bundle.js | 239 --------------------- app/assets/javascripts/boards/index.js | 239 +++++++++++++++++++++ app/assets/javascripts/dispatcher.js | 5 + .../javascripts/pages/projects/boards/index.js | 6 +- app/views/shared/boards/_show.html.haml | 1 - config/webpack.config.js | 1 - spec/javascripts/test_bundle.js | 2 +- 7 files changed, 249 insertions(+), 244 deletions(-) delete mode 100644 app/assets/javascripts/boards/boards_bundle.js create mode 100644 app/assets/javascripts/boards/index.js diff --git a/app/assets/javascripts/boards/boards_bundle.js b/app/assets/javascripts/boards/boards_bundle.js deleted file mode 100644 index 90166b3d3d1..00000000000 --- a/app/assets/javascripts/boards/boards_bundle.js +++ /dev/null @@ -1,239 +0,0 @@ -/* eslint-disable one-var, quote-props, comma-dangle, space-before-function-paren */ - -import _ from 'underscore'; -import Vue from 'vue'; -import Flash from '../flash'; -import { __ } from '../locale'; -import FilteredSearchBoards from './filtered_search_boards'; -import eventHub from './eventhub'; -import sidebarEventHub from '../sidebar/event_hub'; -import './models/issue'; -import './models/label'; -import './models/list'; -import './models/milestone'; -import './models/assignee'; -import './stores/boards_store'; -import './stores/modal_store'; -import BoardService from './services/board_service'; -import './mixins/modal_mixins'; -import './mixins/sortable_default_options'; -import './filters/due_date_filters'; -import './components/board'; -import './components/board_sidebar'; -import './components/new_list_dropdown'; -import './components/modal/index'; -import '../vue_shared/vue_resource_interceptor'; - -$(() => { - const $boardApp = document.getElementById('board-app'); - const Store = gl.issueBoards.BoardsStore; - const ModalStore = gl.issueBoards.ModalStore; - - window.gl = window.gl || {}; - - if (gl.IssueBoardsApp) { - gl.IssueBoardsApp.$destroy(true); - } - - Store.create(); - - // hack to allow sidebar scripts like milestone_select manipulate the BoardsStore - gl.issueBoards.boardStoreIssueSet = (...args) => Vue.set(Store.detail.issue, ...args); - gl.issueBoards.boardStoreIssueDelete = (...args) => Vue.delete(Store.detail.issue, ...args); - - gl.IssueBoardsApp = new Vue({ - el: $boardApp, - components: { - 'board': gl.issueBoards.Board, - 'board-sidebar': gl.issueBoards.BoardSidebar, - 'board-add-issues-modal': gl.issueBoards.IssuesModal, - }, - data: { - state: Store.state, - loading: true, - boardsEndpoint: $boardApp.dataset.boardsEndpoint, - listsEndpoint: $boardApp.dataset.listsEndpoint, - boardId: $boardApp.dataset.boardId, - disabled: $boardApp.dataset.disabled === 'true', - issueLinkBase: $boardApp.dataset.issueLinkBase, - rootPath: $boardApp.dataset.rootPath, - bulkUpdatePath: $boardApp.dataset.bulkUpdatePath, - detailIssue: Store.detail, - defaultAvatar: $boardApp.dataset.defaultAvatar, - }, - computed: { - detailIssueVisible () { - return Object.keys(this.detailIssue.issue).length; - }, - }, - created () { - gl.boardService = new BoardService({ - boardsEndpoint: this.boardsEndpoint, - listsEndpoint: this.listsEndpoint, - bulkUpdatePath: this.bulkUpdatePath, - boardId: this.boardId, - }); - Store.rootPath = this.boardsEndpoint; - - eventHub.$on('updateTokens', this.updateTokens); - eventHub.$on('newDetailIssue', this.updateDetailIssue); - eventHub.$on('clearDetailIssue', this.clearDetailIssue); - sidebarEventHub.$on('toggleSubscription', this.toggleSubscription); - }, - beforeDestroy() { - eventHub.$off('updateTokens', this.updateTokens); - eventHub.$off('newDetailIssue', this.updateDetailIssue); - eventHub.$off('clearDetailIssue', this.clearDetailIssue); - sidebarEventHub.$off('toggleSubscription', this.toggleSubscription); - }, - mounted () { - this.filterManager = new FilteredSearchBoards(Store.filter, true); - this.filterManager.setup(); - - Store.disabled = this.disabled; - gl.boardService.all() - .then(res => res.data) - .then((data) => { - data.forEach((board) => { - const list = Store.addList(board, this.defaultAvatar); - - if (list.type === 'closed') { - list.position = Infinity; - } else if (list.type === 'backlog') { - list.position = -1; - } - }); - - this.state.lists = _.sortBy(this.state.lists, 'position'); - - Store.addBlankState(); - this.loading = false; - }) - .catch(() => { - Flash('An error occurred while fetching the board lists. Please try again.'); - }); - }, - methods: { - updateTokens() { - this.filterManager.updateTokens(); - }, - updateDetailIssue(newIssue) { - const sidebarInfoEndpoint = newIssue.sidebarInfoEndpoint; - if (sidebarInfoEndpoint && newIssue.subscribed === undefined) { - newIssue.setFetchingState('subscriptions', true); - BoardService.getIssueInfo(sidebarInfoEndpoint) - .then(res => res.data) - .then((data) => { - newIssue.setFetchingState('subscriptions', false); - newIssue.updateData({ - subscribed: data.subscribed, - }); - }) - .catch(() => { - newIssue.setFetchingState('subscriptions', false); - Flash(__('An error occurred while fetching sidebar data')); - }); - } - - Store.detail.issue = newIssue; - }, - clearDetailIssue() { - Store.detail.issue = {}; - }, - toggleSubscription(id) { - const issue = Store.detail.issue; - if (issue.id === id && issue.toggleSubscriptionEndpoint) { - issue.setFetchingState('subscriptions', true); - BoardService.toggleIssueSubscription(issue.toggleSubscriptionEndpoint) - .then(() => { - issue.setFetchingState('subscriptions', false); - issue.updateData({ - subscribed: !issue.subscribed, - }); - }) - .catch(() => { - issue.setFetchingState('subscriptions', false); - Flash(__('An error occurred when toggling the notification subscription')); - }); - } - } - }, - }); - - gl.IssueBoardsSearch = new Vue({ - el: document.getElementById('js-add-list'), - data: { - filters: Store.state.filters, - }, - mounted () { - gl.issueBoards.newListDropdownInit(); - }, - }); - - gl.IssueBoardsModalAddBtn = new Vue({ - el: document.getElementById('js-add-issues-btn'), - mixins: [gl.issueBoards.ModalMixins], - data() { - return { - modal: ModalStore.store, - store: Store.state, - }; - }, - computed: { - disabled() { - if (!this.store) { - return true; - } - return !this.store.lists.filter(list => !list.preset).length; - }, - tooltipTitle() { - if (this.disabled) { - return 'Please add a list to your board first'; - } - - return ''; - }, - }, - watch: { - disabled() { - this.updateTooltip(); - }, - }, - mounted() { - this.updateTooltip(); - }, - methods: { - updateTooltip() { - const $tooltip = $(this.$refs.addIssuesButton); - - this.$nextTick(() => { - if (this.disabled) { - $tooltip.tooltip(); - } else { - $tooltip.tooltip('destroy'); - } - }); - }, - openModal() { - if (!this.disabled) { - this.toggleModal(true); - } - }, - }, - template: ` -
- -
- `, - }); -}); diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js new file mode 100644 index 00000000000..7adbf442f00 --- /dev/null +++ b/app/assets/javascripts/boards/index.js @@ -0,0 +1,239 @@ +/* eslint-disable one-var, quote-props, comma-dangle, space-before-function-paren */ + +import _ from 'underscore'; +import Vue from 'vue'; +import Flash from '../flash'; +import { __ } from '../locale'; +import FilteredSearchBoards from './filtered_search_boards'; +import eventHub from './eventhub'; +import sidebarEventHub from '../sidebar/event_hub'; +import './models/issue'; +import './models/label'; +import './models/list'; +import './models/milestone'; +import './models/assignee'; +import './stores/boards_store'; +import './stores/modal_store'; +import BoardService from './services/board_service'; +import './mixins/modal_mixins'; +import './mixins/sortable_default_options'; +import './filters/due_date_filters'; +import './components/board'; +import './components/board_sidebar'; +import './components/new_list_dropdown'; +import './components/modal/index'; +import '../vue_shared/vue_resource_interceptor'; + +export default function initBoards() { + const $boardApp = document.getElementById('board-app'); + const Store = gl.issueBoards.BoardsStore; + const ModalStore = gl.issueBoards.ModalStore; + + window.gl = window.gl || {}; + + if (gl.IssueBoardsApp) { + gl.IssueBoardsApp.$destroy(true); + } + + Store.create(); + + // hack to allow sidebar scripts like milestone_select manipulate the BoardsStore + gl.issueBoards.boardStoreIssueSet = (...args) => Vue.set(Store.detail.issue, ...args); + gl.issueBoards.boardStoreIssueDelete = (...args) => Vue.delete(Store.detail.issue, ...args); + + gl.IssueBoardsApp = new Vue({ + el: $boardApp, + components: { + 'board': gl.issueBoards.Board, + 'board-sidebar': gl.issueBoards.BoardSidebar, + 'board-add-issues-modal': gl.issueBoards.IssuesModal, + }, + data: { + state: Store.state, + loading: true, + boardsEndpoint: $boardApp.dataset.boardsEndpoint, + listsEndpoint: $boardApp.dataset.listsEndpoint, + boardId: $boardApp.dataset.boardId, + disabled: $boardApp.dataset.disabled === 'true', + issueLinkBase: $boardApp.dataset.issueLinkBase, + rootPath: $boardApp.dataset.rootPath, + bulkUpdatePath: $boardApp.dataset.bulkUpdatePath, + detailIssue: Store.detail, + defaultAvatar: $boardApp.dataset.defaultAvatar, + }, + computed: { + detailIssueVisible () { + return Object.keys(this.detailIssue.issue).length; + }, + }, + created () { + gl.boardService = new BoardService({ + boardsEndpoint: this.boardsEndpoint, + listsEndpoint: this.listsEndpoint, + bulkUpdatePath: this.bulkUpdatePath, + boardId: this.boardId, + }); + Store.rootPath = this.boardsEndpoint; + + eventHub.$on('updateTokens', this.updateTokens); + eventHub.$on('newDetailIssue', this.updateDetailIssue); + eventHub.$on('clearDetailIssue', this.clearDetailIssue); + sidebarEventHub.$on('toggleSubscription', this.toggleSubscription); + }, + beforeDestroy() { + eventHub.$off('updateTokens', this.updateTokens); + eventHub.$off('newDetailIssue', this.updateDetailIssue); + eventHub.$off('clearDetailIssue', this.clearDetailIssue); + sidebarEventHub.$off('toggleSubscription', this.toggleSubscription); + }, + mounted () { + this.filterManager = new FilteredSearchBoards(Store.filter, true); + this.filterManager.setup(); + + Store.disabled = this.disabled; + gl.boardService.all() + .then(res => res.data) + .then((data) => { + data.forEach((board) => { + const list = Store.addList(board, this.defaultAvatar); + + if (list.type === 'closed') { + list.position = Infinity; + } else if (list.type === 'backlog') { + list.position = -1; + } + }); + + this.state.lists = _.sortBy(this.state.lists, 'position'); + + Store.addBlankState(); + this.loading = false; + }) + .catch(() => { + Flash('An error occurred while fetching the board lists. Please try again.'); + }); + }, + methods: { + updateTokens() { + this.filterManager.updateTokens(); + }, + updateDetailIssue(newIssue) { + const sidebarInfoEndpoint = newIssue.sidebarInfoEndpoint; + if (sidebarInfoEndpoint && newIssue.subscribed === undefined) { + newIssue.setFetchingState('subscriptions', true); + BoardService.getIssueInfo(sidebarInfoEndpoint) + .then(res => res.data) + .then((data) => { + newIssue.setFetchingState('subscriptions', false); + newIssue.updateData({ + subscribed: data.subscribed, + }); + }) + .catch(() => { + newIssue.setFetchingState('subscriptions', false); + Flash(__('An error occurred while fetching sidebar data')); + }); + } + + Store.detail.issue = newIssue; + }, + clearDetailIssue() { + Store.detail.issue = {}; + }, + toggleSubscription(id) { + const issue = Store.detail.issue; + if (issue.id === id && issue.toggleSubscriptionEndpoint) { + issue.setFetchingState('subscriptions', true); + BoardService.toggleIssueSubscription(issue.toggleSubscriptionEndpoint) + .then(() => { + issue.setFetchingState('subscriptions', false); + issue.updateData({ + subscribed: !issue.subscribed, + }); + }) + .catch(() => { + issue.setFetchingState('subscriptions', false); + Flash(__('An error occurred when toggling the notification subscription')); + }); + } + } + }, + }); + + gl.IssueBoardsSearch = new Vue({ + el: document.getElementById('js-add-list'), + data: { + filters: Store.state.filters, + }, + mounted () { + gl.issueBoards.newListDropdownInit(); + }, + }); + + gl.IssueBoardsModalAddBtn = new Vue({ + el: document.getElementById('js-add-issues-btn'), + mixins: [gl.issueBoards.ModalMixins], + data() { + return { + modal: ModalStore.store, + store: Store.state, + }; + }, + computed: { + disabled() { + if (!this.store) { + return true; + } + return !this.store.lists.filter(list => !list.preset).length; + }, + tooltipTitle() { + if (this.disabled) { + return 'Please add a list to your board first'; + } + + return ''; + }, + }, + watch: { + disabled() { + this.updateTooltip(); + }, + }, + mounted() { + this.updateTooltip(); + }, + methods: { + updateTooltip() { + const $tooltip = $(this.$refs.addIssuesButton); + + this.$nextTick(() => { + if (this.disabled) { + $tooltip.tooltip(); + } else { + $tooltip.tooltip('destroy'); + } + }); + }, + openModal() { + if (!this.disabled) { + this.toggleModal(true); + } + }, + }, + template: ` +
+ +
+ `, + }); +} diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index f8082c74943..872ddcbbbe6 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -180,6 +180,11 @@ var Dispatcher; .then(callDefault) .catch(fail); break; + case 'projects:boards:index': + import('./pages/projects/boards') + .then(callDefault) + .catch(fail); + break; case 'projects:issues:new': import('./pages/projects/issues/new') .then(callDefault) diff --git a/app/assets/javascripts/pages/projects/boards/index.js b/app/assets/javascripts/pages/projects/boards/index.js index 3aeeedbb45d..0bda9fcc421 100644 --- a/app/assets/javascripts/pages/projects/boards/index.js +++ b/app/assets/javascripts/pages/projects/boards/index.js @@ -1,7 +1,9 @@ import UsersSelect from '~/users_select'; import ShortcutsNavigation from '~/shortcuts_navigation'; +import initBoards from '~/boards'; -document.addEventListener('DOMContentLoaded', () => { +export default () => { new UsersSelect(); // eslint-disable-line no-new new ShortcutsNavigation(); // eslint-disable-line no-new -}); + initBoards(); +}; diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml index ee8ad8e3999..de470730f5e 100644 --- a/app/views/shared/boards/_show.html.haml +++ b/app/views/shared/boards/_show.html.haml @@ -7,7 +7,6 @@ - content_for :page_specific_javascripts do = webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'filtered_search' - = webpack_bundle_tag 'boards' %script#js-board-template{ type: "text/x-template" }= render "shared/boards/components/board" %script#js-board-modal-filter{ type: "text/x-template" }= render "shared/issuable/search_bar", type: :boards_modal diff --git a/config/webpack.config.js b/config/webpack.config.js index a4e6c64fce5..ba7003f3673 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -51,7 +51,6 @@ var config = { account: './profile/account/index.js', balsamiq_viewer: './blob/balsamiq_viewer.js', blob: './blob_edit/blob_bundle.js', - boards: './boards/boards_bundle.js', common: './commons/index.js', common_vue: './vue_shared/vue_resource_interceptor.js', cycle_analytics: './cycle_analytics/cycle_analytics_bundle.js', diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index 9b2a5379855..96671041cd2 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -113,7 +113,7 @@ if (process.env.BABEL_ENV === 'coverage') { // exempt these files from the coverage report const troubleMakers = [ './blob_edit/blob_bundle.js', - './boards/boards_bundle.js', + './boards/index.js', './cycle_analytics/cycle_analytics_bundle.js', './cycle_analytics/components/stage_plan_component.js', './cycle_analytics/components/stage_staging_component.js', -- cgit v1.2.1 From 7282dbea094e5dffa3af29f00e183d063a3717b1 Mon Sep 17 00:00:00 2001 From: Constance Okoghenun Date: Fri, 16 Feb 2018 01:17:23 +0100 Subject: Fixed failing test --- app/assets/javascripts/dispatcher.js | 1 + spec/javascripts/test_bundle.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 872ddcbbbe6..99ac424c433 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -180,6 +180,7 @@ var Dispatcher; .then(callDefault) .catch(fail); break; + case 'projects:boards:show': case 'projects:boards:index': import('./pages/projects/boards') .then(callDefault) diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index 96671041cd2..9d2dee990fd 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -113,7 +113,6 @@ if (process.env.BABEL_ENV === 'coverage') { // exempt these files from the coverage report const troubleMakers = [ './blob_edit/blob_bundle.js', - './boards/index.js', './cycle_analytics/cycle_analytics_bundle.js', './cycle_analytics/components/stage_plan_component.js', './cycle_analytics/components/stage_staging_component.js', -- cgit v1.2.1 From e9e5e35d28b9db5402e6216a969b008bee24db2a Mon Sep 17 00:00:00 2001 From: Constance Okoghenun Date: Wed, 21 Feb 2018 23:28:08 +0100 Subject: Removed named import --- app/assets/javascripts/boards/index.js | 4 ++-- spec/javascripts/test_bundle.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index 7adbf442f00..06a8abea940 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -24,7 +24,7 @@ import './components/new_list_dropdown'; import './components/modal/index'; import '../vue_shared/vue_resource_interceptor'; -export default function initBoards() { +export default () => { const $boardApp = document.getElementById('board-app'); const Store = gl.issueBoards.BoardsStore; const ModalStore = gl.issueBoards.ModalStore; @@ -236,4 +236,4 @@ export default function initBoards() { `, }); -} +}; diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index 9f0d8f0d01c..b8b2048f757 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -113,6 +113,7 @@ if (process.env.BABEL_ENV === 'coverage') { // exempt these files from the coverage report const troubleMakers = [ './blob_edit/blob_bundle.js', + './boards/index.js', './cycle_analytics/cycle_analytics_bundle.js', './cycle_analytics/components/stage_plan_component.js', './cycle_analytics/components/stage_staging_component.js', -- cgit v1.2.1 From ec0c598e2caf3714b3eded52e26b50c2740353d5 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Wed, 21 Feb 2018 18:22:01 -0600 Subject: Temporarily remove boards from test bundle troubleMakers --- spec/javascripts/test_bundle.js | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index b8b2048f757..9f0d8f0d01c 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -113,7 +113,6 @@ if (process.env.BABEL_ENV === 'coverage') { // exempt these files from the coverage report const troubleMakers = [ './blob_edit/blob_bundle.js', - './boards/index.js', './cycle_analytics/cycle_analytics_bundle.js', './cycle_analytics/components/stage_plan_component.js', './cycle_analytics/components/stage_staging_component.js', -- cgit v1.2.1 From 11aa990da7794038aef09dd023b85e81b5ac6c4f Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Fri, 23 Feb 2018 12:28:45 -0600 Subject: Explicitly add uncovered files to troubleMakers --- spec/javascripts/test_bundle.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index 9f0d8f0d01c..94fcc6c7f2b 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -113,6 +113,9 @@ if (process.env.BABEL_ENV === 'coverage') { // exempt these files from the coverage report const troubleMakers = [ './blob_edit/blob_bundle.js', + './boards/components/modal/empty_state.js', + './boards/components/modal/footer.js', + './boards/components/modal/header.js', './cycle_analytics/cycle_analytics_bundle.js', './cycle_analytics/components/stage_plan_component.js', './cycle_analytics/components/stage_staging_component.js', -- cgit v1.2.1