Skip to content

Commit d8e5c8f

Browse files
committed
Feat: Highlight cards with important labels
Signed-off-by: Kostiantyn Miakshyn <[email protected]>
1 parent 0a14a0d commit d8e5c8f

File tree

14 files changed

+187
-41
lines changed

14 files changed

+187
-41
lines changed

docs/API.md

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -212,28 +212,32 @@ Returns an array of board items
212212
"color": "31CC7C",
213213
"boardId": 10,
214214
"cardId": null,
215-
"id": 37
215+
"id": 37,
216+
"customSettings": {}
216217
},
217218
{
218219
"title": "To review",
219220
"color": "317CCC",
220221
"boardId": 10,
221222
"cardId": null,
222-
"id": 38
223+
"id": 38,
224+
"customSettings": {}
223225
},
224226
{
225227
"title": "Action needed",
226228
"color": "FF7A66",
227229
"boardId": 10,
228230
"cardId": null,
229-
"id": 39
231+
"id": 39,
232+
"customSettings": { "isImportant": true }
230233
},
231234
{
232235
"title": "Later",
233236
"color": "F1DB50",
234237
"boardId": 10,
235238
"cardId": null,
236-
"id": 40
239+
"id": 40,
240+
"customSettings": {}
237241
}
238242
],
239243
"acl": [],
@@ -282,28 +286,32 @@ A 403 response might be returned if the users ability to create new boards has b
282286
"color": "31CC7C",
283287
"boardId": "10",
284288
"cardId": null,
285-
"id": 37
289+
"id": 37,
290+
"customSettings": {}
286291
},
287292
{
288293
"title": "To review",
289294
"color": "317CCC",
290295
"boardId": "10",
291296
"cardId": null,
292-
"id": 38
297+
"id": 38,
298+
"customSettings": {}
293299
},
294300
{
295301
"title": "Action needed",
296302
"color": "FF7A66",
297303
"boardId": "10",
298304
"cardId": null,
299-
"id": 39
305+
"id": 39,
306+
"customSettings": {}
300307
},
301308
{
302309
"title": "Later",
303310
"color": "F1DB50",
304311
"boardId": "10",
305312
"cardId": null,
306-
"id": 40
313+
"id": 40,
314+
"customSettings": {}
307315
}
308316
],
309317
"acl": [],
@@ -867,24 +875,27 @@ The request can fail with a bad request response for the following reasons:
867875
"color": "31CC7C",
868876
"boardId": "2",
869877
"cardId": null,
870-
"id": 5
878+
"id": 5,
879+
"customSettings": { "isImportant": false }
871880
}
872881
```
873882

874883
### POST /boards/{boardId}/labels - Create a new label
875884

876885
#### Request parameters
877886

878-
| Parameter | Type | Description |
879-
| --------- | ------- | ---------------------------------------- |
880-
| boardId | Integer | The id of the board the label belongs to |
887+
| Parameter | Type | Description |
888+
|----------------|---------|------------------------------------------------------------------------------|
889+
| boardId | Integer | The id of the board the label belongs to |
890+
| customSettings | Object | An key-value structure, currently supported only bool property `isImportant` |
881891

882892
#### Request data
883893

884894
```json
885895
{
886896
"title": "Finished",
887-
"color": "31CC7C"
897+
"color": "31CC7C",
898+
"customSettings": { "isImportant": false }
888899
}
889900
```
890901

@@ -896,18 +907,20 @@ The request can fail with a bad request response for the following reasons:
896907

897908
#### Request parameters
898909

899-
| Parameter | Type | Description |
900-
| --------- | ------- | ---------------------------------------- |
901-
| boardId | Integer | The id of the board the label belongs to |
902-
| labelId | Integer | The id of the label |
910+
| Parameter | Type | Description |
911+
| --------- | ------- |-----------------------------------------------------------------------------------|
912+
| boardId | Integer | The id of the board the label belongs to |
913+
| labelId | Integer | The id of the label |
914+
| customSettings | Object | An key-value structure, currently supported only bool property `isImportant` |
903915

904916

905917
#### Request data
906918

907919
```json
908920
{
909921
"title": "Finished",
910-
"color": "31CC7C"
922+
"color": "31CC7C",
923+
"customSettings": { }
911924
}
912925
```
913926

lib/Controller/LabelApiController.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ public function get() {
5050
*
5151
* @params $title
5252
* @params $color
53+
* @param array<string, scalar> $customSettings
54+
*
5355
* Create a new label
5456
*/
55-
public function create($title, $color) {
56-
$label = $this->labelService->create($title, $color, $this->request->getParam('boardId'));
57+
public function create($title, $color, array $customSettings = []) {
58+
$label = $this->labelService->create($title, $color, $this->request->getParam('boardId'), $customSettings);
5759
return new DataResponse($label, HTTP::STATUS_OK);
5860
}
5961

@@ -64,10 +66,12 @@ public function create($title, $color) {
6466
*
6567
* @params $title
6668
* @params $color
69+
* @param array<string, scalar> $customSettings
70+
*
6771
* Update a specific label
6872
*/
69-
public function update($title, $color) {
70-
$label = $this->labelService->update($this->request->getParam('labelId'), $title, $color);
73+
public function update($title, $color, array $customSettings = []) {
74+
$label = $this->labelService->update($this->request->getParam('labelId'), $title, $color, $customSettings);
7175
return new DataResponse($label, HTTP::STATUS_OK);
7276
}
7377

lib/Controller/LabelController.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,23 @@ public function __construct(
2525
* @param $title
2626
* @param $color
2727
* @param $boardId
28+
* @param array<string, scalar> $customSettings
2829
* @return \OCP\AppFramework\Db\Entity
2930
*/
30-
public function create($title, $color, $boardId) {
31-
return $this->labelService->create($title, $color, $boardId);
31+
public function create($title, $color, $boardId, array $customSettings = []) {
32+
return $this->labelService->create($title, $color, $boardId, $customSettings);
3233
}
3334

3435
/**
3536
* @NoAdminRequired
3637
* @param $id
3738
* @param $title
3839
* @param $color
40+
* @param array<string, scalar> $customSettings
3941
* @return \OCP\AppFramework\Db\Entity
4042
*/
41-
public function update($id, $title, $color) {
42-
return $this->labelService->update($id, $title, $color);
43+
public function update($id, $title, $color, array $customSettings = []) {
44+
return $this->labelService->update($id, $title, $color, $customSettings);
4345
}
4446

4547
/**

lib/Db/Label.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,41 @@
99

1010
/**
1111
* @method getTitle(): string
12+
* @method getCustomSettings(): string
13+
* @method setCustomSettings(string $customSettings)
1214
*/
1315
class Label extends RelationalEntity {
1416
protected $title;
1517
protected $color;
1618
protected $boardId;
1719
protected $cardId;
1820
protected $lastModified;
21+
protected $customSettings;
1922

2023
public function __construct() {
2124
$this->addType('id', 'integer');
2225
$this->addType('boardId', 'integer');
2326
$this->addType('cardId', 'integer');
2427
$this->addType('lastModified', 'integer');
28+
$this->addType('customSettings', 'string');
2529
}
2630

2731
public function getETag() {
2832
return md5((string)$this->getLastModified());
2933
}
34+
35+
public function getCustomSettingsArray(): array {
36+
return $this->customSettings ? json_decode($this->customSettings, true) : [];
37+
}
38+
39+
public function setCustomSettingsArray(array $customSettings): void {
40+
$this->setCustomSettings(json_encode($customSettings ?: new \stdClass()));
41+
}
42+
43+
public function jsonSerialize(): array {
44+
$data = parent::jsonSerialize();
45+
$data['customSettings'] = $this->getCustomSettingsArray() ?: new \stdClass();
46+
47+
return $data;
48+
}
3049
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/**
4+
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
5+
* SPDX-License-Identifier: AGPL-3.0-or-later
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OCA\Deck\Migration;
11+
12+
use Closure;
13+
use OCP\DB\ISchemaWrapper;
14+
use OCP\DB\Types;
15+
use OCP\Migration\IOutput;
16+
use OCP\Migration\SimpleMigrationStep;
17+
18+
class Version20000Date20250907000000 extends SimpleMigrationStep {
19+
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
20+
/** @var ISchemaWrapper $schema */
21+
$schema = $schemaClosure();
22+
23+
$table = $schema->getTable('deck_labels');
24+
if (!$table->hasColumn('custom_settings')) {
25+
$table->addColumn('custom_settings', Types::JSON, [
26+
'notnull' => false,
27+
]);
28+
}
29+
30+
return $schema;
31+
}
32+
}

lib/Service/CardService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ public function update($id, $title, $stackId, $type, $owner, $description = '',
340340
// clone labels that are assigned to card but don't exist in new board
341341
if (empty($filteredLabels)) {
342342
if ($this->permissionService->getPermissions($boardId)[Acl::PERMISSION_MANAGE] === true) {
343-
$newLabel = $this->labelService->create($label->getTitle(), $label->getColor(), $board->getId());
343+
$newLabel = $this->labelService->create($label->getTitle(), $label->getColor(), $board->getId(), $label->getCustomSettingsArray());
344344
$boardLabels[] = $label;
345345
$this->assignLabel($card->getId(), $newLabel->getId());
346346
}

lib/Service/LabelService.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,15 @@ public function find($labelId) {
6262
* @param $title
6363
* @param $color
6464
* @param $boardId
65+
* @param array<string, scalar> $customSettings
6566
* @return \OCP\AppFramework\Db\Entity
6667
* @throws StatusException
6768
* @throws \OCA\Deck\NoPermissionException
6869
* @throws \OCP\AppFramework\Db\DoesNotExistException
6970
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
7071
* @throws BadRequestException
7172
*/
72-
public function create($title, $color, $boardId) {
73+
public function create($title, $color, $boardId, array $customSettings = []) {
7374
$this->labelServiceValidator->check(compact('title', 'color', 'boardId'));
7475

7576
$this->permissionService->checkPermission(null, $boardId, Acl::PERMISSION_MANAGE);
@@ -89,6 +90,7 @@ public function create($title, $color, $boardId) {
8990
$label->setTitle($title);
9091
$label->setColor($color);
9192
$label->setBoardId($boardId);
93+
$label->setCustomSettingsArray($customSettings);
9294
$this->changeHelper->boardChanged($boardId);
9395
return $this->labelMapper->insert($label);
9496
}
@@ -99,7 +101,7 @@ public function cloneLabelIfNotExists(int $labelId, int $targetBoardId): Label {
99101
$originLabel = $this->find($labelId);
100102
$filteredValues = array_values(array_filter($boardLabels, fn ($item) => $item->getTitle() === $originLabel->getTitle()));
101103
if (empty($filteredValues)) {
102-
$label = $this->create($originLabel->getTitle(), $originLabel->getColor(), $targetBoardId);
104+
$label = $this->create($originLabel->getTitle(), $originLabel->getColor(), $targetBoardId, $originLabel->getCustomSettingsArray());
103105
return $label;
104106
}
105107
return $originLabel;
@@ -130,14 +132,15 @@ public function delete($id) {
130132
* @param $id
131133
* @param $title
132134
* @param $color
135+
* @param array<string, scalar> $customSettings
133136
* @return \OCP\AppFramework\Db\Entity
134137
* @throws StatusException
135138
* @throws \OCA\Deck\NoPermissionException
136139
* @throws \OCP\AppFramework\Db\DoesNotExistException
137140
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException
138141
* @throws BadRequestException
139142
*/
140-
public function update($id, $title, $color) {
143+
public function update($id, $title, $color, array $customSettings = []) {
141144
$this->labelServiceValidator->check(compact('title', 'color', 'id'));
142145

143146
$this->permissionService->checkPermission($this->labelMapper, $id, Acl::PERMISSION_MANAGE);
@@ -161,6 +164,7 @@ public function update($id, $title, $color) {
161164

162165
$label->setTitle($title);
163166
$label->setColor($color);
167+
$label->setCustomSettingsArray($customSettings);
164168
$this->changeHelper->boardChanged($label->getBoardId());
165169
return $this->labelMapper->update($label);
166170
}

src/components/board/Board.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ export default {
314314
flex-direction: column;
315315
// Margin left instead of padidng to avoid jumps on dropping a card
316316
margin-left: $stack-spacing;
317+
padding-left: 5px;
317318
padding-right: $stack-spacing;
318319
overflow-x: hidden;
319320
overflow-y: auto;

src/components/board/BoardSidebar.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<NcAppSidebar v-if="board != null"
88
:actions="[]"
99
:name="board.title"
10+
style="width: 400px"
1011
@close="closeSidebar">
1112
<NcAppSidebarTab id="sharing"
1213
:order="0"

0 commit comments

Comments
 (0)