@unbrained/pm-web 2026.7.28 → 2026.7.29

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 (96) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.js +1 -1
  3. package/dist/oidc.js.map +1 -1
  4. package/dist/routes/extensions.d.ts +1 -1
  5. package/dist/routes/oidc.d.ts +1 -1
  6. package/dist/routes/pm.js +125 -0
  7. package/dist/routes/pm.js.map +1 -1
  8. package/dist/services/mutation-event-watcher.d.ts +1 -1
  9. package/dist/services/package-catalog.d.ts +28 -4
  10. package/dist/services/package-catalog.js +67 -5
  11. package/dist/services/package-catalog.js.map +1 -1
  12. package/dist/services/pm-runner.d.ts +1 -1
  13. package/dist/services/pm-runner.js +8 -1
  14. package/dist/services/pm-runner.js.map +1 -1
  15. package/dist/services/project-watcher.d.ts +1 -1
  16. package/dist/services/realtime-bus.d.ts +1 -1
  17. package/manifest.json +1 -1
  18. package/package.json +21 -6
  19. package/public/src/api-types.js +17 -0
  20. package/public/src/api-types.js.map +1 -0
  21. package/public/src/api-types.ts +618 -0
  22. package/public/src/api.js +6 -3
  23. package/public/src/api.js.map +1 -1
  24. package/public/src/api.ts +30 -10
  25. package/public/src/app.js +4 -4
  26. package/public/src/app.js.map +1 -1
  27. package/public/src/app.ts +47 -12
  28. package/public/src/i18n/de.json +2 -1
  29. package/public/src/i18n/en.json +2 -1
  30. package/public/src/i18n/es.json +2 -1
  31. package/public/src/i18n/zh.json +2 -1
  32. package/public/src/i18n.ts +1 -1
  33. package/public/src/sw.ts +1 -0
  34. package/public/src/types.ts +11 -2
  35. package/public/src/views/activity.js +1 -1
  36. package/public/src/views/activity.js.map +1 -1
  37. package/public/src/views/activity.ts +5 -4
  38. package/public/src/views/calendar.js +1 -1
  39. package/public/src/views/calendar.js.map +1 -1
  40. package/public/src/views/calendar.ts +13 -11
  41. package/public/src/views/comments-audit.js.map +1 -1
  42. package/public/src/views/comments-audit.ts +7 -6
  43. package/public/src/views/config.js +1 -1
  44. package/public/src/views/config.js.map +1 -1
  45. package/public/src/views/config.ts +2 -2
  46. package/public/src/views/context.js +3 -3
  47. package/public/src/views/context.js.map +1 -1
  48. package/public/src/views/context.ts +10 -9
  49. package/public/src/views/create.js.map +1 -1
  50. package/public/src/views/create.ts +3 -2
  51. package/public/src/views/dedupe.js +5 -5
  52. package/public/src/views/dedupe.js.map +1 -1
  53. package/public/src/views/dedupe.ts +9 -8
  54. package/public/src/views/export.js.map +1 -1
  55. package/public/src/views/export.ts +2 -2
  56. package/public/src/views/github.js +5 -4
  57. package/public/src/views/github.js.map +1 -1
  58. package/public/src/views/github.ts +20 -18
  59. package/public/src/views/graph.js +7 -9
  60. package/public/src/views/graph.js.map +1 -1
  61. package/public/src/views/graph.ts +11 -13
  62. package/public/src/views/groups.js +1 -1
  63. package/public/src/views/groups.js.map +1 -1
  64. package/public/src/views/groups.ts +9 -8
  65. package/public/src/views/health.js +16 -2
  66. package/public/src/views/health.js.map +1 -1
  67. package/public/src/views/health.ts +26 -8
  68. package/public/src/views/items.js +18 -12
  69. package/public/src/views/items.js.map +1 -1
  70. package/public/src/views/items.ts +65 -35
  71. package/public/src/views/normalize.js.map +1 -1
  72. package/public/src/views/normalize.ts +5 -4
  73. package/public/src/views/packages.js +10 -1
  74. package/public/src/views/packages.js.map +1 -1
  75. package/public/src/views/packages.ts +19 -2
  76. package/public/src/views/plan.js +0 -2
  77. package/public/src/views/plan.js.map +1 -1
  78. package/public/src/views/plan.ts +5 -6
  79. package/public/src/views/projects.js.map +1 -1
  80. package/public/src/views/projects.ts +8 -7
  81. package/public/src/views/search.js.map +1 -1
  82. package/public/src/views/search.ts +3 -2
  83. package/public/src/views/settings.js.map +1 -1
  84. package/public/src/views/settings.ts +8 -6
  85. package/public/src/views/shared.js.map +1 -1
  86. package/public/src/views/shared.ts +4 -3
  87. package/public/src/views/sharing.js.map +1 -1
  88. package/public/src/views/sharing.ts +5 -4
  89. package/public/src/views/stats.js +1 -1
  90. package/public/src/views/stats.js.map +1 -1
  91. package/public/src/views/stats.ts +10 -9
  92. package/public/src/views/templates.js.map +1 -1
  93. package/public/src/views/templates.ts +6 -5
  94. package/public/src/views/validate.js.map +1 -1
  95. package/public/src/views/validate.ts +6 -5
  96. package/public/sw.js +1 -0
@@ -6,6 +6,7 @@ import { api } from '../api.js';
6
6
  import { escHtml, typeIcon } from '../utils.js';
7
7
  import { toast } from '../components/toast.js';
8
8
  import { showView } from './router.js';
9
+ import type { TemplateEntry, TemplatesResponse } from '../api-types.js';
9
10
 
10
11
  export async function renderTemplatesView(): Promise<void> {
11
12
  const el = document.getElementById('content-templates');
@@ -32,8 +33,8 @@ async function fetchAndRenderTemplates(): Promise<void> {
32
33
  const pid = state.currentProject?.id;
33
34
  if (!pid) return;
34
35
  try {
35
- const data = await api('GET', `/projects/${pid}/pm/templates`);
36
- const templates: any[] = (data as any).templates || [];
36
+ const data = await api<TemplatesResponse>('GET', `/projects/${pid}/pm/templates`);
37
+ const templates: TemplateEntry[] = data.templates || [];
37
38
  const el = document.getElementById('templates-content');
38
39
  if (!el) return;
39
40
  if (templates.length === 0) {
@@ -52,7 +53,7 @@ async function fetchAndRenderTemplates(): Promise<void> {
52
53
  }
53
54
  el.innerHTML = `
54
55
  <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px">
55
- ${templates.map((t: any) => renderTemplateCard(t)).join('')}
56
+ ${templates.map((t) => renderTemplateCard(t)).join('')}
56
57
  </div>`;
57
58
  } catch(err: unknown) {
58
59
  const el = document.getElementById('templates-content');
@@ -60,7 +61,7 @@ async function fetchAndRenderTemplates(): Promise<void> {
60
61
  }
61
62
  }
62
63
 
63
- function renderTemplateCard(t: any): string {
64
+ function renderTemplateCard(t: TemplateEntry): string {
64
65
  const name = t.name || t.id || 'Unnamed';
65
66
  const type = t.type || t.defaults?.type || '';
66
67
  const priority = t.priority || t.defaults?.priority || '';
@@ -86,7 +87,7 @@ function renderTemplateCard(t: any): string {
86
87
  </div>`;
87
88
  }
88
89
 
89
- export function createFromTemplate(name: string, template: any): void {
90
+ export function createFromTemplate(name: string, template: TemplateEntry): void {
90
91
  // Navigate to create view and pre-fill from template
91
92
  showView('create');
92
93
  // Give the create view time to render, then fill fields
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["validate.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@
4
4
  import { state } from '../state.js';
5
5
  import { api } from '../api.js';
6
6
  import { escHtml } from '../utils.js';
7
+ import type { ValidateIssue, ValidateResponse } from '../api-types.js';
7
8
 
8
9
  export async function renderValidateView(): Promise<void> {
9
10
  const el = document.getElementById('content-validate');
@@ -16,19 +17,19 @@ export async function renderValidateView(): Promise<void> {
16
17
  </div>
17
18
  <div id="validate-content"><div class="loading-state"><div class="loading-spinner"></div></div></div>`;
18
19
  try {
19
- const data = await api('GET', `/projects/${state.currentProject.id}/pm/validate`) as any;
20
- const issues = data.issues || data.errors || data.violations || [];
21
- const warnings = data.warnings || [];
20
+ const data = await api<ValidateResponse>('GET', `/projects/${state.currentProject.id}/pm/validate`);
21
+ const issues: ValidateIssue[] = data.issues || data.errors || data.violations || [];
22
+ const warnings: ValidateIssue[] = data.warnings || [];
22
23
  const el2 = document.getElementById('validate-content');
23
24
  if (!el2) return;
24
- const allIssues = [...issues.map((i: any)=>({...i,level:'error'})), ...warnings.map((w: any)=>({...w,level:'warning'}))];
25
+ const allIssues = [...issues.map((i)=>({...i,level:'error'})), ...warnings.map((w)=>({...w,level:'warning'}))];
25
26
  el2.innerHTML = `
26
27
  <div class="card" style="margin-bottom:12px">
27
28
  <div class="card-header"><div class="card-title">Validation Results</div></div>
28
29
  <div class="card-body">
29
30
  ${allIssues.length === 0
30
31
  ? '<div style="color:var(--status-closed);font-size:13px">✓ All checks passed — no issues found!</div>'
31
- : allIssues.map((i: any)=>`
32
+ : allIssues.map((i)=>`
32
33
  <div style="display:flex;gap:8px;align-items:flex-start;padding:8px 0;border-bottom:1px solid var(--border)">
33
34
  <span style="color:${i.level==='error'?'var(--status-blocked)':'var(--priority-3)'};flex-shrink:0">${i.level==='error'?'✗':'⚠'}</span>
34
35
  <div>
package/public/sw.js CHANGED
@@ -30,6 +30,7 @@ const STATIC_ASSETS = [
30
30
  '/icons/icon-192.png',
31
31
  '/icons/icon-512.png',
32
32
  '/src/api.js',
33
+ '/src/api-types.js',
33
34
  '/src/app.js',
34
35
  '/src/components/modals.js',
35
36
  '/src/components/toast.js',