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.
@@ -460,15 +460,31 @@ export class CardController {
460
460
  this.outputFormatter.message(`${t('card.show.members')} ${displayMembers}`);
461
461
  }
462
462
 
463
- // Show checklists in compact format
463
+ // Show checklists with detailed view
464
464
  if (card.checklists && card.checklists.length > 0) {
465
- const checklistSummary = card.checklists.map((cl) => {
465
+ this.outputFormatter.message('');
466
+ this.outputFormatter.message(t('card.show.checklists'));
467
+ for (const cl of card.checklists) {
466
468
  const checkItems = Array.isArray(cl.checkItems) ? cl.checkItems : [];
467
- const completed = checkItems.filter((item: { state: string }) => item.state === 'complete').length;
469
+ const done = checkItems.filter((item: { state: string }) => item.state === 'complete').length;
468
470
  const total = checkItems.length;
469
- return `${cl.name} (${completed}/${total})`;
470
- }).join(', ');
471
- this.outputFormatter.message(`${t('card.show.checklists')} ${checklistSummary}`);
471
+ const filledCount = total > 0 ? Math.round((done / total) * 10) : 0;
472
+ const bar = '█'.repeat(filledCount) + '░'.repeat(10 - filledCount);
473
+ const pct = total > 0 ? Math.round((done / total) * 100) : 0;
474
+ const title = t('card.show.checklistTitle', { name: String(cl.name) });
475
+ const progress = t('card.show.checklistProgress', { done, total });
476
+ this.outputFormatter.message(` ${title}${progress} ${bar} ${pct}%`);
477
+ for (const item of checkItems) {
478
+ const checkItem = item as { name: string; state: string };
479
+ if (checkItem.state === 'complete') {
480
+ this.outputFormatter.message(t('card.show.checklistItemDone', { name: checkItem.name }));
481
+ }
482
+ else {
483
+ this.outputFormatter.message(t('card.show.checklistItemPending', { name: checkItem.name }));
484
+ }
485
+ }
486
+ this.outputFormatter.message('');
487
+ }
472
488
  }
473
489
 
474
490
  // Show attachments count if present
@@ -0,0 +1,48 @@
1
+ import type { TrelloRepository } from '@domain/repositories';
2
+ import type { OutputFormatter } from '@/shared';
3
+
4
+ import {
5
+ AddChecklistItemUseCase,
6
+ CreateChecklistUseCase,
7
+ } from '@application/use-cases';
8
+
9
+ import { t } from '@/i18n';
10
+
11
+ export class ChecklistController {
12
+ private createChecklistUseCase: CreateChecklistUseCase;
13
+ private addChecklistItemUseCase: AddChecklistItemUseCase;
14
+
15
+ constructor(
16
+ trelloRepository: TrelloRepository,
17
+ private outputFormatter: OutputFormatter,
18
+ ) {
19
+ this.createChecklistUseCase = new CreateChecklistUseCase(trelloRepository);
20
+ this.addChecklistItemUseCase = new AddChecklistItemUseCase(trelloRepository);
21
+ }
22
+
23
+ async createChecklist(cardId: string, name: string): Promise<void> {
24
+ const checklist = await this.createChecklistUseCase.execute(cardId, name);
25
+
26
+ console.log(t('checklist.created', { name: checklist.name }));
27
+ console.log(t('checklist.checklistId', { id: checklist.id }));
28
+ console.log(t('checklist.checklistCard', { idCard: checklist.idCard }));
29
+
30
+ this.outputFormatter.output([checklist], {
31
+ headers: ['ID', 'Name', 'Card ID', 'Items'],
32
+ fields: ['id', 'name', 'idCard', 'checkItems'],
33
+ });
34
+ }
35
+
36
+ async addChecklistItem(checklistId: string, name: string): Promise<void> {
37
+ const item = await this.addChecklistItemUseCase.execute(checklistId, name);
38
+
39
+ console.log(t('checklist.itemAdded', { name: item.name }));
40
+ console.log(t('checklist.itemId', { id: item.id }));
41
+ console.log(t('checklist.itemState', { state: item.state }));
42
+
43
+ this.outputFormatter.output([item], {
44
+ headers: ['ID', 'Name', 'State', 'Checklist ID'],
45
+ fields: ['id', 'name', 'state', 'idChecklist'],
46
+ });
47
+ }
48
+ }
@@ -12,12 +12,13 @@ import { Command } from 'commander';
12
12
 
13
13
  import { t } from '@/i18n';
14
14
  import { ErrorHandler, OutputFormatter } from '@/shared';
15
- import { AuthController, BoardController, CardController } from './index';
15
+ import { AuthController, BoardController, CardController, ChecklistController } from './index';
16
16
 
17
17
  export class CommandController {
18
18
  private authController: AuthController;
19
19
  private boardController!: BoardController;
20
20
  private cardController!: CardController;
21
+ private checklistController!: ChecklistController;
21
22
  private program: Command;
22
23
  private outputFormatter: OutputFormatter;
23
24
 
@@ -95,6 +96,10 @@ export class CommandController {
95
96
  this.boardController,
96
97
  this.outputFormatter,
97
98
  );
99
+ this.checklistController = new ChecklistController(
100
+ trelloRepository,
101
+ this.outputFormatter,
102
+ );
98
103
  }
99
104
 
100
105
  private setupCommands(): void {
@@ -451,6 +456,45 @@ export class CommandController {
451
456
  await this.cardController.deleteCard(cardId);
452
457
  }, 'delete-card-legacy');
453
458
  });
459
+
460
+ // Checklists subcommands
461
+ const checklistsCmd = this.program
462
+ .command('checklists')
463
+ .description(t('commands.checklists.description'));
464
+
465
+ checklistsCmd
466
+ .command('create <cardId>')
467
+ .description(t('commands.checklists.create.description'))
468
+ .requiredOption('-n, --name <name>', t('commands.checklists.create.nameOption'))
469
+ .option('-f, --format <format>', t('commands.formatOption'), 'table')
470
+ .action(async (cardId: string, options: { name: string; format?: string }) => {
471
+ await ErrorHandler.withErrorHandling(async () => {
472
+ await this.initializeTrelloControllers();
473
+ if (options.format) {
474
+ this.outputFormatter.setFormat(options.format as import('@/shared').OutputFormat);
475
+ }
476
+ await this.checklistController.createChecklist(cardId, options.name);
477
+ }, 'checklists create');
478
+ });
479
+
480
+ const checklistItemCmd = checklistsCmd
481
+ .command('item')
482
+ .description(t('commands.checklists.item.description'));
483
+
484
+ checklistItemCmd
485
+ .command('add <checklistId>')
486
+ .description(t('commands.checklists.item.add.description'))
487
+ .requiredOption('-n, --name <name>', t('commands.checklists.item.add.nameOption'))
488
+ .option('-f, --format <format>', t('commands.formatOption'), 'table')
489
+ .action(async (checklistId: string, options: { name: string; format?: string }) => {
490
+ await ErrorHandler.withErrorHandling(async () => {
491
+ await this.initializeTrelloControllers();
492
+ if (options.format) {
493
+ this.outputFormatter.setFormat(options.format as import('@/shared').OutputFormat);
494
+ }
495
+ await this.checklistController.addChecklistItem(checklistId, options.name);
496
+ }, 'checklists-item-add');
497
+ });
454
498
  }
455
499
 
456
500
  async run(): Promise<void> {
@@ -20,9 +20,7 @@ export class TrelloCliController {
20
20
  constructor(
21
21
  private configRepository: ConfigRepository,
22
22
  private outputFormatter: OutputFormatter,
23
- ) {
24
- this.initializeControllers();
25
- }
23
+ ) {}
26
24
 
27
25
  private async initializeControllers(): Promise<void> {
28
26
  this.authController = new AuthController(this.configRepository);
@@ -1,6 +1,7 @@
1
1
  export * from './AuthController';
2
2
  export * from './BoardController';
3
3
  export * from './CardController';
4
+ export * from './ChecklistController';
4
5
  export * from './CommandController';
5
6
  export * from './ConfigController';
6
7
  export * from './MainMenuController';