From 3e839b3468bd4280d96ce5cec4eab27d16abc85d Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 4 Aug 2016 16:16:50 +0100 Subject: [PATCH] Hooked the frontend services up with the backend --- .../javascripts/boards/boards_bundle.js.es6 | 19 +++-- .../boards/components/board.js.es6 | 4 +- .../components/new_list_dropdown.js.es6 | 7 +- .../javascripts/boards/models/label.js.es6 | 4 +- .../javascripts/boards/models/list.js.es6 | 16 +++- .../boards/services/board_service.js.es6 | 35 ++++++--- .../boards/stores/boards_store.js.es6 | 76 ++++++++++++++----- .../boards/components/_board.html.haml | 6 +- app/views/projects/boards/index.html.haml | 14 ---- app/views/projects/boards/show.html.haml | 28 +++---- config/routes.rb | 10 --- 11 files changed, 126 insertions(+), 93 deletions(-) delete mode 100644 app/views/projects/boards/index.html.haml diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js.es6 index 450f265f760..8f360f69c6a 100644 --- a/app/assets/javascripts/boards/boards_bundle.js.es6 +++ b/app/assets/javascripts/boards/boards_bundle.js.es6 @@ -19,18 +19,17 @@ $(function () { .then((resp) => { const boards = resp.json(); - // Add blank state board - if (boards.length === 2) { - boards.splice(1, 0, { - id: 'blank', - title: 'Welcome to your Issue Board!', - index: 1 - }); - } - boards.forEach((board) => { - BoardsStore.new(board); + const list = new List(board); + + if (list.type === 'done') { + list.position = 9999999; + } + + BoardsStore.state.lists.push(list); }); + + BoardsStore.addBlankState(); }); } }); diff --git a/app/assets/javascripts/boards/components/board.js.es6 b/app/assets/javascripts/boards/components/board.js.es6 index 894e3643d56..cee169b45e6 100644 --- a/app/assets/javascripts/boards/components/board.js.es6 +++ b/app/assets/javascripts/boards/components/board.js.es6 @@ -15,7 +15,7 @@ }, computed: { isPreset: function () { - return typeof this.board.id !== 'number'; + return this.board.type === 'backlog' || this.board.type === 'done' || this.board.type === 'blank'; } }, ready: function () { @@ -27,7 +27,7 @@ fallbackClass: 'is-dragging', ghostClass: 'is-ghost', onUpdate: function (e) { - BoardsStore.moveList(e.oldIndex + 1, e.newIndex + 1); + BoardsStore.moveList(e.oldIndex, e.newIndex); } }); }, diff --git a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 b/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 index f1a8941a733..d5ba7cb8744 100644 --- a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 +++ b/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 @@ -31,13 +31,12 @@ $(() => { clicked: (label, $el, e) => { e.preventDefault(); BoardsStore.new({ - id: BoardsStore.state.lists.length - 1, title: label.title, - index: BoardsStore.state.lists.length - 1, + position: BoardsStore.state.lists.length - 1, label: { + id: label.id, title: label.title, - backgroundColor: label.color, - color: '#fff' + color: label.color }, issues: [] }); diff --git a/app/assets/javascripts/boards/models/label.js.es6 b/app/assets/javascripts/boards/models/label.js.es6 index 93da376de7c..d2ce30c37ea 100644 --- a/app/assets/javascripts/boards/models/label.js.es6 +++ b/app/assets/javascripts/boards/models/label.js.es6 @@ -1,7 +1,7 @@ class Label { constructor (obj) { + this.id = obj.id; this.title = obj.title; - this.backgroundColor = obj.backgroundColor; - this.textColor = obj.textColor; + this.color = obj.color; } } diff --git a/app/assets/javascripts/boards/models/list.js.es6 b/app/assets/javascripts/boards/models/list.js.es6 index ebef8bc6fd7..ecbf367bfe1 100644 --- a/app/assets/javascripts/boards/models/list.js.es6 +++ b/app/assets/javascripts/boards/models/list.js.es6 @@ -1,9 +1,9 @@ class List { constructor (obj) { this.id = obj.id; - this.index = obj.index; - this.search = obj.search || false; + this.position = obj.position; this.title = obj.title; + this.type = obj.list_type; if (obj.label) { this.label = new Label(obj.label); @@ -17,6 +17,18 @@ class List { } } + destroy () { + service.destroyList(this.id); + } + + update () { + service.updateList(this); + } + + canSearch () { + return this.type === 'backlog'; + } + addIssue (issue, index) { this.issues.splice(index, 0, issue); diff --git a/app/assets/javascripts/boards/services/board_service.js.es6 b/app/assets/javascripts/boards/services/board_service.js.es6 index 859fd961230..398e3c5650d 100644 --- a/app/assets/javascripts/boards/services/board_service.js.es6 +++ b/app/assets/javascripts/boards/services/board_service.js.es6 @@ -2,12 +2,8 @@ class BoardService { constructor (root) { Vue.http.options.root = root; - this.resource = Vue.resource(`${root}{/id}`, {}, { - all: { - method: 'GET', - url: 'all' - } - }); + this.lists = Vue.resource(`${root}{/id}.json`, {}); + this.list = Vue.resource(`${root}/lists{/id}.json`, {}); } setCSRF () { @@ -16,11 +12,32 @@ class BoardService { all () { this.setCSRF(); - return this.resource.all(); + return this.lists.get(); + } + + createList (labelId) { + this.setCSRF(); + + return this.list.save({}, { + list: { + label_id: labelId + } + }); } - updateBoard (id, index) { + updateList (list) { this.setCSRF(); - return this.resource.update({ id: id }, { index: index }); + + return this.list.update({ id: list.id }, { + list: { + position: list.position + } + }); + } + + destroyList (id) { + this.setCSRF(); + + return this.list.delete({ id }); } }; diff --git a/app/assets/javascripts/boards/stores/boards_store.js.es6 b/app/assets/javascripts/boards/stores/boards_store.js.es6 index c3c82864ce8..74ecf847328 100644 --- a/app/assets/javascripts/boards/stores/boards_store.js.es6 +++ b/app/assets/javascripts/boards/stores/boards_store.js.es6 @@ -2,7 +2,6 @@ w.BoardsStore = { state: { lists: [], - done: {}, filters: { author: {}, assignee: {}, @@ -10,47 +9,88 @@ } }, new: function (board) { - // Move the done list index - const doneList = this.getDoneList(); + const doneList = this.getDoneList(), + list = new List(board); + this.state.lists.push(list); + + if (list.type !== 'blank') { + service.createList(list.label.id) + .then(function (resp) { + const data = resp.json(); - if (doneList) { - doneList.index = board.index + 1; + list.id = data.id; + list.type = data.list_type; + list.position = data.position; + }); + + this.removeBlankState(); + this.addBlankState(); } + }, + addBlankState: function () { + const doneList = this.getDoneList(); - const list = new List(board); - this.state.lists.push(list); + // Decide whether to add the blank state + let addBlankState = true; + + this.state.lists.forEach(function (list) { + if (list.type !== 'backlog' && list.type !== 'done') { + addBlankState = false; + return; + } + }); + + if (addBlankState) { + this.new({ + id: 'blank', + list_type: 'blank', + title: 'Welcome to your Issue Board!', + position: 0 + }); + } + }, + removeBlankState: function () { + this.removeList('blank'); }, getDoneList: function () { return _.find(this.state.lists, (list) => { - return list.id === 'done'; + return list.type === 'done'; }); }, removeList: function (id) { + const list = _.find(this.state.lists, (list) => { + return list.id === id; + }); + + if (id !== 'blank') { + list.destroy(); + } + this.state.lists = _.reject(this.state.lists, (list) => { return list.id === id; }); if (id !== 'blank') { - this.getDoneList().index = this.state.lists.length - 1; + this.addBlankState(); } }, moveList: function (oldIndex, newIndex) { const listFrom = _.find(this.state.lists, (list) => { - return list.index === oldIndex; + return list.position === oldIndex; }); - service.updateBoard(listFrom.id, newIndex); - const listTo = _.find(this.state.lists, (list) => { - return list.index === newIndex; + return list.position === newIndex; }); - listFrom.index = newIndex; - if (newIndex > listTo.index) { - listTo.index--; + listFrom.position = newIndex; + if (newIndex > listTo.position) { + listTo.position--; } else { - listTo.index++; + listTo.position++; } + + listFrom.update(); }, moveCardToList: function (listFromId, listToId, issueId, toIndex) { const listFrom = _.find(this.state.lists, (list) => { @@ -84,7 +124,7 @@ return list.findIssue(issue.id); }); }, - clearDone: () => { + clearDone: function () { Vue.set(BoardsStore.state, 'done', {}); } }; diff --git a/app/views/projects/boards/components/_board.html.haml b/app/views/projects/boards/components/_board.html.haml index bf9e03cb75d..ccdb8beb339 100644 --- a/app/views/projects/boards/components/_board.html.haml +++ b/app/views/projects/boards/components/_board.html.haml @@ -1,7 +1,7 @@ -%board{ "inline-template" => true, "v-cloak" => true, "v-for" => "board in state.lists | orderBy 'index'", ":board" => "board" } +%board{ "inline-template" => true, "v-cloak" => true, "v-for" => "board in state.lists | orderBy 'position'", ":board" => "board" } .board{ ":class" => "{ 'is-draggable': !isPreset }" } .board-inner - %header.board-inner-container.board-header{ ":class" => "{ 'has-border': board.label }", ":style" => "{ borderTopColor: board.label.backgroundColor }" } + %header.board-inner-container.board-header{ ":class" => "{ 'has-border': board.label }", ":style" => "{ borderTopColor: board.label.color }" } %h3.board-title {{ board.title }} %span.pull-right @@ -9,7 +9,7 @@ %board-delete{ "inline-template" => true, "v-if" => "!isPreset", ":board-id" => "board.id" } %button.board-delete.has-tooltip.pull-right{ type: "button", title: "Delete board", "aria-label" => "Delete board", data: { placement: "bottom" }, "@click" => "deleteBoard" } = icon("trash") - .board-inner-container.board-search-container{ "v-if" => "board.search" } + .board-inner-container.board-search-container{ "v-if" => "board.canSearch()" } %input.form-control{ type: "text", placeholder: "Search issues", "v-model" => "query" } = icon("search", class: "board-search-icon", "v-show" => "!query") %button.board-search-clear-btn{ type: "button", role: "button", "aria-label" => "Clear search", "@click" => "clearSearch", "v-show" => "query" } diff --git a/app/views/projects/boards/index.html.haml b/app/views/projects/boards/index.html.haml deleted file mode 100644 index 620cdb12a35..00000000000 --- a/app/views/projects/boards/index.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -- @no_container = true -- @content_class = "issue-boards-content" -- page_title "Boards" - -- content_for :page_specific_javascripts do - = page_specific_javascript_tag('boards/boards_bundle.js') - = page_specific_javascript_tag('boards/test_utils/simulate_drag.js') if Rails.env.test? - -= render "projects/issues/head" - -= render 'shared/issuable/filter', type: :boards - -.boards-list#board-app{ "data-endpoint" => "#{namespace_project_boards_path(@project.namespace, @project)}" } - = render "projects/boards/components/board" diff --git a/app/views/projects/boards/show.html.haml b/app/views/projects/boards/show.html.haml index fcbd8ea6309..c834a8beff6 100644 --- a/app/views/projects/boards/show.html.haml +++ b/app/views/projects/boards/show.html.haml @@ -1,24 +1,14 @@ - @no_container = true - @content_class = "issue-boards-content" - page_title "Boards" + +- content_for :page_specific_javascripts do + = page_specific_javascript_tag('boards/boards_bundle.js') + = page_specific_javascript_tag('boards/test_utils/simulate_drag.js') if Rails.env.test? + = render "projects/issues/head" -.boards-list - .board - .board-inner - %header.board-inner-container - %h3.board-title - Backlog - %span.pull-right - 5 - .board-inner-container.board-search-container - %input.form-control{ type: "text", placeholder: "Search issues" } - %ul.board-list - %li.card - %h4.card-title - Issue title - .card-footer - %span.card-number - \#288 - %span.label.color-label{ style: "background-color: #428bca; color: #FFFFFF" } - label += render 'shared/issuable/filter', type: :boards + +.boards-list#board-app{ "data-endpoint" => "#{namespace_project_board_path(@project.namespace, @project)}" } + = render "projects/boards/components/board" diff --git a/config/routes.rb b/config/routes.rb index c0691cb6d5a..09a8945c59e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -832,17 +832,7 @@ Rails.application.routes.draw do end end -<<<<<<< 9d83a366e263d015894908f72576972f87848399 resources :project_members, except: [:show, :new, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ }, concerns: :access_requestable do -======= - resources :boards do - collection do - get :all - end - end - - resources :project_members, except: [:new, :edit], constraints: { id: /[a-zA-Z.\/0-9_\-#%+]+/ }, concerns: :access_requestable do ->>>>>>> Added vue-resource to get & save data collection do delete :leave -- GitLab