diff --git a/src/components/card/CardSidebarTabAttachments.vue b/src/components/card/CardSidebarTabAttachments.vue index 100716150..ba9685fb3 100644 --- a/src/components/card/CardSidebarTabAttachments.vue +++ b/src/components/card/CardSidebarTabAttachments.vue @@ -22,30 +22,98 @@ diff --git a/src/components/cards/CardBadges.vue b/src/components/cards/CardBadges.vue index 72f7315fc..1dc509a88 100644 --- a/src/components/cards/CardBadges.vue +++ b/src/components/cards/CardBadges.vue @@ -34,7 +34,9 @@ {{ checkListCheckedCount }}/{{ checkListCount }} -
+
+ {{ card.attachmentCount }} +
@@ -99,9 +101,10 @@ export default { .icon { opacity: 0.5; - padding: 12px 3px; + padding: 12px 14px; margin-right: 10px; background-position: left; + background-size: 16px; span { margin-left: 18px; } diff --git a/src/services/AttachmentApi.js b/src/services/AttachmentApi.js new file mode 100644 index 000000000..241a98daa --- /dev/null +++ b/src/services/AttachmentApi.js @@ -0,0 +1,68 @@ +/* + * @copyright Copyright (c) 2020 Jakob Röhrl + * + * @author Jakob Röhrl + * + * @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 axios from '@nextcloud/axios' +import { generateUrl } from '@nextcloud/router' + +export class AttachmentApi { + + url(url) { + return generateUrl(`/apps/deck${url}`) + } + + async fetchAttachments(cardId) { + const response = await axios({ + method: 'GET', + url: this.url(`/cards/${cardId}/attachments`), + }) + return response.data + } + + async createAttachment({ cardId, formData }) { + try { + const response = await axios({ + method: 'POST', + url: this.url(`/cards/${cardId}/attachment`), + data: formData, + }) + return response.data + } catch (e) { + throw e + } + } + + async deleteAttachment(attachment) { + await axios({ + method: 'DELETE', + url: this.url(`/cards/${attachment.cardId}/attachment/${attachment.id}`), + }) + } + + async displayAttachment(attachment) { + const response = await axios({ + method: 'GET', + url: this.url(`/cards/${attachment.cardId}/attachment/${attachment.id}`), + }) + return response.data + } + +} diff --git a/src/store/attachment.js b/src/store/attachment.js new file mode 100644 index 000000000..ffa3c21d2 --- /dev/null +++ b/src/store/attachment.js @@ -0,0 +1,77 @@ +/* + * @copyright Copyright (c) 2020 Jakob Röhrl + * + * @author Jakob Röhrl + * + * @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 { AttachmentApi } from './../services/AttachmentApi' +import Vue from 'vue' + +const apiClient = new AttachmentApi() + +export default { + state: { + attachments: {}, + }, + getters: { + attachmentsByCard: state => (cardId) => { + if (typeof state.attachments[cardId] === 'undefined') { + return [] + } + return state.attachments[cardId] + }, + + }, + mutations: { + createAttachment(state, { cardId, attachments }) { + if (typeof state.attachments[cardId] === 'undefined') { + Vue.set(state.attachments, cardId, attachments) + } else { + state.attachments[cardId].push(attachments) + } + }, + + deleteAttachment(state, deletedAttachment) { + const existingIndex = state.attachments[deletedAttachment.cardId].findIndex(a => a.id === deletedAttachment.id) + if (existingIndex !== -1) { + state.attachments[deletedAttachment.cardId].splice(existingIndex, 1) + } + }, + + }, + actions: { + async fetchAttachments({ commit }, cardId) { + const attachments = await apiClient.fetchAttachments(cardId) + commit('createAttachment', { cardId, attachments }) + }, + + async createAttachment({ commit }, { cardId, formData }) { + const attachments = await apiClient.createAttachment({ cardId, formData }) + commit('createAttachment', { cardId, attachments }) + commit('cardIncreaseAttachmentCount', cardId) + }, + + async deleteAttachment({ commit }, attachment) { + await apiClient.deleteAttachment(attachment) + commit('deleteAttachment', attachment) + commit('cardDecreaseAttachmentCount', attachment.cardId) + }, + + }, +} diff --git a/src/store/card.js b/src/store/card.js index 24e800f5e..65fffffc1 100644 --- a/src/store/card.js +++ b/src/store/card.js @@ -140,6 +140,20 @@ export default { Vue.set(state.cards[existingIndex], property, card[property]) } }, + cardIncreaseAttachmentCount(state, cardId) { + const existingIndex = state.cards.findIndex(_card => _card.id === cardId) + if (existingIndex !== -1) { + const existingCard = state.cards.find(_card => _card.id === cardId) + Vue.set(state.cards, existingCard.attachmentCount, existingCard.attachmentCount++) + } + }, + cardDecreaseAttachmentCount(state, cardId) { + const existingIndex = state.cards.findIndex(_card => _card.id === cardId) + if (existingIndex !== -1) { + const existingCard = state.cards.find(_card => _card.id === cardId) + Vue.set(state.cards, existingCard.attachmentCount, existingCard.attachmentCount--) + } + }, }, actions: { async addCard({ commit }, card) { diff --git a/src/store/main.js b/src/store/main.js index 56079ff0b..1fef80971 100644 --- a/src/store/main.js +++ b/src/store/main.js @@ -30,6 +30,7 @@ import stack from './stack' import card from './card' import comment from './comment' import trashbin from './trashbin' +import attachment from './attachment' Vue.use(Vuex) @@ -48,6 +49,7 @@ export default new Vuex.Store({ card, comment, trashbin, + attachment, }, strict: debug, state: {