@autocode-cli/autocode 0.2.1 → 0.3.1

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.
Files changed (47) hide show
  1. package/dist/server/dashboard/pages/autocreate.js +3 -3
  2. package/dist/server/dashboard/pages/changelog.d.ts.map +1 -1
  3. package/dist/server/dashboard/pages/changelog.js +20 -11
  4. package/dist/server/dashboard/pages/changelog.js.map +1 -1
  5. package/dist/server/dashboard/pages/column-edit.js +2 -2
  6. package/dist/server/dashboard/pages/column-prompt.d.ts.map +1 -1
  7. package/dist/server/dashboard/pages/column-prompt.js +21 -0
  8. package/dist/server/dashboard/pages/column-prompt.js.map +1 -1
  9. package/dist/server/dashboard/pages/column-terminal.d.ts.map +1 -1
  10. package/dist/server/dashboard/pages/column-terminal.js +21 -0
  11. package/dist/server/dashboard/pages/column-terminal.js.map +1 -1
  12. package/dist/server/dashboard/pages/issue-graph.d.ts.map +1 -1
  13. package/dist/server/dashboard/pages/issue-graph.js +70 -22
  14. package/dist/server/dashboard/pages/issue-graph.js.map +1 -1
  15. package/dist/server/dashboard/pages/issue-shared.d.ts.map +1 -1
  16. package/dist/server/dashboard/pages/issue-shared.js +54 -122
  17. package/dist/server/dashboard/pages/issue-shared.js.map +1 -1
  18. package/dist/server/dashboard/pages/issue-view.js +1 -1
  19. package/dist/server/dashboard/pages/new-issue.d.ts.map +1 -1
  20. package/dist/server/dashboard/pages/new-issue.js +34 -128
  21. package/dist/server/dashboard/pages/new-issue.js.map +1 -1
  22. package/dist/server/dashboard/pages/pipeline-configurator.d.ts.map +1 -1
  23. package/dist/server/dashboard/pages/pipeline-configurator.js +39 -183
  24. package/dist/server/dashboard/pages/pipeline-configurator.js.map +1 -1
  25. package/dist/server/dashboard/pages/stats-page.d.ts.map +1 -1
  26. package/dist/server/dashboard/pages/stats-page.js +43 -109
  27. package/dist/server/dashboard/pages/stats-page.js.map +1 -1
  28. package/dist/server/dashboard/scripts/index.d.ts.map +1 -1
  29. package/dist/server/dashboard/scripts/index.js +48 -253
  30. package/dist/server/dashboard/scripts/index.js.map +1 -1
  31. package/dist/server/dashboard/shared/header.d.ts +88 -0
  32. package/dist/server/dashboard/shared/header.d.ts.map +1 -0
  33. package/dist/server/dashboard/shared/header.js +209 -0
  34. package/dist/server/dashboard/shared/header.js.map +1 -0
  35. package/dist/server/dashboard/shared/i18n-script.d.ts +45 -0
  36. package/dist/server/dashboard/shared/i18n-script.d.ts.map +1 -0
  37. package/dist/server/dashboard/shared/i18n-script.js +204 -0
  38. package/dist/server/dashboard/shared/i18n-script.js.map +1 -0
  39. package/dist/server/dashboard/shared/index.d.ts +19 -0
  40. package/dist/server/dashboard/shared/index.d.ts.map +1 -0
  41. package/dist/server/dashboard/shared/index.js +22 -0
  42. package/dist/server/dashboard/shared/index.js.map +1 -0
  43. package/dist/server/dashboard/shared/translations.d.ts +515 -0
  44. package/dist/server/dashboard/shared/translations.d.ts.map +1 -0
  45. package/dist/server/dashboard/shared/translations.js +591 -0
  46. package/dist/server/dashboard/shared/translations.js.map +1 -0
  47. package/package.json +1 -1
@@ -2,6 +2,7 @@
2
2
  * Stats page - Claude usage statistics dashboard
3
3
  */
4
4
  import { getStyles } from '../styles/index.js';
5
+ import { generateI18nScript, generateLangSwitcher } from '../shared/index.js';
5
6
  /**
6
7
  * Generate the stats page HTML
7
8
  */
@@ -306,19 +307,16 @@ export function generateStatsPage() {
306
307
  <body>
307
308
  <div class="stats-page">
308
309
  <div class="stats-header">
309
- <h1><span data-i18n="title"></span> <span id="refresh-indicator" class="refresh-indicator"></span></h1>
310
+ <h1><span data-i18n="stats.pageTitle"></span> <span id="refresh-indicator" class="refresh-indicator"></span></h1>
310
311
  <div class="header-actions">
311
- <div class="lang-switcher">
312
- <button class="lang-btn" data-lang="fr">FR</button>
313
- <button class="lang-btn" data-lang="en">EN</button>
314
- </div>
315
- <a href="/" class="btn-back" data-i18n="back"></a>
312
+ ${generateLangSwitcher()}
313
+ <a href="/" class="btn-back" data-i18n="btn.backToDashboard"></a>
316
314
  </div>
317
315
  </div>
318
316
 
319
317
  <div class="stats-cards">
320
318
  <div class="stats-card">
321
- <h3 data-i18n="profile"></h3>
319
+ <h3 data-i18n="stats.profile"></h3>
322
320
  <div class="profile-badge" id="profile">-</div>
323
321
  <div style="margin-top: 15px">
324
322
  <span class="model-badge" id="model">-</span>
@@ -326,52 +324,52 @@ export function generateStatsPage() {
326
324
  </div>
327
325
 
328
326
  <div class="stats-card">
329
- <h3 data-i18n="session"></h3>
327
+ <h3 data-i18n="stats.session"></h3>
330
328
  <div class="stats-grid">
331
329
  <div class="stats-item">
332
330
  <span class="value" id="session-tokens">-</span>
333
- <span class="label" data-i18n="totalTokens"></span>
331
+ <span class="label" data-i18n="stats.totalTokens"></span>
334
332
  </div>
335
333
  <div class="stats-item">
336
334
  <span class="value" id="session-calls">-</span>
337
- <span class="label" data-i18n="calls"></span>
335
+ <span class="label" data-i18n="stats.calls"></span>
338
336
  </div>
339
337
  <div class="stats-item">
340
338
  <span class="value" id="session-cost" style="color: #22c55e;">-</span>
341
- <span class="label" data-i18n="cost"></span>
339
+ <span class="label" data-i18n="stats.cost"></span>
342
340
  </div>
343
341
  </div>
344
342
  <div class="label" id="session-started" style="margin-top: 10px;"></div>
345
343
  </div>
346
344
 
347
345
  <div class="stats-card">
348
- <h3 data-i18n="totals"></h3>
346
+ <h3 data-i18n="stats.totals"></h3>
349
347
  <div class="stats-grid">
350
348
  <div class="stats-item">
351
349
  <span class="value" id="total-tokens">-</span>
352
- <span class="label" data-i18n="totalTokens"></span>
350
+ <span class="label" data-i18n="stats.totalTokens"></span>
353
351
  </div>
354
352
  <div class="stats-item">
355
353
  <span class="value" id="total-calls">-</span>
356
- <span class="label" data-i18n="calls"></span>
354
+ <span class="label" data-i18n="stats.calls"></span>
357
355
  </div>
358
356
  <div class="stats-item">
359
357
  <span class="value" id="total-cost" style="color: #22c55e;">-</span>
360
- <span class="label" data-i18n="cost"></span>
358
+ <span class="label" data-i18n="stats.cost"></span>
361
359
  </div>
362
360
  </div>
363
361
  </div>
364
362
 
365
363
  <div class="stats-card" id="processing-card" style="display: none;">
366
- <h3 data-i18n="processing"></h3>
364
+ <h3 data-i18n="status.processing"></h3>
367
365
  <div id="processing-issues"></div>
368
366
  </div>
369
367
  </div>
370
368
 
371
369
  <div class="stats-card">
372
- <h3 data-i18n="history"></h3>
370
+ <h3 data-i18n="stats.history"></h3>
373
371
  <div id="history-container">
374
- <div class="empty-state" data-i18n="loading"></div>
372
+ <div class="empty-state" data-i18n="status.loading"></div>
375
373
  </div>
376
374
  <div class="info-box">
377
375
  <span class="icon">i</span>
@@ -381,88 +379,27 @@ export function generateStatsPage() {
381
379
  </div>
382
380
 
383
381
  <script>
384
- // ========================================
385
- // TRANSLATIONS
386
- // ========================================
387
- const translations = {
388
- fr: {
389
- title: 'Statistiques Claude',
390
- profile: 'Profil',
391
- model: 'Modèle',
392
- session: 'Session actuelle',
393
- totals: 'Totaux',
394
- tokensInput: 'Tokens entrée',
395
- tokensOutput: 'Tokens sortie',
396
- totalTokens: 'Total tokens',
397
- calls: 'Appels',
398
- cost: 'Coût',
399
- history: 'Historique des appels',
400
- noHistory: 'Aucun appel enregistré',
401
- back: 'Retour au dashboard',
402
- startedAt: 'Démarré le',
403
- issue: 'Ticket',
404
- column: 'Colonne',
405
- duration: 'Durée',
406
- date: 'Date',
407
- loading: 'Chargement...',
408
- processing: 'En cours',
409
- costExplanation: '<strong>Pourquoi le coût semble bas ?</strong> Claude utilise un <strong>cache de prompts</strong> qui réduit significativement les coûts. Quand une partie du contexte a déjà été envoyée dans une conversation précédente, Claude ne la refacture pas au prix plein. Le coût affiché est le <strong>coût réel facturé</strong> par l\\'API Claude, qui inclut ces réductions de cache. C\\'est pour cela que <code>tokens × prix</code> ne correspond pas toujours au coût affiché - et c\\'est une bonne nouvelle pour votre portefeuille !',
410
- },
411
- en: {
412
- title: 'Claude Statistics',
413
- profile: 'Profile',
414
- model: 'Model',
415
- session: 'Current session',
416
- totals: 'Totals',
417
- tokensInput: 'Input tokens',
418
- tokensOutput: 'Output tokens',
419
- totalTokens: 'Total tokens',
420
- calls: 'Calls',
421
- cost: 'Cost',
422
- history: 'Call history',
423
- noHistory: 'No calls recorded',
424
- back: 'Back to dashboard',
425
- startedAt: 'Started at',
426
- issue: 'Issue',
427
- column: 'Column',
428
- duration: 'Duration',
429
- date: 'Date',
430
- loading: 'Loading...',
431
- processing: 'Processing',
432
- costExplanation: '<strong>Why does the cost seem low?</strong> Claude uses <strong>prompt caching</strong> which significantly reduces costs. When part of the context was already sent in a previous conversation, Claude doesn\\'t charge full price again. The cost shown is the <strong>actual cost billed</strong> by the Claude API, including these cache discounts. That\\'s why <code>tokens × price</code> doesn\\'t always match the displayed cost - and that\\'s good news for your wallet!',
433
- }
434
- };
382
+ ${generateI18nScript({
383
+ keys: [
384
+ 'stats.pageTitle', 'stats.profile', 'stats.session', 'stats.totals',
385
+ 'stats.tokensInput', 'stats.tokensOutput', 'stats.totalTokens',
386
+ 'stats.calls', 'stats.cost', 'stats.history', 'stats.noHistory',
387
+ 'stats.startedAt', 'stats.issue', 'stats.column', 'stats.duration',
388
+ 'stats.date', 'stats.costExplanation', 'status.processing',
389
+ 'status.loading', 'btn.backToDashboard',
390
+ ],
391
+ onLangChangeCallback: 'onLangChange',
392
+ })}
435
393
 
436
- let currentLang = localStorage.getItem('autocode-lang') || 'fr';
437
394
  let statsData = null;
438
395
 
439
- function t(key) {
440
- return translations[currentLang][key] || translations['en'][key] || key;
441
- }
442
-
443
- function switchLanguage(lang) {
444
- currentLang = lang;
445
- localStorage.setItem('autocode-lang', lang);
446
- document.documentElement.lang = lang;
447
-
448
- // Update lang switcher buttons
449
- document.querySelectorAll('.lang-switcher .lang-btn').forEach(btn => {
450
- btn.classList.toggle('active', btn.dataset.lang === lang);
451
- });
452
-
453
- // Update all elements with data-i18n
454
- document.querySelectorAll('[data-i18n]').forEach(el => {
455
- const key = el.getAttribute('data-i18n');
456
- if (translations[lang] && translations[lang][key]) {
457
- el.textContent = translations[lang][key];
458
- }
459
- });
460
-
396
+ // Callback called after language switch
397
+ function onLangChange() {
461
398
  // Update cost explanation (HTML content)
462
- document.getElementById('cost-explanation').innerHTML = t('costExplanation');
399
+ document.getElementById('cost-explanation').innerHTML = t('stats.costExplanation');
463
400
 
464
401
  // Update page title
465
- document.title = t('title') + ' - AutoCode';
402
+ document.title = t('stats.pageTitle') + ' - AutoCode';
466
403
 
467
404
  // Re-render history table if data exists
468
405
  if (statsData) {
@@ -471,6 +408,9 @@ export function generateStatsPage() {
471
408
  }
472
409
  }
473
410
 
411
+ // Initial cost explanation
412
+ document.getElementById('cost-explanation').innerHTML = t('stats.costExplanation');
413
+
474
414
  // ========================================
475
415
  // FORMATTING
476
416
  // ========================================
@@ -495,7 +435,7 @@ export function generateStatsPage() {
495
435
  // ========================================
496
436
  function renderSessionStarted(data) {
497
437
  if (data.session.startedAt) {
498
- document.getElementById('session-started').textContent = t('startedAt') + ': ' + formatDate(data.session.startedAt);
438
+ document.getElementById('session-started').textContent = t('stats.startedAt') + ': ' + formatDate(data.session.startedAt);
499
439
  }
500
440
  }
501
441
 
@@ -514,13 +454,13 @@ export function generateStatsPage() {
514
454
  </colgroup>
515
455
  <thead>
516
456
  <tr>
517
- <th>\${t('issue')}</th>
518
- <th>\${t('column')}</th>
519
- <th>\${t('tokensInput')}</th>
520
- <th>\${t('tokensOutput')}</th>
521
- <th>\${t('cost')}</th>
522
- <th>\${t('duration')}</th>
523
- <th>\${t('date')}</th>
457
+ <th>\${t('stats.issue')}</th>
458
+ <th>\${t('stats.column')}</th>
459
+ <th>\${t('stats.tokensInput')}</th>
460
+ <th>\${t('stats.tokensOutput')}</th>
461
+ <th>\${t('stats.cost')}</th>
462
+ <th>\${t('stats.duration')}</th>
463
+ <th>\${t('stats.date')}</th>
524
464
  </tr>
525
465
  </thead>
526
466
  <tbody>
@@ -539,7 +479,7 @@ export function generateStatsPage() {
539
479
  </table>
540
480
  \`;
541
481
  } else {
542
- document.getElementById('history-container').innerHTML = '<div class="empty-state">' + t('noHistory') + '</div>';
482
+ document.getElementById('history-container').innerHTML = '<div class="empty-state">' + t('stats.noHistory') + '</div>';
543
483
  }
544
484
  }
545
485
 
@@ -597,12 +537,6 @@ export function generateStatsPage() {
597
537
  // ========================================
598
538
  // INIT
599
539
  // ========================================
600
- // Initialize language switcher
601
- document.querySelectorAll('.lang-switcher .lang-btn').forEach(btn => {
602
- btn.addEventListener('click', () => switchLanguage(btn.dataset.lang));
603
- });
604
- switchLanguage(currentLang);
605
-
606
540
  // Initial load
607
541
  loadStats();
608
542
 
@@ -1 +1 @@
1
- {"version":3,"file":"stats-page.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/stats-page.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO;;;;;;;MAOH,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA8lBT,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"stats-page.js","sourceRoot":"","sources":["../../../../src/server/dashboard/pages/stats-page.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAuB,MAAM,oBAAoB,CAAC;AAEnG;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO;;;;;;;MAOH,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAuSP,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAsE1B,kBAAkB,CAAC;QACnB,IAAI,EAAE;YACJ,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc;YACnE,mBAAmB,EAAE,oBAAoB,EAAE,mBAAmB;YAC9D,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB;YAC/D,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB;YAClE,YAAY,EAAE,uBAAuB,EAAE,mBAAmB;YAC1D,gBAAgB,EAAE,qBAAqB;SACxC;QACD,oBAAoB,EAAE,cAAc;KACrC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAoKE,CAAC;AACT,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/dashboard/scripts/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAg8ClC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/dashboard/scripts/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4CH;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,CA2sClC"}
@@ -4,255 +4,59 @@
4
4
  * This file contains all interactive functionality for the dashboard.
5
5
  * The code is kept in a single function to maintain shared state and scope.
6
6
  */
7
+ import { generateI18nScript } from '../shared/index.js';
8
+ // Dashboard translation keys
9
+ const dashboardKeys = [
10
+ // Filter
11
+ 'filter.allPriorities', 'filter.search',
12
+ // Buttons
13
+ 'btn.newIssue', 'btn.createIssue', 'btn.update', 'btn.cancel', 'btn.archive',
14
+ 'btn.next', 'btn.add', 'btn.edit', 'btn.save', 'btn.reload',
15
+ 'btn.updating', 'btn.creating', 'btn.moving', 'btn.archiving', 'btn.sending', 'btn.saving',
16
+ // Modal
17
+ 'modal.newIssue', 'modal.editIssue', 'modal.title', 'modal.titlePlaceholder',
18
+ 'modal.description', 'modal.descriptionPlaceholder', 'modal.priority', 'modal.releaseType',
19
+ 'modal.labels', 'modal.selectLabel', 'modal.acceptanceCriteria', 'modal.addCriteria',
20
+ 'modal.attachments', 'modal.addAttachment', 'modal.noAttachments',
21
+ 'modal.comments', 'modal.noComments', 'modal.addCommentPlaceholder', 'modal.claudeTerminal',
22
+ // Priority
23
+ 'priority.p0', 'priority.p1', 'priority.p2', 'priority.p3',
24
+ // Semver
25
+ 'semver.patch', 'semver.minor', 'semver.major', 'semver.none',
26
+ // Status
27
+ 'status.waiting', 'status.processing', 'status.completed', 'status.failed', 'status.connected',
28
+ // Stats
29
+ 'stats.total', 'stats.tokens', 'stats.viewStats',
30
+ // Board
31
+ 'board.empty',
32
+ // Action modal
33
+ 'action.instructions', 'action.noInstructions', 'action.noFile', 'action.modifiedOn',
34
+ // Notifications
35
+ 'notify.titleRequired', 'notify.titleMandatory', 'notify.issueUpdated', 'notify.issueCreated',
36
+ 'notify.issueAdvanced', 'notify.issueArchived', 'notify.issueMoved', 'notify.moveTo',
37
+ 'notify.commentAdded', 'notify.actionUpdated', 'notify.error', 'notify.unableToSave',
38
+ 'notify.loadingError', 'notify.claudeStarted', 'notify.claudeFinished', 'notify.claudeFailed',
39
+ 'notify.processingSuccess', 'notify.checkLogs',
40
+ // Confirm
41
+ 'confirm.archive',
42
+ // Changelog
43
+ 'changelog.title', 'changelog.gotIt', 'changelog.viewAll', 'changelog.moreVersions',
44
+ // Footer
45
+ 'footer.changelog',
46
+ ];
7
47
  /**
8
48
  * Get all JavaScript for dashboard interactivity
9
49
  */
10
50
  export function getScript() {
11
51
  return `
12
- // ========================================
13
- // i18n TRANSLATIONS
14
- // ========================================
15
- const translations = {
16
- en: {
17
- // Filter
18
- 'filter.allPriorities': 'All priorities',
19
- 'filter.search': 'Search...',
20
- // Buttons
21
- 'btn.newIssue': '+ New issue',
22
- 'btn.createIssue': 'Create issue',
23
- 'btn.update': 'Update',
24
- 'btn.cancel': 'Cancel',
25
- 'btn.archive': 'Archive',
26
- 'btn.next': 'Next',
27
- 'btn.add': 'Add',
28
- 'btn.edit': 'Edit',
29
- 'btn.save': 'Save',
30
- 'btn.reload': 'Reload',
31
- // Modal
32
- 'modal.newIssue': 'New issue',
33
- 'modal.editIssue': 'Edit',
34
- 'modal.title': 'Title *',
35
- 'modal.titlePlaceholder': 'E.g.: Fix the login bug',
36
- 'modal.description': 'Description',
37
- 'modal.descriptionPlaceholder': 'Describe the context and details...',
38
- 'modal.priority': 'Priority',
39
- 'modal.releaseType': 'Release type',
40
- 'modal.labels': 'Labels',
41
- 'modal.selectLabel': 'Select a label...',
42
- 'modal.acceptanceCriteria': 'Acceptance criteria',
43
- 'modal.addCriteria': 'Add criteria',
44
- 'modal.attachments': 'Attachments',
45
- 'modal.addAttachment': 'Add file',
46
- 'modal.noAttachments': 'No attachments',
47
- 'modal.comments': 'Comments',
48
- 'modal.noComments': 'No comments',
49
- 'modal.addCommentPlaceholder': 'Add a comment...',
50
- 'modal.claudeTerminal': 'Claude Terminal',
51
- // Priority
52
- 'priority.p0': 'P0 - Critical',
53
- 'priority.p1': 'P1 - High',
54
- 'priority.p2': 'P2 - Normal',
55
- 'priority.p3': 'P3 - Low',
56
- // Semver
57
- 'semver.patch': 'Patch (x.x.X) - Bug fix',
58
- 'semver.minor': 'Minor (x.X.0) - Feature',
59
- 'semver.major': 'Major (X.0.0) - Breaking',
60
- 'semver.none': 'No deployment',
61
- // Status
62
- 'status.waiting': 'Waiting',
63
- 'status.processing': 'Running...',
64
- 'status.completed': 'Completed',
65
- 'status.failed': 'Failed',
66
- 'status.connected': 'Connected',
67
- // Stats
68
- 'stats.total': 'Total',
69
- 'stats.tokens': 'Tokens',
70
- 'stats.viewStats': 'View stats',
71
- // Board
72
- 'board.empty': 'Empty',
73
- // Action modal
74
- 'action.instructions': 'Instructions',
75
- 'action.noInstructions': 'No instructions available',
76
- 'action.noFile': 'No ACTION file. Click "Edit" to create it.',
77
- 'action.modifiedOn': 'Modified on',
78
- // Notifications
79
- 'notify.titleRequired': 'Title required',
80
- 'notify.titleMandatory': 'Title is mandatory',
81
- 'notify.issueUpdated': 'Issue updated',
82
- 'notify.issueCreated': 'Issue created',
83
- 'notify.issueAdvanced': 'Issue advanced',
84
- 'notify.issueArchived': 'Issue archived',
85
- 'notify.issueMoved': 'moved',
86
- 'notify.moveTo': 'To',
87
- 'notify.commentAdded': 'Comment added',
88
- 'notify.actionUpdated': 'updated',
89
- 'notify.error': 'Error',
90
- 'notify.unableToSave': 'Unable to save',
91
- 'notify.loadingError': 'Loading error',
92
- 'notify.claudeStarted': 'Claude started',
93
- 'notify.claudeFinished': 'Claude finished',
94
- 'notify.claudeFailed': 'Claude failed',
95
- 'notify.processingSuccess': 'Processing successful',
96
- 'notify.checkLogs': 'Check logs',
97
- // Confirm
98
- 'confirm.archive': 'Archive',
99
- // Button states
100
- 'btn.updating': 'Updating...',
101
- 'btn.creating': 'Creating...',
102
- 'btn.moving': 'Moving...',
103
- 'btn.archiving': 'Archiving...',
104
- 'btn.sending': 'Sending...',
105
- 'btn.saving': 'Saving...',
106
- // Changelog
107
- 'changelog.title': "What's new?",
108
- 'changelog.gotIt': 'Got it',
109
- 'changelog.viewAll': 'View all',
110
- 'changelog.moreVersions': '...and {count} more versions',
111
- // Footer
112
- 'footer.changelog': 'Changelog',
113
- },
114
- fr: {
115
- // Filter
116
- 'filter.allPriorities': 'Toutes priorités',
117
- 'filter.search': 'Rechercher...',
118
- // Buttons
119
- 'btn.newIssue': '+ Nouveau ticket',
120
- 'btn.createIssue': 'Créer le ticket',
121
- 'btn.update': 'Mettre à jour',
122
- 'btn.cancel': 'Annuler',
123
- 'btn.archive': 'Archiver',
124
- 'btn.next': 'Suivant',
125
- 'btn.add': 'Ajouter',
126
- 'btn.edit': 'Modifier',
127
- 'btn.save': 'Enregistrer',
128
- 'btn.reload': 'Recharger',
129
- // Modal
130
- 'modal.newIssue': 'Nouveau ticket',
131
- 'modal.editIssue': 'Modifier',
132
- 'modal.title': 'Titre *',
133
- 'modal.titlePlaceholder': 'Ex: Corriger le bug de connexion',
134
- 'modal.description': 'Description',
135
- 'modal.descriptionPlaceholder': 'Décrivez le contexte et les détails...',
136
- 'modal.priority': 'Priorité',
137
- 'modal.releaseType': 'Type de release',
138
- 'modal.labels': 'Labels',
139
- 'modal.selectLabel': 'Sélectionner un label...',
140
- 'modal.acceptanceCriteria': 'Critères d\\'acceptation',
141
- 'modal.addCriteria': 'Ajouter un critère',
142
- 'modal.attachments': 'Pièces jointes',
143
- 'modal.addAttachment': 'Ajouter un fichier',
144
- 'modal.noAttachments': 'Aucune pièce jointe',
145
- 'modal.comments': 'Commentaires',
146
- 'modal.noComments': 'Aucun commentaire',
147
- 'modal.addCommentPlaceholder': 'Ajouter un commentaire...',
148
- 'modal.claudeTerminal': 'Terminal Claude',
149
- // Priority
150
- 'priority.p0': 'P0 - Critique',
151
- 'priority.p1': 'P1 - Haute',
152
- 'priority.p2': 'P2 - Normale',
153
- 'priority.p3': 'P3 - Basse',
154
- // Semver
155
- 'semver.patch': 'Patch (x.x.X) - Bug fix',
156
- 'semver.minor': 'Minor (x.X.0) - Fonctionnalité',
157
- 'semver.major': 'Major (X.0.0) - Breaking',
158
- 'semver.none': 'Aucun déploiement',
159
- // Status
160
- 'status.waiting': 'En attente',
161
- 'status.processing': 'En cours...',
162
- 'status.completed': 'Terminé',
163
- 'status.failed': 'Échoué',
164
- 'status.connected': 'Connecté',
165
- // Stats
166
- 'stats.total': 'Total',
167
- 'stats.tokens': 'Tokens',
168
- 'stats.viewStats': 'Voir stats',
169
- // Board
170
- 'board.empty': 'Vide',
171
- // Action modal
172
- 'action.instructions': 'Instructions',
173
- 'action.noInstructions': 'Aucune instruction disponible',
174
- 'action.noFile': 'Aucun fichier ACTION. Cliquez sur "Modifier" pour le créer.',
175
- 'action.modifiedOn': 'Modifié le',
176
- // Notifications
177
- 'notify.titleRequired': 'Titre requis',
178
- 'notify.titleMandatory': 'Le titre est obligatoire',
179
- 'notify.issueUpdated': 'Ticket mis à jour',
180
- 'notify.issueCreated': 'Ticket créé',
181
- 'notify.issueAdvanced': 'Ticket avancé',
182
- 'notify.issueArchived': 'Ticket archivé',
183
- 'notify.issueMoved': 'déplacé',
184
- 'notify.moveTo': 'Vers',
185
- 'notify.commentAdded': 'Commentaire ajouté',
186
- 'notify.actionUpdated': 'mis à jour',
187
- 'notify.error': 'Erreur',
188
- 'notify.unableToSave': 'Impossible de sauvegarder',
189
- 'notify.loadingError': 'Erreur de chargement',
190
- 'notify.claudeStarted': 'Claude démarré',
191
- 'notify.claudeFinished': 'Claude terminé',
192
- 'notify.claudeFailed': 'Claude échoué',
193
- 'notify.processingSuccess': 'Traitement réussi',
194
- 'notify.checkLogs': 'Voir les logs',
195
- // Confirm
196
- 'confirm.archive': 'Archiver',
197
- // Button states
198
- 'btn.updating': 'Mise à jour...',
199
- 'btn.creating': 'Création...',
200
- 'btn.moving': 'Déplacement...',
201
- 'btn.archiving': 'Archivage...',
202
- 'btn.sending': 'Envoi...',
203
- 'btn.saving': 'Sauvegarde...',
204
- // Changelog
205
- 'changelog.title': 'Quoi de neuf ?',
206
- 'changelog.gotIt': "J'ai compris",
207
- 'changelog.viewAll': 'Voir tout',
208
- 'changelog.moreVersions': '...et {count} autres versions',
209
- // Footer
210
- 'footer.changelog': 'Changelog',
211
- }
212
- };
213
-
214
- let currentLang = localStorage.getItem('autocode-lang') || 'fr';
215
-
216
- function t(key) {
217
- return translations[currentLang][key] || translations['en'][key] || key;
218
- }
219
-
220
- function switchLanguage(lang) {
221
- currentLang = lang;
222
- currentActionLang = lang;
223
- localStorage.setItem('autocode-lang', lang);
224
- document.documentElement.lang = lang;
225
-
226
- // Update lang switcher buttons
227
- document.querySelectorAll('.lang-switcher .lang-btn').forEach(btn => {
228
- btn.classList.toggle('active', btn.dataset.lang === lang);
229
- });
230
-
231
- // Update all elements with data-i18n
232
- document.querySelectorAll('[data-i18n]').forEach(el => {
233
- const key = el.getAttribute('data-i18n');
234
- if (translations[lang] && translations[lang][key]) {
235
- el.textContent = translations[lang][key];
236
- }
237
- });
238
-
239
- // Update placeholders
240
- document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
241
- const key = el.getAttribute('data-i18n-placeholder');
242
- if (translations[lang] && translations[lang][key]) {
243
- el.placeholder = translations[lang][key];
244
- }
245
- });
246
-
247
- // Update select options
248
- document.querySelectorAll('select option[data-i18n]').forEach(el => {
249
- const key = el.getAttribute('data-i18n');
250
- if (translations[lang] && translations[lang][key]) {
251
- el.textContent = translations[lang][key];
252
- }
253
- });
254
-
255
- // Re-render board to update dynamic content
52
+ ${generateI18nScript({
53
+ keys: [...dashboardKeys],
54
+ includeActionLang: true,
55
+ onLangChangeCallback: 'onDashboardLangChange',
56
+ })}
57
+
58
+ // Callback after language change - re-render board
59
+ function onDashboardLangChange() {
256
60
  render();
257
61
  }
258
62
 
@@ -269,19 +73,10 @@ export function getScript() {
269
73
  let draggedIssue = null;
270
74
  let draggedFromColumn = null;
271
75
  let currentActionSlug = null;
272
- let currentActionLang = localStorage.getItem('autocode-lang') || 'fr';
273
76
  let originalActionContent = '';
274
77
  let claudeProcessingIssues = new Set();
275
78
  let claudeStats = { session: { tokensInput: 0, tokensOutput: 0, callCount: 0 } };
276
79
 
277
- // Initialize language switcher on page load
278
- (function initLangSwitcher() {
279
- document.querySelectorAll('.lang-switcher .lang-btn').forEach(btn => {
280
- btn.addEventListener('click', () => switchLanguage(btn.dataset.lang));
281
- });
282
- switchLanguage(currentLang);
283
- })();
284
-
285
80
  // ========================================
286
81
  // NOTIFICATIONS
287
82
  // ========================================
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/dashboard/scripts/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA87CN,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/dashboard/scripts/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,6BAA6B;AAC7B,MAAM,aAAa,GAAG;IACpB,SAAS;IACT,sBAAsB,EAAE,eAAe;IACvC,UAAU;IACV,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa;IAC5E,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY;IAC3D,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY;IAC1F,QAAQ;IACR,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,wBAAwB;IAC5E,mBAAmB,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,mBAAmB;IAC1F,cAAc,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,mBAAmB;IACpF,mBAAmB,EAAE,qBAAqB,EAAE,qBAAqB;IACjE,gBAAgB,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,sBAAsB;IAC3F,WAAW;IACX,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa;IAC1D,SAAS;IACT,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa;IAC7D,SAAS;IACT,gBAAgB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB;IAC9F,QAAQ;IACR,aAAa,EAAE,cAAc,EAAE,iBAAiB;IAChD,QAAQ;IACR,aAAa;IACb,eAAe;IACf,qBAAqB,EAAE,uBAAuB,EAAE,eAAe,EAAE,mBAAmB;IACpF,gBAAgB;IAChB,sBAAsB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,qBAAqB;IAC7F,sBAAsB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,eAAe;IACpF,qBAAqB,EAAE,sBAAsB,EAAE,cAAc,EAAE,qBAAqB;IACpF,qBAAqB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,qBAAqB;IAC7F,0BAA0B,EAAE,kBAAkB;IAC9C,UAAU;IACV,iBAAiB;IACjB,YAAY;IACZ,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,wBAAwB;IACnF,SAAS;IACT,kBAAkB;CACV,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO;MACH,kBAAkB,CAAC;QACnB,IAAI,EAAE,CAAC,GAAG,aAAa,CAAC;QACxB,iBAAiB,EAAE,IAAI;QACvB,oBAAoB,EAAE,uBAAuB;KAC9C,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAosCH,CAAC;AACJ,CAAC"}