diff --git a/src/main.js b/src/main.js index e62734851..c0c441a1f 100644 --- a/src/main.js +++ b/src/main.js @@ -27,15 +27,7 @@ import { sync } from 'vuex-router-sync' import { translate, translatePlural } from 'nextcloud-server/dist/l10n' import { generateFilePath } from 'nextcloud-server/dist/router' import VTooltip from 'v-tooltip' - -/** - * Board model - * - * @typedef {Object} Board - * @property {String} title - * @property {boolean} archived - * @property {number} shared 1 (shared) or 0 (not shared) - */ +import './models' // eslint-disable-next-line __webpack_nonce__ = btoa(OC.requestToken) diff --git a/src/models/index.js b/src/models/index.js new file mode 100644 index 000000000..4649a5e57 --- /dev/null +++ b/src/models/index.js @@ -0,0 +1,48 @@ +/* + * @copyright Copyright (c) 2018 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +/** + * Board model + * + * @typedef {Object} Board + * @property {String} title + * @property {boolean} archived + * @property {number} shared 1 (shared) or 0 (not shared) + */ + +/** + * Stack model + * + * @typedef {Object} Stack + * @property {String} title + * @property {number} boardId + * @property {number} order + */ + +/** + * Card model + * + * @typedef {Object} Card + * @property {String} title + * @property {boolean} archived + * @property {number} order + */ diff --git a/src/services/StackApi.js b/src/services/StackApi.js index 5b2785117..2a6fe4e1e 100644 --- a/src/services/StackApi.js +++ b/src/services/StackApi.js @@ -22,24 +22,15 @@ import axios from 'nextcloud-axios' -/** - * This class handles all the api communication with the Deck backend. - */ -export class BoardApi { +export class StackApi { url(url) { url = `/apps/deck${url}` return OC.generateUrl(url) } - /** - * Updates a board. - * - * @param {Board} board - * @return Promise - */ - updateBoard(board) { - return axios.put(this.url(`/boards/${board.id}`), board) + loadStacks(boardId) { + return axios.get(this.url(`/stacks/${boardId}`)) .then( (response) => { return Promise.resolve(response.data) @@ -54,15 +45,11 @@ export class BoardApi { } /** - * Creates a new board. - * - * @param {{String title, String color, String hashedColor}} boardData The board data to send. - * hashedColor is the color in hex format, e.g. "#ff0000" - * color is the same color without the "#" - * @return Promise + * @param {Stack} stack + * @returns {Promise} */ - createBoard(boardData) { - return axios.post(this.url('/boards'), boardData) + createStack(stack) { + return axios.post(this.url(`/stacks`), stack) .then( (response) => { return Promise.resolve(response.data) @@ -76,23 +63,8 @@ export class BoardApi { }) } - loadBoards() { - return axios.get(this.url('/boards')) - .then( - (response) => { - return Promise.resolve(response.data) - }, - (err) => { - return Promise.reject(err) - } - ) - .catch((err) => { - return Promise.reject(err) - }) - } - - loadById(id) { - return axios.get(this.url(`/boards/${id}`)) + reorderStack(stackId, order) { + return axios.put(this.url(`/stacks/${stackId}/reorder`), { order }) .then( (response) => { return Promise.resolve(response.data) diff --git a/src/store/card.js b/src/store/card.js new file mode 100644 index 000000000..0c2501ac6 --- /dev/null +++ b/src/store/card.js @@ -0,0 +1,50 @@ +/* + * @copyright Copyright (c) 2018 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import Vue from 'vue' + +export default { + state: { + cards: [] + }, + getters: { + cardsByStack: state => (id) => { + return state.cards.filter((card) => card.stackId === id).sort((a, b) => a.order - b.order) + }, + cardById: state => (id) => { + return state.cards.find((card) => card.id === id) + } + }, + mutations: { + addCard(state, card) { + let existingIndex = state.cards.findIndex(_card => _card.id === card.id) + if (existingIndex !== -1) { + let existingCard = state.cards.find(_card => _card.id === card.id) + Vue.set(state.cards, existingIndex, Object.assign({}, existingCard, card)) + } else { + state.cards.push(card) + } + } + }, + actions: { + } +} diff --git a/src/store/main.js b/src/store/main.js index 38798da96..7f7354b37 100644 --- a/src/store/main.js +++ b/src/store/main.js @@ -24,6 +24,8 @@ import Vue from 'vue' import Vuex from 'vuex' import { boardToMenuItem } from './../helpers/boardToMenuItem' import { BoardApi } from './../services/BoardApi' +import stack from './stack' +import card from './card' Vue.use(Vuex) @@ -37,7 +39,10 @@ export const BOARD_FILTERS = { } export default new Vuex.Store({ - modules: {}, + modules: { + stack, + card + }, strict: debug, state: { navShown: true, diff --git a/src/store/stack.js b/src/store/stack.js new file mode 100644 index 000000000..4ac673d74 --- /dev/null +++ b/src/store/stack.js @@ -0,0 +1,86 @@ +/* + * @copyright Copyright (c) 2018 Julius Härtl + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import Vue from 'vue' +import { StackApi } from './../services/StackApi' +import applyOrderToArray from './../helpers/applyOrderToArray' + +const apiClient = new StackApi() + +export default { + state: { + stacks: [] + }, + getters: { + stacksByBoard: state => (id) => { + return state.stacks.filter((stack) => stack.boardId === id).sort((a, b) => a.order - b.order) + } + }, + mutations: { + addStack(state, stack) { + let existingIndex = state.stacks.findIndex(_stack => _stack.id === stack.id) + if (existingIndex !== -1) { + let existingStack = state.stacks.find(_stack => _stack.id === stack.id) + Vue.set(state.stacks, existingIndex, Object.assign({}, existingStack, stack)) + } else { + state.stacks.push(stack) + } + }, + orderStack(state, { stack, removedIndex, addedIndex }) { + let currentOrder = state.stacks.filter((_stack) => _stack.boardId === stack.boardId).sort((a, b) => a.order - b.order) + var newOrder = applyOrderToArray(currentOrder, removedIndex, addedIndex) + for (let i = 0; i < newOrder.length; i++) { + newOrder[i].order = parseInt(i) + } + } + }, + actions: { + orderStack({ commit }, { stack, removedIndex, addedIndex }) { + commit('orderStack', { stack, removedIndex, addedIndex }) + apiClient.reorderStack(stack.id, addedIndex) + .catch((err) => { + OC.Notification.showTemporary('Failed to change order') + console.error(err.response.data.message) + commit('orderStack', { stack, addedIndex, removedIndex }) + }) + }, + loadStacks({ commit }, board) { + apiClient.loadStacks(board.id) + .then((stacks) => { + for (let i in stacks) { + let stack = stacks[i] + for (let j in stack.cards) { + commit('addCard', stack.cards[j]) + } + delete stack.cards + commit('addStack', stack) + } + }) + }, + createStack({ commit }, stack) { + apiClient.createStack(stack) + .then((stack) => { + commit('addStack', stack) + }) + } + } +}