trello-cli-unofficial 0.13.13 β 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +21 -761
- package/dist/main.js +240 -8
- package/package.json +7 -2
- package/src/application/use-cases/AddChecklistItemUseCase.ts +15 -0
- package/src/application/use-cases/CreateChecklistUseCase.ts +15 -0
- package/src/application/use-cases/index.ts +2 -0
- package/src/domain/entities/Checklist.ts +65 -0
- package/src/domain/entities/index.ts +1 -0
- package/src/domain/repositories/TrelloRepository.ts +4 -0
- package/src/i18n/locales/en.json +31 -1
- package/src/i18n/locales/pt-BR.json +31 -1
- package/src/infrastructure/repositories/TrelloApiRepository.ts +53 -1
- package/src/presentation/cli/CardController.ts +22 -6
- package/src/presentation/cli/ChecklistController.ts +48 -0
- package/src/presentation/cli/CommandController.ts +45 -1
- package/src/presentation/cli/TrelloCliController.ts +1 -3
- package/src/presentation/cli/index.ts +1 -0
package/dist/main.js
CHANGED
|
@@ -2962,7 +2962,23 @@ var require_en = __commonJS((exports, module) => {
|
|
|
2962
2962
|
checklists: "\u2705 Checklists:",
|
|
2963
2963
|
attachments: "\uD83D\uDCCE Attachments:",
|
|
2964
2964
|
location: "\uD83D\uDCCD Board:",
|
|
2965
|
-
list: "\uD83D\uDCCB List:"
|
|
2965
|
+
list: "\uD83D\uDCCB List:",
|
|
2966
|
+
checklistTitle: "\uD83D\uDCCB {{name}}",
|
|
2967
|
+
checklistProgress: " [{{done}}/{{total}}]",
|
|
2968
|
+
checklistItemDone: " \u2611 {{name}}",
|
|
2969
|
+
checklistItemPending: " \u2610 {{name}}"
|
|
2970
|
+
}
|
|
2971
|
+
},
|
|
2972
|
+
checklist: {
|
|
2973
|
+
created: '\u2705 Checklist "{{name}}" created successfully!',
|
|
2974
|
+
checklistId: "\uD83C\uDD94 ID: {{id}}",
|
|
2975
|
+
checklistCard: "\uD83D\uDCCB Card ID: {{idCard}}",
|
|
2976
|
+
itemAdded: '\u2705 Item "{{name}}" added to checklist successfully!',
|
|
2977
|
+
itemId: "\uD83C\uDD94 ID: {{id}}",
|
|
2978
|
+
itemState: "\uD83D\uDCCC State: {{state}}",
|
|
2979
|
+
validation: {
|
|
2980
|
+
requiredName: "Checklist name is required",
|
|
2981
|
+
requiredItemName: "Item name is required"
|
|
2966
2982
|
}
|
|
2967
2983
|
},
|
|
2968
2984
|
errors: {
|
|
@@ -3111,6 +3127,20 @@ var require_en = __commonJS((exports, module) => {
|
|
|
3111
3127
|
delete: {
|
|
3112
3128
|
description: "Delete a card"
|
|
3113
3129
|
}
|
|
3130
|
+
},
|
|
3131
|
+
checklists: {
|
|
3132
|
+
description: "Manage checklists on Trello cards",
|
|
3133
|
+
create: {
|
|
3134
|
+
description: "Create a checklist on a card",
|
|
3135
|
+
nameOption: "Checklist name"
|
|
3136
|
+
},
|
|
3137
|
+
item: {
|
|
3138
|
+
description: "Manage checklist items",
|
|
3139
|
+
add: {
|
|
3140
|
+
description: "Add an item to a checklist",
|
|
3141
|
+
nameOption: "Item name"
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3114
3144
|
}
|
|
3115
3145
|
}
|
|
3116
3146
|
};
|
|
@@ -3257,7 +3287,23 @@ var require_pt_BR = __commonJS((exports, module) => {
|
|
|
3257
3287
|
checklists: "\u2705 Checklists:",
|
|
3258
3288
|
attachments: "\uD83D\uDCCE Anexos:",
|
|
3259
3289
|
location: "\uD83D\uDCCD Board:",
|
|
3260
|
-
list: "\uD83D\uDCCB List:"
|
|
3290
|
+
list: "\uD83D\uDCCB List:",
|
|
3291
|
+
checklistTitle: "\uD83D\uDCCB {{name}}",
|
|
3292
|
+
checklistProgress: " [{{done}}/{{total}}]",
|
|
3293
|
+
checklistItemDone: " \u2611 {{name}}",
|
|
3294
|
+
checklistItemPending: " \u2610 {{name}}"
|
|
3295
|
+
}
|
|
3296
|
+
},
|
|
3297
|
+
checklist: {
|
|
3298
|
+
created: '\u2705 Checklist "{{name}}" criado com sucesso!',
|
|
3299
|
+
checklistId: "\uD83C\uDD94 ID: {{id}}",
|
|
3300
|
+
checklistCard: "\uD83D\uDCCB ID do Card: {{idCard}}",
|
|
3301
|
+
itemAdded: '\u2705 Item "{{name}}" adicionado ao checklist com sucesso!',
|
|
3302
|
+
itemId: "\uD83C\uDD94 ID: {{id}}",
|
|
3303
|
+
itemState: "\uD83D\uDCCC Estado: {{state}}",
|
|
3304
|
+
validation: {
|
|
3305
|
+
requiredName: "Nome do checklist \xE9 obrigat\xF3rio",
|
|
3306
|
+
requiredItemName: "Nome do item \xE9 obrigat\xF3rio"
|
|
3261
3307
|
}
|
|
3262
3308
|
},
|
|
3263
3309
|
errors: {
|
|
@@ -3406,6 +3452,20 @@ var require_pt_BR = __commonJS((exports, module) => {
|
|
|
3406
3452
|
delete: {
|
|
3407
3453
|
description: "Deleta um card"
|
|
3408
3454
|
}
|
|
3455
|
+
},
|
|
3456
|
+
checklists: {
|
|
3457
|
+
description: "Gerencia checklists nos cards do Trello",
|
|
3458
|
+
create: {
|
|
3459
|
+
description: "Cria um checklist em um card",
|
|
3460
|
+
nameOption: "Nome do checklist"
|
|
3461
|
+
},
|
|
3462
|
+
item: {
|
|
3463
|
+
description: "Gerencia itens de checklist",
|
|
3464
|
+
add: {
|
|
3465
|
+
description: "Adiciona um item a um checklist",
|
|
3466
|
+
nameOption: "Nome do item"
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3409
3469
|
}
|
|
3410
3470
|
}
|
|
3411
3471
|
};
|
|
@@ -3492,6 +3552,23 @@ var init_i18n = __esm(() => {
|
|
|
3492
3552
|
});
|
|
3493
3553
|
});
|
|
3494
3554
|
|
|
3555
|
+
// src/application/use-cases/AddChecklistItemUseCase.ts
|
|
3556
|
+
class AddChecklistItemUseCase {
|
|
3557
|
+
trelloRepository;
|
|
3558
|
+
constructor(trelloRepository) {
|
|
3559
|
+
this.trelloRepository = trelloRepository;
|
|
3560
|
+
}
|
|
3561
|
+
async execute(checklistId, name) {
|
|
3562
|
+
if (!name.trim()) {
|
|
3563
|
+
throw new Error(t2("checklist.validation.requiredItemName"));
|
|
3564
|
+
}
|
|
3565
|
+
return await this.trelloRepository.addChecklistItem(checklistId, name);
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
var init_AddChecklistItemUseCase = __esm(() => {
|
|
3569
|
+
init_i18n();
|
|
3570
|
+
});
|
|
3571
|
+
|
|
3495
3572
|
// src/domain/services/AuthenticationService.ts
|
|
3496
3573
|
class AuthenticationService {
|
|
3497
3574
|
configRepository;
|
|
@@ -3597,6 +3674,23 @@ var init_CreateCardUseCase = __esm(() => {
|
|
|
3597
3674
|
init_i18n();
|
|
3598
3675
|
});
|
|
3599
3676
|
|
|
3677
|
+
// src/application/use-cases/CreateChecklistUseCase.ts
|
|
3678
|
+
class CreateChecklistUseCase {
|
|
3679
|
+
trelloRepository;
|
|
3680
|
+
constructor(trelloRepository) {
|
|
3681
|
+
this.trelloRepository = trelloRepository;
|
|
3682
|
+
}
|
|
3683
|
+
async execute(cardId, name) {
|
|
3684
|
+
if (!name.trim()) {
|
|
3685
|
+
throw new Error(t2("checklist.validation.requiredName"));
|
|
3686
|
+
}
|
|
3687
|
+
return await this.trelloRepository.createChecklist(cardId, name);
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
var init_CreateChecklistUseCase = __esm(() => {
|
|
3691
|
+
init_i18n();
|
|
3692
|
+
});
|
|
3693
|
+
|
|
3600
3694
|
// src/application/use-cases/CreateListUseCase.ts
|
|
3601
3695
|
class CreateListUseCase {
|
|
3602
3696
|
trelloRepository;
|
|
@@ -3736,9 +3830,11 @@ var init_UpdateCardUseCase = __esm(() => {
|
|
|
3736
3830
|
|
|
3737
3831
|
// src/application/use-cases/index.ts
|
|
3738
3832
|
var init_use_cases = __esm(() => {
|
|
3833
|
+
init_AddChecklistItemUseCase();
|
|
3739
3834
|
init_AuthenticateUserUseCase();
|
|
3740
3835
|
init_CreateBoardUseCase();
|
|
3741
3836
|
init_CreateCardUseCase();
|
|
3837
|
+
init_CreateChecklistUseCase();
|
|
3742
3838
|
init_CreateListUseCase();
|
|
3743
3839
|
init_GetBoardDetailsUseCase();
|
|
3744
3840
|
init_UpdateCardUseCase();
|
|
@@ -25945,13 +26041,28 @@ class CardController {
|
|
|
25945
26041
|
this.outputFormatter.message(`${t2("card.show.members")} ${displayMembers}`);
|
|
25946
26042
|
}
|
|
25947
26043
|
if (card.checklists && card.checklists.length > 0) {
|
|
25948
|
-
|
|
26044
|
+
this.outputFormatter.message("");
|
|
26045
|
+
this.outputFormatter.message(t2("card.show.checklists"));
|
|
26046
|
+
for (const cl of card.checklists) {
|
|
25949
26047
|
const checkItems = Array.isArray(cl.checkItems) ? cl.checkItems : [];
|
|
25950
|
-
const
|
|
26048
|
+
const done = checkItems.filter((item) => item.state === "complete").length;
|
|
25951
26049
|
const total = checkItems.length;
|
|
25952
|
-
|
|
25953
|
-
|
|
25954
|
-
|
|
26050
|
+
const filledCount = total > 0 ? Math.round(done / total * 10) : 0;
|
|
26051
|
+
const bar = "\u2588".repeat(filledCount) + "\u2591".repeat(10 - filledCount);
|
|
26052
|
+
const pct = total > 0 ? Math.round(done / total * 100) : 0;
|
|
26053
|
+
const title = t2("card.show.checklistTitle", { name: String(cl.name) });
|
|
26054
|
+
const progress = t2("card.show.checklistProgress", { done, total });
|
|
26055
|
+
this.outputFormatter.message(` ${title}${progress} ${bar} ${pct}%`);
|
|
26056
|
+
for (const item of checkItems) {
|
|
26057
|
+
const checkItem = item;
|
|
26058
|
+
if (checkItem.state === "complete") {
|
|
26059
|
+
this.outputFormatter.message(t2("card.show.checklistItemDone", { name: checkItem.name }));
|
|
26060
|
+
} else {
|
|
26061
|
+
this.outputFormatter.message(t2("card.show.checklistItemPending", { name: checkItem.name }));
|
|
26062
|
+
}
|
|
26063
|
+
}
|
|
26064
|
+
this.outputFormatter.message("");
|
|
26065
|
+
}
|
|
25955
26066
|
}
|
|
25956
26067
|
if (card.attachments && card.attachments.length > 0) {
|
|
25957
26068
|
this.outputFormatter.message(`${t2("card.show.attachments")} ${card.attachments.length} file(s)`);
|
|
@@ -26004,6 +26115,42 @@ var init_CardController = __esm(() => {
|
|
|
26004
26115
|
init_i18n();
|
|
26005
26116
|
});
|
|
26006
26117
|
|
|
26118
|
+
// src/presentation/cli/ChecklistController.ts
|
|
26119
|
+
class ChecklistController {
|
|
26120
|
+
outputFormatter;
|
|
26121
|
+
createChecklistUseCase;
|
|
26122
|
+
addChecklistItemUseCase;
|
|
26123
|
+
constructor(trelloRepository, outputFormatter) {
|
|
26124
|
+
this.outputFormatter = outputFormatter;
|
|
26125
|
+
this.createChecklistUseCase = new CreateChecklistUseCase(trelloRepository);
|
|
26126
|
+
this.addChecklistItemUseCase = new AddChecklistItemUseCase(trelloRepository);
|
|
26127
|
+
}
|
|
26128
|
+
async createChecklist(cardId, name) {
|
|
26129
|
+
const checklist = await this.createChecklistUseCase.execute(cardId, name);
|
|
26130
|
+
console.log(t2("checklist.created", { name: checklist.name }));
|
|
26131
|
+
console.log(t2("checklist.checklistId", { id: checklist.id }));
|
|
26132
|
+
console.log(t2("checklist.checklistCard", { idCard: checklist.idCard }));
|
|
26133
|
+
this.outputFormatter.output([checklist], {
|
|
26134
|
+
headers: ["ID", "Name", "Card ID", "Items"],
|
|
26135
|
+
fields: ["id", "name", "idCard", "checkItems"]
|
|
26136
|
+
});
|
|
26137
|
+
}
|
|
26138
|
+
async addChecklistItem(checklistId, name) {
|
|
26139
|
+
const item = await this.addChecklistItemUseCase.execute(checklistId, name);
|
|
26140
|
+
console.log(t2("checklist.itemAdded", { name: item.name }));
|
|
26141
|
+
console.log(t2("checklist.itemId", { id: item.id }));
|
|
26142
|
+
console.log(t2("checklist.itemState", { state: item.state }));
|
|
26143
|
+
this.outputFormatter.output([item], {
|
|
26144
|
+
headers: ["ID", "Name", "State", "Checklist ID"],
|
|
26145
|
+
fields: ["id", "name", "state", "idChecklist"]
|
|
26146
|
+
});
|
|
26147
|
+
}
|
|
26148
|
+
}
|
|
26149
|
+
var init_ChecklistController = __esm(() => {
|
|
26150
|
+
init_use_cases();
|
|
26151
|
+
init_i18n();
|
|
26152
|
+
});
|
|
26153
|
+
|
|
26007
26154
|
// src/domain/entities/Board.ts
|
|
26008
26155
|
class BoardEntity {
|
|
26009
26156
|
id;
|
|
@@ -26056,6 +26203,39 @@ class CardEntity {
|
|
|
26056
26203
|
}
|
|
26057
26204
|
}
|
|
26058
26205
|
|
|
26206
|
+
// src/domain/entities/Checklist.ts
|
|
26207
|
+
class ChecklistItemEntity {
|
|
26208
|
+
id;
|
|
26209
|
+
name;
|
|
26210
|
+
state;
|
|
26211
|
+
idChecklist;
|
|
26212
|
+
constructor(id, name, state, idChecklist) {
|
|
26213
|
+
this.id = id;
|
|
26214
|
+
this.name = name;
|
|
26215
|
+
this.state = state;
|
|
26216
|
+
this.idChecklist = idChecklist;
|
|
26217
|
+
}
|
|
26218
|
+
static fromApiResponse(data) {
|
|
26219
|
+
return new ChecklistItemEntity(data.id, data.name, data.state === "complete" ? "complete" : "incomplete", data.idChecklist);
|
|
26220
|
+
}
|
|
26221
|
+
}
|
|
26222
|
+
|
|
26223
|
+
class ChecklistEntity {
|
|
26224
|
+
id;
|
|
26225
|
+
name;
|
|
26226
|
+
idCard;
|
|
26227
|
+
checkItems;
|
|
26228
|
+
constructor(id, name, idCard, checkItems) {
|
|
26229
|
+
this.id = id;
|
|
26230
|
+
this.name = name;
|
|
26231
|
+
this.idCard = idCard;
|
|
26232
|
+
this.checkItems = checkItems;
|
|
26233
|
+
}
|
|
26234
|
+
static fromApiResponse(data) {
|
|
26235
|
+
return new ChecklistEntity(data.id, data.name, data.idCard, (data.checkItems || []).map((item) => ChecklistItemEntity.fromApiResponse(item)));
|
|
26236
|
+
}
|
|
26237
|
+
}
|
|
26238
|
+
|
|
26059
26239
|
// src/domain/entities/Config.ts
|
|
26060
26240
|
class ConfigEntity {
|
|
26061
26241
|
apiKey;
|
|
@@ -28416,6 +28596,36 @@ ${errorText}`);
|
|
|
28416
28596
|
const data = await this.request(endpoint);
|
|
28417
28597
|
return CardEntity.fromApiResponse(data);
|
|
28418
28598
|
}
|
|
28599
|
+
async createChecklist(cardId, name) {
|
|
28600
|
+
const body = new URLSearchParams({
|
|
28601
|
+
name,
|
|
28602
|
+
key: this.apiKey,
|
|
28603
|
+
token: this.token
|
|
28604
|
+
});
|
|
28605
|
+
const data = await this.request(`/cards/${cardId}/checklists`, {
|
|
28606
|
+
method: "POST",
|
|
28607
|
+
headers: {
|
|
28608
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
28609
|
+
},
|
|
28610
|
+
body: body.toString()
|
|
28611
|
+
});
|
|
28612
|
+
return ChecklistEntity.fromApiResponse(data);
|
|
28613
|
+
}
|
|
28614
|
+
async addChecklistItem(checklistId, name) {
|
|
28615
|
+
const body = new URLSearchParams({
|
|
28616
|
+
name,
|
|
28617
|
+
key: this.apiKey,
|
|
28618
|
+
token: this.token
|
|
28619
|
+
});
|
|
28620
|
+
const data = await this.request(`/checklists/${checklistId}/checkItems`, {
|
|
28621
|
+
method: "POST",
|
|
28622
|
+
headers: {
|
|
28623
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
28624
|
+
},
|
|
28625
|
+
body: body.toString()
|
|
28626
|
+
});
|
|
28627
|
+
return ChecklistItemEntity.fromApiResponse(data);
|
|
28628
|
+
}
|
|
28419
28629
|
}
|
|
28420
28630
|
var init_TrelloApiRepository = __esm(() => {
|
|
28421
28631
|
init_entities();
|
|
@@ -30834,7 +31044,6 @@ class TrelloCliController {
|
|
|
30834
31044
|
constructor(configRepository, outputFormatter) {
|
|
30835
31045
|
this.configRepository = configRepository;
|
|
30836
31046
|
this.outputFormatter = outputFormatter;
|
|
30837
|
-
this.initializeControllers();
|
|
30838
31047
|
}
|
|
30839
31048
|
async initializeControllers() {
|
|
30840
31049
|
this.authController = new AuthController(this.configRepository);
|
|
@@ -30867,6 +31076,7 @@ class CommandController {
|
|
|
30867
31076
|
authController;
|
|
30868
31077
|
boardController;
|
|
30869
31078
|
cardController;
|
|
31079
|
+
checklistController;
|
|
30870
31080
|
program;
|
|
30871
31081
|
outputFormatter;
|
|
30872
31082
|
constructor() {
|
|
@@ -30909,6 +31119,7 @@ class CommandController {
|
|
|
30909
31119
|
const trelloRepository = new TrelloApiRepository(config.apiKey, config.token);
|
|
30910
31120
|
this.boardController = new BoardController(trelloRepository, this.outputFormatter);
|
|
30911
31121
|
this.cardController = new CardController(trelloRepository, this.boardController, this.outputFormatter);
|
|
31122
|
+
this.checklistController = new ChecklistController(trelloRepository, this.outputFormatter);
|
|
30912
31123
|
}
|
|
30913
31124
|
setupCommands() {
|
|
30914
31125
|
if (!this.program) {
|
|
@@ -31089,6 +31300,26 @@ class CommandController {
|
|
|
31089
31300
|
await this.cardController.deleteCard(cardId);
|
|
31090
31301
|
}, "delete-card-legacy");
|
|
31091
31302
|
});
|
|
31303
|
+
const checklistsCmd = this.program.command("checklists").description(t2("commands.checklists.description"));
|
|
31304
|
+
checklistsCmd.command("create <cardId>").description(t2("commands.checklists.create.description")).requiredOption("-n, --name <name>", t2("commands.checklists.create.nameOption")).option("-f, --format <format>", t2("commands.formatOption"), "table").action(async (cardId, options) => {
|
|
31305
|
+
await ErrorHandler.withErrorHandling(async () => {
|
|
31306
|
+
await this.initializeTrelloControllers();
|
|
31307
|
+
if (options.format) {
|
|
31308
|
+
this.outputFormatter.setFormat(options.format);
|
|
31309
|
+
}
|
|
31310
|
+
await this.checklistController.createChecklist(cardId, options.name);
|
|
31311
|
+
}, "checklists create");
|
|
31312
|
+
});
|
|
31313
|
+
const checklistItemCmd = checklistsCmd.command("item").description(t2("commands.checklists.item.description"));
|
|
31314
|
+
checklistItemCmd.command("add <checklistId>").description(t2("commands.checklists.item.add.description")).requiredOption("-n, --name <name>", t2("commands.checklists.item.add.nameOption")).option("-f, --format <format>", t2("commands.formatOption"), "table").action(async (checklistId, options) => {
|
|
31315
|
+
await ErrorHandler.withErrorHandling(async () => {
|
|
31316
|
+
await this.initializeTrelloControllers();
|
|
31317
|
+
if (options.format) {
|
|
31318
|
+
this.outputFormatter.setFormat(options.format);
|
|
31319
|
+
}
|
|
31320
|
+
await this.checklistController.addChecklistItem(checklistId, options.name);
|
|
31321
|
+
}, "checklists-item-add");
|
|
31322
|
+
});
|
|
31092
31323
|
}
|
|
31093
31324
|
async run() {
|
|
31094
31325
|
if (!this.program) {
|
|
@@ -31238,6 +31469,7 @@ var init_cli = __esm(() => {
|
|
|
31238
31469
|
init_AuthController();
|
|
31239
31470
|
init_BoardController();
|
|
31240
31471
|
init_CardController();
|
|
31472
|
+
init_ChecklistController();
|
|
31241
31473
|
init_CommandController();
|
|
31242
31474
|
init_ConfigController();
|
|
31243
31475
|
init_MainMenuController();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trello-cli-unofficial",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.14.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Unofficial Trello CLI using Power-Up authentication, built with Bun for maximum performance",
|
|
7
7
|
"author": "Matheus Caiser <matheus.kaiser@gmail.com> (https://www.mrdeveloper.com.br/)",
|
|
@@ -22,7 +22,12 @@
|
|
|
22
22
|
"bun",
|
|
23
23
|
"typescript",
|
|
24
24
|
"i18n",
|
|
25
|
-
"internationalization"
|
|
25
|
+
"internationalization",
|
|
26
|
+
"trello-cli",
|
|
27
|
+
"trello-command-line",
|
|
28
|
+
"trello-tool",
|
|
29
|
+
"trello-utility",
|
|
30
|
+
"trello-helper"
|
|
26
31
|
],
|
|
27
32
|
"module": "main.ts",
|
|
28
33
|
"bin": {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ChecklistItemEntity } from '@domain/entities';
|
|
2
|
+
import type { TrelloRepository } from '@domain/repositories';
|
|
3
|
+
import { t } from '@/i18n';
|
|
4
|
+
|
|
5
|
+
export class AddChecklistItemUseCase {
|
|
6
|
+
constructor(private trelloRepository: TrelloRepository) {}
|
|
7
|
+
|
|
8
|
+
async execute(checklistId: string, name: string): Promise<ChecklistItemEntity> {
|
|
9
|
+
if (!name.trim()) {
|
|
10
|
+
throw new Error(t('checklist.validation.requiredItemName'));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return await this.trelloRepository.addChecklistItem(checklistId, name);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ChecklistEntity } from '@domain/entities';
|
|
2
|
+
import type { TrelloRepository } from '@domain/repositories';
|
|
3
|
+
import { t } from '@/i18n';
|
|
4
|
+
|
|
5
|
+
export class CreateChecklistUseCase {
|
|
6
|
+
constructor(private trelloRepository: TrelloRepository) {}
|
|
7
|
+
|
|
8
|
+
async execute(cardId: string, name: string): Promise<ChecklistEntity> {
|
|
9
|
+
if (!name.trim()) {
|
|
10
|
+
throw new Error(t('checklist.validation.requiredName'));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return await this.trelloRepository.createChecklist(cardId, name);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
export * from './AddChecklistItemUseCase';
|
|
1
2
|
export * from './AuthenticateUserUseCase';
|
|
2
3
|
export * from './CreateBoardUseCase';
|
|
3
4
|
export * from './CreateCardUseCase';
|
|
5
|
+
export * from './CreateChecklistUseCase';
|
|
4
6
|
export * from './CreateListUseCase';
|
|
5
7
|
export * from './DeleteCardUseCase';
|
|
6
8
|
export * from './GetBoardDetailsUseCase';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export interface ChecklistItem {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
state: 'incomplete' | 'complete';
|
|
5
|
+
idChecklist: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface Checklist {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
idCard: string;
|
|
12
|
+
checkItems: ChecklistItem[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface TrelloChecklistItemResponse {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
state: string;
|
|
19
|
+
idChecklist: string;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface TrelloChecklistResponse {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
idCard: string;
|
|
27
|
+
checkItems: TrelloChecklistItemResponse[];
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class ChecklistItemEntity implements ChecklistItem {
|
|
32
|
+
constructor(
|
|
33
|
+
public readonly id: string,
|
|
34
|
+
public readonly name: string,
|
|
35
|
+
public readonly state: 'incomplete' | 'complete',
|
|
36
|
+
public readonly idChecklist: string,
|
|
37
|
+
) {}
|
|
38
|
+
|
|
39
|
+
static fromApiResponse(data: TrelloChecklistItemResponse): ChecklistItemEntity {
|
|
40
|
+
return new ChecklistItemEntity(
|
|
41
|
+
data.id,
|
|
42
|
+
data.name,
|
|
43
|
+
data.state === 'complete' ? 'complete' : 'incomplete',
|
|
44
|
+
data.idChecklist,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export class ChecklistEntity implements Checklist {
|
|
50
|
+
constructor(
|
|
51
|
+
public readonly id: string,
|
|
52
|
+
public readonly name: string,
|
|
53
|
+
public readonly idCard: string,
|
|
54
|
+
public readonly checkItems: ChecklistItemEntity[],
|
|
55
|
+
) {}
|
|
56
|
+
|
|
57
|
+
static fromApiResponse(data: TrelloChecklistResponse): ChecklistEntity {
|
|
58
|
+
return new ChecklistEntity(
|
|
59
|
+
data.id,
|
|
60
|
+
data.name,
|
|
61
|
+
data.idCard,
|
|
62
|
+
(data.checkItems || []).map(item => ChecklistItemEntity.fromApiResponse(item)),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BoardEntity,
|
|
3
3
|
CardEntity,
|
|
4
|
+
ChecklistEntity,
|
|
5
|
+
ChecklistItemEntity,
|
|
4
6
|
CreateCardData,
|
|
5
7
|
ListEntity,
|
|
6
8
|
UpdateCardData,
|
|
@@ -34,4 +36,6 @@ export interface TrelloRepository {
|
|
|
34
36
|
updateCard: (cardId: string, data: UpdateCardData) => Promise<CardEntity>;
|
|
35
37
|
deleteCard: (cardId: string) => Promise<void>;
|
|
36
38
|
moveCard: (cardId: string, targetListId: string) => Promise<CardEntity>;
|
|
39
|
+
createChecklist: (cardId: string, name: string) => Promise<ChecklistEntity>;
|
|
40
|
+
addChecklistItem: (checklistId: string, name: string) => Promise<ChecklistItemEntity>;
|
|
37
41
|
}
|
package/src/i18n/locales/en.json
CHANGED
|
@@ -137,7 +137,23 @@
|
|
|
137
137
|
"checklists": "β
Checklists:",
|
|
138
138
|
"attachments": "π Attachments:",
|
|
139
139
|
"location": "π Board:",
|
|
140
|
-
"list": "π List:"
|
|
140
|
+
"list": "π List:",
|
|
141
|
+
"checklistTitle": "π {{name}}",
|
|
142
|
+
"checklistProgress": " [{{done}}/{{total}}]",
|
|
143
|
+
"checklistItemDone": " β {{name}}",
|
|
144
|
+
"checklistItemPending": " β {{name}}"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"checklist": {
|
|
148
|
+
"created": "β
Checklist \"{{name}}\" created successfully!",
|
|
149
|
+
"checklistId": "π ID: {{id}}",
|
|
150
|
+
"checklistCard": "π Card ID: {{idCard}}",
|
|
151
|
+
"itemAdded": "β
Item \"{{name}}\" added to checklist successfully!",
|
|
152
|
+
"itemId": "π ID: {{id}}",
|
|
153
|
+
"itemState": "π State: {{state}}",
|
|
154
|
+
"validation": {
|
|
155
|
+
"requiredName": "Checklist name is required",
|
|
156
|
+
"requiredItemName": "Item name is required"
|
|
141
157
|
}
|
|
142
158
|
},
|
|
143
159
|
"errors": {
|
|
@@ -286,6 +302,20 @@
|
|
|
286
302
|
"delete": {
|
|
287
303
|
"description": "Delete a card"
|
|
288
304
|
}
|
|
305
|
+
},
|
|
306
|
+
"checklists": {
|
|
307
|
+
"description": "Manage checklists on Trello cards",
|
|
308
|
+
"create": {
|
|
309
|
+
"description": "Create a checklist on a card",
|
|
310
|
+
"nameOption": "Checklist name"
|
|
311
|
+
},
|
|
312
|
+
"item": {
|
|
313
|
+
"description": "Manage checklist items",
|
|
314
|
+
"add": {
|
|
315
|
+
"description": "Add an item to a checklist",
|
|
316
|
+
"nameOption": "Item name"
|
|
317
|
+
}
|
|
318
|
+
}
|
|
289
319
|
}
|
|
290
320
|
}
|
|
291
321
|
}
|
|
@@ -137,7 +137,23 @@
|
|
|
137
137
|
"checklists": "β
Checklists:",
|
|
138
138
|
"attachments": "π Anexos:",
|
|
139
139
|
"location": "π Board:",
|
|
140
|
-
"list": "π List:"
|
|
140
|
+
"list": "π List:",
|
|
141
|
+
"checklistTitle": "π {{name}}",
|
|
142
|
+
"checklistProgress": " [{{done}}/{{total}}]",
|
|
143
|
+
"checklistItemDone": " β {{name}}",
|
|
144
|
+
"checklistItemPending": " β {{name}}"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"checklist": {
|
|
148
|
+
"created": "β
Checklist \"{{name}}\" criado com sucesso!",
|
|
149
|
+
"checklistId": "π ID: {{id}}",
|
|
150
|
+
"checklistCard": "π ID do Card: {{idCard}}",
|
|
151
|
+
"itemAdded": "β
Item \"{{name}}\" adicionado ao checklist com sucesso!",
|
|
152
|
+
"itemId": "π ID: {{id}}",
|
|
153
|
+
"itemState": "π Estado: {{state}}",
|
|
154
|
+
"validation": {
|
|
155
|
+
"requiredName": "Nome do checklist Γ© obrigatΓ³rio",
|
|
156
|
+
"requiredItemName": "Nome do item Γ© obrigatΓ³rio"
|
|
141
157
|
}
|
|
142
158
|
},
|
|
143
159
|
"errors": {
|
|
@@ -286,6 +302,20 @@
|
|
|
286
302
|
"delete": {
|
|
287
303
|
"description": "Deleta um card"
|
|
288
304
|
}
|
|
305
|
+
},
|
|
306
|
+
"checklists": {
|
|
307
|
+
"description": "Gerencia checklists nos cards do Trello",
|
|
308
|
+
"create": {
|
|
309
|
+
"description": "Cria um checklist em um card",
|
|
310
|
+
"nameOption": "Nome do checklist"
|
|
311
|
+
},
|
|
312
|
+
"item": {
|
|
313
|
+
"description": "Gerencia itens de checklist",
|
|
314
|
+
"add": {
|
|
315
|
+
"description": "Adiciona um item a um checklist",
|
|
316
|
+
"nameOption": "Nome do item"
|
|
317
|
+
}
|
|
318
|
+
}
|
|
289
319
|
}
|
|
290
320
|
}
|
|
291
321
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CreateCardData, UpdateCardData } from '@domain/entities';
|
|
2
2
|
import type { TrelloRepository } from '@domain/repositories';
|
|
3
|
-
import { BoardEntity, CardEntity, ListEntity } from '@domain/entities';
|
|
3
|
+
import { BoardEntity, CardEntity, ChecklistEntity, ChecklistItemEntity, ListEntity } from '@domain/entities';
|
|
4
4
|
import { t } from '@/i18n';
|
|
5
5
|
|
|
6
6
|
// API Response types
|
|
@@ -43,6 +43,22 @@ interface TrelloLabelResponse {
|
|
|
43
43
|
[key: string]: unknown;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
interface TrelloChecklistItemResponse {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
state: string;
|
|
50
|
+
idChecklist: string;
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface TrelloChecklistResponse {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
idCard: string;
|
|
58
|
+
checkItems: TrelloChecklistItemResponse[];
|
|
59
|
+
[key: string]: unknown;
|
|
60
|
+
}
|
|
61
|
+
|
|
46
62
|
export class TrelloApiRepository implements TrelloRepository {
|
|
47
63
|
private readonly baseUrl = 'https://api.trello.com/1';
|
|
48
64
|
|
|
@@ -278,4 +294,40 @@ export class TrelloApiRepository implements TrelloRepository {
|
|
|
278
294
|
const data = await this.request(endpoint);
|
|
279
295
|
return CardEntity.fromApiResponse(data as TrelloCardResponse);
|
|
280
296
|
}
|
|
297
|
+
|
|
298
|
+
async createChecklist(cardId: string, name: string): Promise<ChecklistEntity> {
|
|
299
|
+
const body = new URLSearchParams({
|
|
300
|
+
name,
|
|
301
|
+
key: this.apiKey,
|
|
302
|
+
token: this.token,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const data = await this.request(`/cards/${cardId}/checklists`, {
|
|
306
|
+
method: 'POST',
|
|
307
|
+
headers: {
|
|
308
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
309
|
+
},
|
|
310
|
+
body: body.toString(),
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
return ChecklistEntity.fromApiResponse(data as TrelloChecklistResponse);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
async addChecklistItem(checklistId: string, name: string): Promise<ChecklistItemEntity> {
|
|
317
|
+
const body = new URLSearchParams({
|
|
318
|
+
name,
|
|
319
|
+
key: this.apiKey,
|
|
320
|
+
token: this.token,
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
const data = await this.request(`/checklists/${checklistId}/checkItems`, {
|
|
324
|
+
method: 'POST',
|
|
325
|
+
headers: {
|
|
326
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
327
|
+
},
|
|
328
|
+
body: body.toString(),
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
return ChecklistItemEntity.fromApiResponse(data as TrelloChecklistItemResponse);
|
|
332
|
+
}
|
|
281
333
|
}
|