Skip to content

Commit 696ca2f

Browse files
committed
fix: pass boardId to attachmentController
Signed-off-by: grnd-alt <git@belakkaf.net>
1 parent 30d5122 commit 696ca2f

File tree

6 files changed

+164
-35
lines changed

6 files changed

+164
-35
lines changed

appinfo/routes.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@
147147
['name' => 'stack_ocs#create', 'url' => '/api/v{apiVersion}/stacks', 'verb' => 'POST'],
148148
['name' => 'stack_ocs#delete', 'url' => '/api/v{apiVersion}/stacks/{stackId}/{boardId}', 'verb' => 'DELETE', 'defaults' => ['boardId' => null]],
149149

150+
['name' => 'attachment_ocs#getAll', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments', 'verb' => 'GET'],
151+
['name' => 'attachment_ocs#create', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachment', 'verb' => 'POST'],
152+
['name' => 'attachment_ocs#update', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'PUT'],
153+
['name' => 'attachment_ocs#delete', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'DELETE'],
154+
['name' => 'attachment_ocs#restore', 'url' => '/api/v{apiVersion}/cards/{cardId}/attachments/{attachmentId}/restore', 'verb' => 'PUT'],
155+
150156
['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'],
151157
['name' => 'Config#setValue', 'url' => '/api/v{apiVersion}/config/{key}', 'verb' => 'POST'],
152158

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
namespace OCA\Deck\Controller;
10+
11+
use OCA\Deck\NotImplementedException;
12+
use OCA\Deck\Service\AttachmentService;
13+
use OCA\Deck\Service\BoardService;
14+
use OCP\AppFramework\Http\Attribute\CORS;
15+
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
16+
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
17+
use OCP\AppFramework\Http\DataResponse;
18+
use OCP\AppFramework\OCSController;
19+
use OCP\IRequest;
20+
21+
class AttachmentOcsController extends OCSController {
22+
public function __construct(
23+
string $appName,
24+
IRequest $request,
25+
private AttachmentService $attachmentService,
26+
private BoardService $boardService,
27+
) {
28+
parent::__construct($appName, $request);
29+
}
30+
31+
private function ensureLocalBoard(?int $boardId): void {
32+
if ($boardId) {
33+
$board = $this->boardService->find($boardId);
34+
if ($board->getExternalId()) {
35+
throw new NotImplementedException('attachments for federated boards are not supported');
36+
}
37+
}
38+
}
39+
40+
#[NoAdminRequired]
41+
#[CORS]
42+
#[NoCSRFRequired]
43+
public function getAll(int $cardId, ?int $boardId = null): DataResponse {
44+
$this->ensureLocalBoard($boardId);
45+
$attachment = $this->attachmentService->findAll($cardId, true);
46+
return new DataResponse($attachment);
47+
}
48+
49+
#[NoAdminRequired]
50+
#[CORS]
51+
#[NoCSRFRequired]
52+
public function create(int $cardId, string $type, string $data = '', ?int $boardId = null): DataResponse {
53+
$this->ensureLocalBoard($boardId);
54+
$attachment = $this->attachmentService->create($cardId, $type, $data);
55+
return new DataResponse($attachment);
56+
}
57+
58+
#[NoAdminRequired]
59+
#[CORS]
60+
#[NoCSRFRequired]
61+
public function update(int $cardId, int $attachmentId, string $data, string $type = 'file', ?int $boardId = null): DataResponse {
62+
$this->ensureLocalBoard($boardId);
63+
$attachment = $this->attachmentService->update($cardId, $attachmentId, $data, $type);
64+
return new DataResponse($attachment);
65+
}
66+
67+
#[NoAdminRequired]
68+
#[CORS]
69+
#[NoCSRFRequired]
70+
public function delete(int $cardId, int $attachmentId, string $type = 'file', ?int $boardId = null): DataResponse {
71+
$this->ensureLocalBoard($boardId);
72+
$attachment = $this->attachmentService->delete($cardId, $attachmentId, $type);
73+
return new DataResponse($attachment);
74+
}
75+
76+
#[NoAdminRequired]
77+
#[CORS]
78+
#[NoCSRFRequired]
79+
public function restore(int $cardId, int $attachmentId, string $type = 'file', ?int $boardId = null): DataResponse {
80+
$this->ensureLocalBoard($boardId);
81+
$attachment = $this->attachmentService->restore($cardId, $attachmentId, $type);
82+
return new DataResponse($attachment);
83+
}
84+
85+
}

lib/NotImplementedException.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/**
4+
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
namespace OCA\Deck;
9+
10+
use OCP\AppFramework\Http;
11+
12+
class NotImplementedException extends StatusException {
13+
public function __construct($message) {
14+
parent::__construct($message);
15+
}
16+
17+
public function getStatus() {
18+
return HTTP::STATUS_NOT_IMPLEMENTED;
19+
}
20+
}

lib/Service/AttachmentService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public function count(int $cardId): int {
160160
* @throws StatusException
161161
* @throws BadRequestException
162162
*/
163-
public function create(int $cardId, string $type, string $data) {
163+
public function create(int $cardId, string $type, string $data = '') {
164164
$this->attachmentServiceValidator->check(compact('cardId', 'type'));
165165

166166
$this->permissionService->checkPermission($this->cardMapper, $cardId, Acl::PERMISSION_EDIT);

src/services/AttachmentApi.js

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,62 +4,74 @@
44
*/
55

66
import axios from '@nextcloud/axios'
7-
import { generateUrl } from '@nextcloud/router'
7+
import { generateOcsUrl, generateUrl } from '@nextcloud/router'
88

99
export class AttachmentApi {
1010

1111
url(url) {
1212
return generateUrl(`/apps/deck${url}`)
1313
}
1414

15-
async fetchAttachments(cardId) {
15+
ocsUrl(url) {
16+
url = `/apps/deck/api/v1.0${url}`
17+
return generateOcsUrl(url)
18+
}
19+
20+
async fetchAttachments(cardId, boardId) {
1621
const response = await axios({
1722
method: 'GET',
18-
url: this.url(`/cards/${cardId}/attachments`),
23+
url: this.ocsUrl(`/cards/${cardId}/attachments`),
24+
params: {
25+
boardId: boardId ?? null,
26+
},
1927
})
20-
return response.data
28+
return response.data.ocs.data
2129
}
2230

23-
async createAttachment({ cardId, formData, onUploadProgress }) {
31+
async createAttachment({ cardId, formData, onUploadProgress, boardId }) {
2432
const response = await axios({
2533
method: 'POST',
26-
url: this.url(`/cards/${cardId}/attachment`),
34+
url: this.ocsUrl(`/cards/${cardId}/attachment`),
35+
params: {
36+
boardId: boardId ?? null,
37+
},
2738
data: formData,
2839
onUploadProgress,
2940
})
30-
return response.data
41+
return response.data.ocs.data
3142
}
3243

33-
async updateAttachment({ cardId, attachment, formData }) {
44+
async updateAttachment({ cardId, attachment, formData, boardId }) {
3445
const response = await axios({
3546
method: 'POST',
36-
url: this.url(`/cards/${cardId}/attachment/${attachment.type}:${attachment.id}`),
47+
url: this.ocsUrl(`/cards/${cardId}/attachment/${attachment.type}:${attachment.id}`),
48+
params: {
49+
boardId: boardId ?? null,
50+
},
3751
data: formData,
3852
})
3953
return response.data
4054
}
4155

42-
async deleteAttachment(attachment) {
56+
async deleteAttachment(attachment, boardId) {
4357
await axios({
4458
method: 'DELETE',
45-
url: this.url(`/cards/${attachment.cardId}/attachment/${attachment.type}:${attachment.id}`),
46-
})
47-
}
48-
49-
async restoreAttachment(attachment) {
50-
const response = await axios({
51-
method: 'GET',
52-
url: this.url(`/cards/${attachment.cardId}/attachment/${attachment.type}:${attachment.id}/restore`),
59+
url: this.ocsUrl(`/cards/${attachment.cardId}/attachment/${attachment.type}:${attachment.id}`),
60+
params: {
61+
boardId: boardId ?? null,
62+
},
5363
})
54-
return response.data
5564
}
5665

57-
async displayAttachment(attachment) {
66+
async restoreAttachment(attachment, boardId) {
5867
const response = await axios({
5968
method: 'GET',
60-
url: this.url(`/cards/${attachment.cardId}/attachment/${attachment.type}:${attachment.id}`),
69+
url: this.ocsUrl(`/cards/${attachment.cardId}/attachment/${attachment.type}:${attachment.id}/restore`),
70+
params: {
71+
boardId: boardId ?? null,
72+
},
6173
})
62-
return response.data
74+
return response.data.ocs.data
6375
}
6476

6577
}

src/store/attachment.js

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,37 +64,43 @@ export default {
6464

6565
},
6666
actions: {
67-
async fetchAttachments({ commit }, cardId) {
68-
const attachments = await apiClient.fetchAttachments(cardId)
67+
async fetchAttachments({ commit, rootState }, cardId) {
68+
const boardId = rootState.currentBoard.id
69+
const attachments = await apiClient.fetchAttachments(cardId, boardId)
6970
commit('createAttachments', { cardId, attachments })
7071
commit('cardSetAttachmentCount', { cardId, count: attachments.length })
7172
},
7273

73-
async createAttachment({ commit }, { cardId, formData, onUploadProgress }) {
74-
const attachment = await apiClient.createAttachment({ cardId, formData, onUploadProgress })
74+
async createAttachment({ commit, rootState }, { cardId, formData, onUploadProgress }) {
75+
const boardId = rootState.currentBoard.id
76+
const attachment = await apiClient.createAttachment({ cardId, formData, onUploadProgress, boardId })
7577
commit('createAttachment', { cardId, attachment })
7678
commit('cardIncreaseAttachmentCount', cardId)
7779
},
7880

79-
async updateAttachment({ commit }, { cardId, attachment, formData }) {
80-
const result = await apiClient.updateAttachment({ cardId, attachment, formData })
81+
async updateAttachment({ commit, rootState }, { cardId, attachment, formData }) {
82+
const boardId = rootState.currentBoard.id
83+
const result = await apiClient.updateAttachment({ cardId, attachment, formData, boardId })
8184
commit('updateAttachment', { cardId, attachment: result })
8285
},
8386

84-
async deleteAttachment({ commit }, attachment) {
85-
await apiClient.deleteAttachment(attachment)
87+
async deleteAttachment({ commit, rootState }, attachment) {
88+
const boardId = rootState.currentBoard.id
89+
await apiClient.deleteAttachment(attachment, boardId)
8690
commit('deleteAttachment', attachment)
8791
commit('cardDecreaseAttachmentCount', attachment.cardId)
8892
},
8993

90-
async unshareAttachment({ commit }, attachment) {
91-
await apiClient.deleteAttachment(attachment)
94+
async unshareAttachment({ commit, rootState }, attachment) {
95+
const boardId = rootState.currentBoard.id
96+
await apiClient.deleteAttachment(attachment, boardId)
9297
commit('unshareAttachment', attachment)
9398
commit('cardDecreaseAttachmentCount', attachment.cardId)
9499
},
95100

96-
async restoreAttachment({ commit }, attachment) {
97-
const restoredAttachment = await apiClient.restoreAttachment(attachment)
101+
async restoreAttachment({ commit, rootState }, attachment) {
102+
const boardId = rootState.currentBoard.id
103+
const restoredAttachment = await apiClient.restoreAttachment(attachment, boardId)
98104
commit('restoreAttachment', restoredAttachment)
99105
commit('cardIncreaseAttachmentCount', attachment.cardId)
100106
},

0 commit comments

Comments
 (0)