Skip to content

Commit 307b9ee

Browse files
authored
Merge pull request #8142 from nextcloud/refactor/pinia-migration-attachment-attachmentStore
refactor(pinia): move attachmentStore to pinia
2 parents 13d5d95 + 6202190 commit 307b9ee

9 files changed

Lines changed: 107 additions & 130 deletions

File tree

appinfo/routes.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
['name' => 'attachment_ocs#getAll', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments', 'verb' => 'GET'],
161161
['name' => 'attachment_ocs#create', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachment', 'verb' => 'POST'],
162162
['name' => 'attachment_ocs#update', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'PUT'],
163-
['name' => 'attachment_ocs#delete', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'DELETE'],
163+
['name' => 'attachment_ocs#delete', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments/{type}:{attachmentId}', 'verb' => 'DELETE'],
164164
['name' => 'attachment_ocs#restore', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments/{attachmentId}/restore', 'verb' => 'PUT'],
165165

166166
['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'],

src/components/card/AttachmentList.vue

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,12 @@ import relativeDate from '../../mixins/relativeDate.js'
9494
import { formatFileSize } from '@nextcloud/files'
9595
import { getCurrentUser } from '@nextcloud/auth'
9696
import { generateUrl, generateOcsUrl, generateRemoteUrl } from '@nextcloud/router'
97-
import { mapState, mapActions } from 'vuex'
97+
import { mapState as mapStateVuex } from 'vuex'
98+
import { mapState, mapActions } from 'pinia'
9899
import { loadState } from '@nextcloud/initial-state'
99100
import attachmentUpload from '../../mixins/attachmentUpload.js'
100101
import { getFilePickerBuilder } from '@nextcloud/dialogs'
102+
import { useAttachmentStore } from '../../stores/attachment.js'
101103
const maxUploadSizeState = loadState('deck', 'maxUploadSize', -1)
102104
103105
const picker = getFilePickerBuilder(t('deck', 'File to share'))
@@ -147,7 +149,7 @@ export default {
147149
},
148150
attachments() {
149151
// FIXME sort propertly by last modified / deleted at
150-
return [...this.$store.getters.attachmentsByCard(this.cardId)].filter(attachment => attachment.deletedAt >= 0).sort((a, b) => b.id - a.id)
152+
return [...this.attachmentsByCard(this.cardId)].filter(attachment => attachment.deletedAt >= 0).sort((a, b) => b.id - a.id)
151153
},
152154
mimetypeForAttachment() {
153155
return (attachment) => {
@@ -176,9 +178,12 @@ export default {
176178
formattedFileSize() {
177179
return (filesize) => formatFileSize(filesize)
178180
},
179-
...mapState({
181+
...mapStateVuex({
180182
currentBoard: state => state.currentBoard,
181183
}),
184+
...mapState(useAttachmentStore, [
185+
'attachmentsByCard',
186+
]),
182187
isReadOnly() {
183188
return !this.$store.getters.canEdit
184189
},
@@ -210,8 +215,9 @@ export default {
210215
},
211216
},
212217
methods: {
213-
...mapActions([
218+
...mapActions(useAttachmentStore, [
214219
'fetchAttachments',
220+
'unshareAttachment',
215221
]),
216222
handleUploadFile(event) {
217223
const files = event.target.files ?? []
@@ -240,9 +246,6 @@ export default {
240246
})
241247
})
242248
},
243-
unshareAttachment(attachment) {
244-
this.$store.dispatch('unshareAttachment', attachment)
245-
},
246249
clickAddNewAttachmment() {
247250
this.$refs.localAttachments.click()
248251
},

src/components/card/CardSidebarTabAttachments.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
</template>
1212

1313
<script>
14+
import { mapActions } from 'pinia'
1415
import AttachmentList from './AttachmentList.vue'
16+
import { useAttachmentStore } from '../../stores/attachment.js'
1517
export default {
1618
name: 'CardSidebarTabAttachments',
1719
components: {
@@ -24,12 +26,10 @@ export default {
2426
},
2527
},
2628
methods: {
27-
deleteAttachment(attachment) {
28-
this.$store.dispatch('deleteAttachment', attachment)
29-
},
30-
restoreAttachment(attachment) {
31-
this.$store.dispatch('restoreAttachment', attachment)
32-
},
29+
...mapActions(useAttachmentStore, [
30+
'deleteAttachment',
31+
'restoreAttachment',
32+
]),
3333
},
3434
}
3535
</script>

src/components/cards/CardCover.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
</div>
1313
</template>
1414
<script>
15-
import { mapActions } from 'vuex'
15+
import { mapActions } from 'pinia'
1616
import { generateUrl } from '@nextcloud/router'
17+
import { useAttachmentStore } from '../../stores/attachment.js'
1718
export default {
1819
name: 'CardCover',
1920
props: {
@@ -61,7 +62,7 @@ export default {
6162
},
6263
},
6364
methods: {
64-
...mapActions([
65+
...mapActions(useAttachmentStore, [
6566
'fetchAttachments',
6667
]),
6768
},

src/mixins/attachmentUpload.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { showError } from '@nextcloud/dialogs'
66
import { formatFileSize } from '@nextcloud/files'
77
// eslint-disable-next-line import/no-unresolved
88
import PQueue from 'p-queue'
9+
import { mapActions } from 'pinia'
10+
import { useAttachmentStore } from '../stores/attachment.js'
911

1012
const queue = new PQueue({ concurrency: 2 })
1113

@@ -33,7 +35,7 @@ export default {
3335
bodyFormData.append('file', file)
3436
await queue.add(async () => {
3537
try {
36-
await this.$store.dispatch('createAttachment', {
38+
await this.createAttachment({
3739
cardId: this.cardId,
3840
formData: bodyFormData,
3941
onUploadProgress: (e) => {
@@ -54,13 +56,17 @@ export default {
5456
})
5557

5658
},
59+
...mapActions(useAttachmentStore, [
60+
'createAttachment',
61+
'updateAttachment',
62+
]),
5763

5864
overrideAttachment() {
5965
const bodyFormData = new FormData()
6066
bodyFormData.append('cardId', this.cardId)
6167
bodyFormData.append('type', 'deck_file')
6268
bodyFormData.append('file', this.file)
63-
this.$store.dispatch('updateAttachment', {
69+
this.updateAttachment({
6470
cardId: this.cardId,
6571
attachment: this.overwriteAttachment,
6672
formData: bodyFormData,

src/services/AttachmentApi.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export class AttachmentApi {
5656
async deleteAttachment(attachment, boardId) {
5757
await axios({
5858
method: 'DELETE',
59-
url: this.ocsUrl(`/cards/${attachment.cardId}/attachment/${attachment.type}:${attachment.id}`),
59+
url: this.ocsUrl(`/cards/${attachment.cardId}/attachments/${attachment.type}:${attachment.id}`),
6060
params: {
6161
boardId: boardId ?? null,
6262
},

src/store/attachment.js

Lines changed: 0 additions & 109 deletions
This file was deleted.

src/store/main.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { generateOcsUrl, generateUrl } from '@nextcloud/router'
1313
import { BoardApi } from '../services/BoardApi.js'
1414
import stackModuleFactory from './stack.js'
1515
import cardModuleFactory from './card.js'
16-
import attachment from './attachment.js'
1716
Vue.use(Vuex)
1817

1918
const apiClient = new BoardApi()
@@ -33,7 +32,6 @@ export default function storeFactory() {
3332
modules: {
3433
stack: stackModuleFactory(),
3534
card: cardModuleFactory(),
36-
attachment,
3735
},
3836
strict: debug,
3937
state: {

src/stores/attachment.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { defineStore } from 'pinia'
7+
import Vue from 'vue'
8+
import { AttachmentApi } from '../services/AttachmentApi.js'
9+
10+
const apiClient = new AttachmentApi()
11+
12+
export const useAttachmentStore = defineStore('attachment', {
13+
state: () => ({
14+
attachments: {},
15+
}),
16+
getters: {
17+
attachmentsByCard: (state) => (cardId) => {
18+
if (typeof state.attachments[cardId] === 'undefined') {
19+
return []
20+
}
21+
return state.attachments[cardId]
22+
},
23+
},
24+
actions: {
25+
async createAttachment({ cardId, formData, onUploadProgress }) {
26+
const boardId = this.$vuex.state.currentBoard.id
27+
const attachment = await apiClient.createAttachment({ cardId, formData, onUploadProgress, boardId })
28+
if (typeof this.attachments[cardId] === 'undefined') {
29+
Vue.set(this.attachments, cardId, [attachment])
30+
} else {
31+
this.attachments[cardId].push(attachment)
32+
}
33+
this.$vuex.commit('cardIncreaseAttachmentCount', cardId)
34+
},
35+
async fetchAttachments(cardId) {
36+
const boardId = this.$vuex.state.currentBoard.id
37+
const attachments = await apiClient.fetchAttachments(cardId, boardId)
38+
Vue.set(this.attachments, cardId, attachments)
39+
this.$vuex.commit('cardSetAttachmentCount', { cardId, count: attachments.length })
40+
},
41+
async updateAttachment({ cardId, attachment, formData }) {
42+
const boardId = this.$vuex.state.currentBoard.id
43+
const result = await apiClient.updateAttachment({ cardId, attachment, formData, boardId })
44+
const existingIndex = this.attachments[attachment.cardId].findIndex(a => a.id === attachment.id && a.type === attachment.type)
45+
if (existingIndex !== -1) {
46+
Vue.set(this.attachments[cardId], existingIndex, result)
47+
}
48+
},
49+
async deleteAttachment(attachment) {
50+
const boardId = this.$vuex.state.currentBoard.id
51+
await apiClient.deleteAttachment(attachment, boardId)
52+
const existingIndex = this.attachments[attachment.cardId].findIndex(a => a.id === attachment.id && a.type === attachment.type)
53+
if (existingIndex !== -1) {
54+
Vue.set(this.attachments[attachment.cardId][existingIndex], 'deletedAt', Date.now() / 1000 | 0)
55+
}
56+
this.$vuex.commit('cardDecreaseAttachmentCount', attachment.cardId)
57+
},
58+
async unshareAttachment(attachment) {
59+
const boardId = this.$vuex.state.currentBoard.id
60+
await apiClient.deleteAttachment(attachment, boardId)
61+
const existingIndex = this.attachments[attachment.cardId].findIndex(a => a.id === attachment.id && a.type === attachment.type)
62+
if (existingIndex !== -1) {
63+
Vue.set(this.attachments[attachment.cardId][existingIndex], 'deletedAt', -1)
64+
}
65+
this.$vuex.commit('cardDecreaseAttachmentCount', attachment.cardId)
66+
},
67+
async restoreAttachment(attachment) {
68+
const boardId = this.$vuex.state.currentBoard.id
69+
const restoredAttachment = await apiClient.restoreAttachment(attachment, boardId)
70+
const existingIndex = this.attachments[restoredAttachment.cardId].findIndex(a => a.id === restoredAttachment.id && a.type === restoredAttachment.type)
71+
if (existingIndex !== -1) {
72+
Vue.set(this.attachments[restoredAttachment.cardId][existingIndex], 'deletedAt', 0)
73+
}
74+
this.$vuex.commit('cardIncreaseAttachmentCount', attachment.cardId)
75+
},
76+
},
77+
78+
})

0 commit comments

Comments
 (0)