@unbrained/pm-web 1.0.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.
Files changed (150) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +107 -0
  3. package/dist/auth.js +20 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/crypto.js +42 -0
  6. package/dist/crypto.js.map +1 -0
  7. package/dist/db.js +111 -0
  8. package/dist/db.js.map +1 -0
  9. package/dist/index.js +88 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/middleware/auth.js +16 -0
  12. package/dist/middleware/auth.js.map +1 -0
  13. package/dist/routes/admin.js +207 -0
  14. package/dist/routes/admin.js.map +1 -0
  15. package/dist/routes/auth.js +163 -0
  16. package/dist/routes/auth.js.map +1 -0
  17. package/dist/routes/github.js +354 -0
  18. package/dist/routes/github.js.map +1 -0
  19. package/dist/routes/groups.js +180 -0
  20. package/dist/routes/groups.js.map +1 -0
  21. package/dist/routes/pm.js +2446 -0
  22. package/dist/routes/pm.js.map +1 -0
  23. package/dist/routes/projects.js +151 -0
  24. package/dist/routes/projects.js.map +1 -0
  25. package/dist/routes/sharing.js +155 -0
  26. package/dist/routes/sharing.js.map +1 -0
  27. package/dist/server.js +64 -0
  28. package/dist/server.js.map +1 -0
  29. package/dist/services/pm-runner.js +190 -0
  30. package/dist/services/pm-runner.js.map +1 -0
  31. package/dist/services/sse.js +111 -0
  32. package/dist/services/sse.js.map +1 -0
  33. package/manifest.json +15 -0
  34. package/package.json +111 -0
  35. package/public/icons/icon-192.png +0 -0
  36. package/public/icons/icon-512.png +0 -0
  37. package/public/index.html +265 -0
  38. package/public/manifest.json +66 -0
  39. package/public/src/api.js +28 -0
  40. package/public/src/api.js.map +1 -0
  41. package/public/src/api.ts +29 -0
  42. package/public/src/app.js +926 -0
  43. package/public/src/app.js.map +1 -0
  44. package/public/src/app.ts +929 -0
  45. package/public/src/components/modals.js +62 -0
  46. package/public/src/components/modals.js.map +1 -0
  47. package/public/src/components/modals.ts +73 -0
  48. package/public/src/components/toast.js +10 -0
  49. package/public/src/components/toast.js.map +1 -0
  50. package/public/src/components/toast.ts +13 -0
  51. package/public/src/constants.js +30 -0
  52. package/public/src/constants.js.map +1 -0
  53. package/public/src/constants.ts +41 -0
  54. package/public/src/state.js +15 -0
  55. package/public/src/state.js.map +1 -0
  56. package/public/src/state.ts +19 -0
  57. package/public/src/types.js +5 -0
  58. package/public/src/types.js.map +1 -0
  59. package/public/src/types.ts +253 -0
  60. package/public/src/utils.js +57 -0
  61. package/public/src/utils.js.map +1 -0
  62. package/public/src/utils.ts +56 -0
  63. package/public/src/views/activity.js +47 -0
  64. package/public/src/views/activity.js.map +1 -0
  65. package/public/src/views/activity.ts +41 -0
  66. package/public/src/views/admin.js +435 -0
  67. package/public/src/views/admin.js.map +1 -0
  68. package/public/src/views/admin.ts +504 -0
  69. package/public/src/views/auth.js +81 -0
  70. package/public/src/views/auth.js.map +1 -0
  71. package/public/src/views/auth.ts +74 -0
  72. package/public/src/views/calendar.js +133 -0
  73. package/public/src/views/calendar.js.map +1 -0
  74. package/public/src/views/calendar.ts +129 -0
  75. package/public/src/views/comments-audit.js +109 -0
  76. package/public/src/views/comments-audit.js.map +1 -0
  77. package/public/src/views/comments-audit.ts +108 -0
  78. package/public/src/views/config.js +322 -0
  79. package/public/src/views/config.js.map +1 -0
  80. package/public/src/views/config.ts +344 -0
  81. package/public/src/views/context.js +98 -0
  82. package/public/src/views/context.js.map +1 -0
  83. package/public/src/views/context.ts +100 -0
  84. package/public/src/views/create.js +293 -0
  85. package/public/src/views/create.js.map +1 -0
  86. package/public/src/views/create.ts +246 -0
  87. package/public/src/views/dedupe.js +51 -0
  88. package/public/src/views/dedupe.js.map +1 -0
  89. package/public/src/views/dedupe.ts +43 -0
  90. package/public/src/views/export.js +300 -0
  91. package/public/src/views/export.js.map +1 -0
  92. package/public/src/views/export.ts +274 -0
  93. package/public/src/views/github.js +360 -0
  94. package/public/src/views/github.js.map +1 -0
  95. package/public/src/views/github.ts +308 -0
  96. package/public/src/views/graph-canvas.js +1986 -0
  97. package/public/src/views/graph-canvas.js.map +1 -0
  98. package/public/src/views/graph-canvas.ts +2218 -0
  99. package/public/src/views/graph.js +1824 -0
  100. package/public/src/views/graph.js.map +1 -0
  101. package/public/src/views/graph.ts +1891 -0
  102. package/public/src/views/groups.js +186 -0
  103. package/public/src/views/groups.js.map +1 -0
  104. package/public/src/views/groups.ts +172 -0
  105. package/public/src/views/guide.js +151 -0
  106. package/public/src/views/guide.js.map +1 -0
  107. package/public/src/views/guide.ts +162 -0
  108. package/public/src/views/health.js +105 -0
  109. package/public/src/views/health.js.map +1 -0
  110. package/public/src/views/health.ts +102 -0
  111. package/public/src/views/items.js +1306 -0
  112. package/public/src/views/items.js.map +1 -0
  113. package/public/src/views/items.ts +1196 -0
  114. package/public/src/views/normalize.js +67 -0
  115. package/public/src/views/normalize.js.map +1 -0
  116. package/public/src/views/normalize.ts +58 -0
  117. package/public/src/views/plan.js +454 -0
  118. package/public/src/views/plan.js.map +1 -0
  119. package/public/src/views/plan.ts +496 -0
  120. package/public/src/views/projects.js +204 -0
  121. package/public/src/views/projects.js.map +1 -0
  122. package/public/src/views/projects.ts +196 -0
  123. package/public/src/views/router.js +227 -0
  124. package/public/src/views/router.js.map +1 -0
  125. package/public/src/views/router.ts +188 -0
  126. package/public/src/views/search.js +103 -0
  127. package/public/src/views/search.js.map +1 -0
  128. package/public/src/views/search.ts +94 -0
  129. package/public/src/views/settings.js +272 -0
  130. package/public/src/views/settings.js.map +1 -0
  131. package/public/src/views/settings.ts +190 -0
  132. package/public/src/views/shared.js +49 -0
  133. package/public/src/views/shared.js.map +1 -0
  134. package/public/src/views/shared.ts +49 -0
  135. package/public/src/views/sharing.js +152 -0
  136. package/public/src/views/sharing.js.map +1 -0
  137. package/public/src/views/sharing.ts +139 -0
  138. package/public/src/views/stats.js +92 -0
  139. package/public/src/views/stats.js.map +1 -0
  140. package/public/src/views/stats.ts +88 -0
  141. package/public/src/views/templates.js +117 -0
  142. package/public/src/views/templates.js.map +1 -0
  143. package/public/src/views/templates.ts +113 -0
  144. package/public/src/views/validate.js +54 -0
  145. package/public/src/views/validate.js.map +1 -0
  146. package/public/src/views/validate.ts +48 -0
  147. package/public/styles.css +2231 -0
  148. package/public/sw.js +318 -0
  149. package/public/tsconfig.json +20 -0
  150. package/sql/schema.sql +105 -0
@@ -0,0 +1,360 @@
1
+ // ═══════════════════════════════════════════════════════════════
2
+ // GITHUB VIEW
3
+ // ═══════════════════════════════════════════════════════════════
4
+ import { state } from '../state.js';
5
+ import { api } from '../api.js';
6
+ import { escHtml } from '../utils.js';
7
+ import { confirmDialog } from '../components/modals.js';
8
+ import { toast } from '../components/toast.js';
9
+ export async function renderGitHubView() {
10
+ const el = document.getElementById('content-github');
11
+ if (!el)
12
+ return;
13
+ if (!state.currentProject) {
14
+ el.innerHTML = '<div class="empty-state"><div class="empty-state-text">No project selected</div></div>';
15
+ return;
16
+ }
17
+ el.innerHTML = `
18
+ <div class="page-header">
19
+ <div><div class="page-title">GitHub Integration</div><div class="page-subtitle">${escHtml(state.currentProject.name)}</div></div>
20
+ <div class="page-actions"><button class="btn btn-secondary btn-sm" onclick="window.__app.renderGitHubView()">↺ Refresh</button></div>
21
+ </div>
22
+ <div id="github-content"><div class="loading-state"><div class="loading-spinner"></div></div></div>`;
23
+ if (!state.user?.has_github_token) {
24
+ const contentEl = document.getElementById('github-content');
25
+ if (contentEl)
26
+ contentEl.innerHTML = `
27
+ <div class="card">
28
+ <div class="card-body">
29
+ <div style="display:flex;align-items:center;gap:10px;padding:12px;background:rgba(251,146,60,0.1);border:1px solid rgba(251,146,60,0.3);border-radius:var(--radius);margin-bottom:16px">
30
+ <span style="font-size:16px">⚠</span>
31
+ <div>
32
+ <div style="font-size:13px;font-weight:500;color:#fb923c">GitHub token required</div>
33
+ <div style="font-size:12px;color:var(--text-secondary);margin-top:2px">Add a GitHub token in <a href="#" onclick="window.__app.showView('settings');return false" style="color:var(--accent)">Settings</a> first to use GitHub integration.</div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>`;
38
+ return;
39
+ }
40
+ try {
41
+ const data = await api('GET', `/projects/${state.currentProject.id}/github`);
42
+ renderGitHubContent(data);
43
+ }
44
+ catch (err) {
45
+ const contentEl = document.getElementById('github-content');
46
+ if (contentEl)
47
+ contentEl.innerHTML = `<div class="empty-state"><div class="empty-state-text">Error: ${escHtml(err instanceof Error ? err.message : String(err))}</div></div>`;
48
+ }
49
+ }
50
+ function renderGitHubContent(data) {
51
+ const linked = data.linked;
52
+ const owner = data.owner || '';
53
+ const repo = data.repo || '';
54
+ const tokenBanner = !state.user?.has_github_token ? `
55
+ <div style="display:flex;align-items:center;gap:10px;padding:12px;background:rgba(251,146,60,0.1);border:1px solid rgba(251,146,60,0.3);border-radius:var(--radius);margin-bottom:16px">
56
+ <span style="font-size:16px">⚠</span>
57
+ <div style="font-size:13px;color:var(--text-secondary)">Add a GitHub token in <a href="#" onclick="window.__app.showView('settings');return false" style="color:var(--accent)">Settings</a> first</div>
58
+ </div>` : '';
59
+ const linkPanel = `
60
+ <div class="card" style="margin-bottom:16px">
61
+ <div class="card-header"><div class="card-title">${linked ? 'Linked Repository' : 'Link GitHub Repository'}</div></div>
62
+ <div class="card-body">
63
+ ${tokenBanner}
64
+ ${linked ? `
65
+ <div style="display:flex;align-items:center;gap:10px;margin-bottom:16px">
66
+ <span style="font-size:20px">⊙</span>
67
+ <div>
68
+ <div style="font-size:14px;font-weight:600">${escHtml(owner)}/${escHtml(repo)}</div>
69
+ <div style="font-size:12px;color:var(--text-muted)">Linked GitHub repository</div>
70
+ </div>
71
+ <button class="btn btn-danger btn-sm" style="margin-left:auto" onclick="window.__app.unlinkGitHubRepo()">Unlink</button>
72
+ </div>
73
+ <hr class="section-divider">` : ''}
74
+ <div class="two-col" style="margin-bottom:12px">
75
+ <div class="form-group" style="margin-bottom:0">
76
+ <label class="form-label">Owner / Organization</label>
77
+ <input class="form-input" id="gh-owner" type="text" placeholder="octocat" value="${escHtml(owner)}">
78
+ </div>
79
+ <div class="form-group" style="margin-bottom:0">
80
+ <label class="form-label">Repository Name</label>
81
+ <input class="form-input" id="gh-repo" type="text" placeholder="hello-world" value="${escHtml(repo)}">
82
+ </div>
83
+ </div>
84
+ <div class="form-error" id="gh-link-error" style="display:none"></div>
85
+ <button class="btn btn-primary btn-sm" id="gh-link-btn" onclick="window.__app.linkGitHubRepo()"><span>${linked ? 'Update Link' : 'Link Repository'}</span></button>
86
+ </div>
87
+ </div>`;
88
+ const syncPanels = linked ? `
89
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px" class="github-sync-grid">
90
+ <div class="card">
91
+ <div class="card-header">
92
+ <div class="card-title">↓ Import from GitHub</div>
93
+ <button class="btn btn-secondary btn-sm" onclick="window.__app.loadGitHubIssues()">↺ Load Issues</button>
94
+ </div>
95
+ <div class="card-body">
96
+ <div id="github-issues-list">
97
+ <div style="color:var(--text-muted);font-size:13px">Click "Load Issues" to fetch open GitHub issues.</div>
98
+ </div>
99
+ <div id="github-import-result" style="margin-top:12px;display:none"></div>
100
+ </div>
101
+ </div>
102
+ <div class="card">
103
+ <div class="card-header">
104
+ <div class="card-title">↑ Export to GitHub</div>
105
+ <button class="btn btn-secondary btn-sm" onclick="window.__app.loadItemsForPush()">↺ Load Items</button>
106
+ </div>
107
+ <div class="card-body">
108
+ <div id="github-push-list">
109
+ <div style="color:var(--text-muted);font-size:13px">Click "Load Items" to select pm items to push as GitHub issues.</div>
110
+ </div>
111
+ <div id="github-push-result" style="margin-top:12px;display:none"></div>
112
+ </div>
113
+ </div>
114
+ </div>` : '';
115
+ const contentEl = document.getElementById('github-content');
116
+ if (contentEl)
117
+ contentEl.innerHTML = linkPanel + syncPanels;
118
+ }
119
+ export async function linkGitHubRepo() {
120
+ const owner = document.getElementById('gh-owner')?.value?.trim() || '';
121
+ const repo = document.getElementById('gh-repo')?.value?.trim() || '';
122
+ const errEl = document.getElementById('gh-link-error');
123
+ const btn = document.getElementById('gh-link-btn');
124
+ if (errEl)
125
+ errEl.style.display = 'none';
126
+ if (!owner || !repo) {
127
+ if (errEl) {
128
+ errEl.textContent = 'Owner and repository name are required';
129
+ errEl.style.display = 'block';
130
+ }
131
+ return;
132
+ }
133
+ if (btn) {
134
+ btn.disabled = true;
135
+ const sp = btn.querySelector('span');
136
+ if (sp)
137
+ sp.textContent = 'Linking…';
138
+ }
139
+ try {
140
+ await api('PATCH', `/projects/${state.currentProject.id}/github`, { owner, repo });
141
+ toast('Repository linked', 'success');
142
+ renderGitHubView();
143
+ }
144
+ catch (err) {
145
+ if (errEl) {
146
+ errEl.textContent = err instanceof Error ? err.message : String(err);
147
+ errEl.style.display = 'block';
148
+ }
149
+ if (btn) {
150
+ btn.disabled = false;
151
+ const sp = btn.querySelector('span');
152
+ if (sp)
153
+ sp.textContent = 'Link Repository';
154
+ }
155
+ }
156
+ }
157
+ export function unlinkGitHubRepo() {
158
+ confirmDialog('Unlink Repository?', 'GitHub integration will be disabled for this project.', async () => {
159
+ try {
160
+ await api('PATCH', `/projects/${state.currentProject.id}/github`, { owner: '', repo: '' });
161
+ toast('Repository unlinked', 'success');
162
+ renderGitHubView();
163
+ }
164
+ catch (err) {
165
+ toast(err instanceof Error ? err.message : String(err), 'error');
166
+ }
167
+ });
168
+ }
169
+ export async function loadGitHubIssues() {
170
+ const el = document.getElementById('github-issues-list');
171
+ if (!el)
172
+ return;
173
+ el.innerHTML = '<div class="loading-state"><div class="loading-spinner"></div></div>';
174
+ try {
175
+ const data = await api('GET', `/projects/${state.currentProject.id}/github/issues`);
176
+ const issues = data.issues || [];
177
+ if (issues.length === 0) {
178
+ el.innerHTML = '<div style="color:var(--text-muted);font-size:13px">No open issues found in this repository.</div>';
179
+ return;
180
+ }
181
+ el.innerHTML = `
182
+ <div style="margin-bottom:12px;display:flex;align-items:center;justify-content:space-between">
183
+ <div style="font-size:12px;color:var(--text-muted)">${issues.length} open issue${issues.length !== 1 ? 's' : ''} — select to import</div>
184
+ <div style="display:flex;gap:8px">
185
+ <button class="btn btn-ghost btn-sm" onclick="window.__app.selectAllIssues(true)">Select All</button>
186
+ <button class="btn btn-ghost btn-sm" onclick="window.__app.selectAllIssues(false)">None</button>
187
+ </div>
188
+ </div>
189
+ <div style="display:flex;flex-direction:column;gap:4px;max-height:360px;overflow-y:auto;margin-bottom:12px">
190
+ ${issues.map((i) => `
191
+ <label style="display:flex;align-items:flex-start;gap:10px;padding:8px 10px;background:var(--bg-card2);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:var(--transition)" onmouseover="this.style.borderColor='var(--border-light)'" onmouseout="this.style.borderColor='var(--border)'">
192
+ <input type="checkbox" class="gh-issue-cb" data-number="${escHtml(String(i.number))}" style="margin-top:2px;accent-color:var(--accent)">
193
+ <div style="flex:1;min-width:0">
194
+ <div style="font-size:13px;font-weight:500">${escHtml(i.title || '')}</div>
195
+ <div style="font-size:11px;color:var(--text-muted);margin-top:2px">#${escHtml(String(i.number))}${i.labels?.length ? ` · ${i.labels.map((l) => escHtml(l.name || l)).join(', ')}` : ''}</div>
196
+ </div>
197
+ </label>`).join('')}
198
+ </div>
199
+ <button class="btn btn-primary btn-sm" id="gh-import-btn" onclick="window.__app.importGitHubIssues()"><span>Import Selected</span></button>`;
200
+ }
201
+ catch (err) {
202
+ el.innerHTML = `<div style="color:var(--status-blocked);font-size:13px">Error: ${escHtml(err instanceof Error ? err.message : String(err))}</div>`;
203
+ }
204
+ }
205
+ export function selectAllIssues(checked) {
206
+ document.querySelectorAll('.gh-issue-cb').forEach(cb => { cb.checked = checked; });
207
+ }
208
+ export async function loadItemsForPush() {
209
+ const el = document.getElementById('github-push-list');
210
+ if (!el)
211
+ return;
212
+ el.innerHTML = '<div class="loading-state"><div class="loading-spinner"></div></div>';
213
+ try {
214
+ const [itemsData, linksData] = await Promise.all([
215
+ api('GET', `/projects/${state.currentProject.id}/pm/list-all?limit=200`),
216
+ api('GET', `/projects/${state.currentProject.id}/github/links`),
217
+ ]);
218
+ const items = itemsData.items || [];
219
+ const links = linksData.links || [];
220
+ const linkMap = new Map(links.map(l => [l.pm_item_id, l]));
221
+ if (items.length === 0) {
222
+ el.innerHTML = '<div style="color:var(--text-muted);font-size:13px">No open items in this project.</div>';
223
+ return;
224
+ }
225
+ el.innerHTML = `
226
+ <div style="margin-bottom:12px;display:flex;align-items:center;justify-content:space-between">
227
+ <div style="font-size:12px;color:var(--text-muted)">${items.length} item${items.length !== 1 ? 's' : ''} — select to push as issues</div>
228
+ <div style="display:flex;gap:8px">
229
+ <button class="btn btn-ghost btn-sm" onclick="window.__app.selectAllPushItems(true)">All</button>
230
+ <button class="btn btn-ghost btn-sm" onclick="window.__app.selectAllPushItems(false)">None</button>
231
+ </div>
232
+ </div>
233
+ <div style="display:flex;flex-direction:column;gap:4px;max-height:300px;overflow-y:auto;margin-bottom:12px">
234
+ ${items.map((i) => {
235
+ const link = linkMap.get(i.id);
236
+ const linkedBadge = link ? `<a href="${escHtml(link.issue_url)}" target="_blank" rel="noopener" style="font-size:10px;color:var(--accent);margin-top:2px;display:block">#${link.issue_number} ↗</a>` : '';
237
+ const updateBtn = link ? `<button class="btn btn-ghost btn-sm" style="font-size:10px;padding:2px 6px" onclick="window.__app.updateGitHubIssue('${escHtml(i.id)}')">Update</button>` : '';
238
+ return `
239
+ <label style="display:flex;align-items:flex-start;gap:10px;padding:8px 10px;background:var(--bg-card2);border:1px solid ${link ? 'var(--accent-muted,#334)' : 'var(--border)'};border-radius:var(--radius);cursor:pointer;transition:var(--transition)">
240
+ <input type="checkbox" class="gh-push-cb" data-item-id="${escHtml(i.id)}" style="margin-top:2px;accent-color:var(--accent)">
241
+ <div style="flex:1;min-width:0">
242
+ <div style="font-size:13px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">${escHtml(i.title || i.id)}</div>
243
+ <div style="font-size:11px;color:var(--text-muted);margin-top:1px">${escHtml(i.id)} · ${escHtml(i.type || 'Task')} · ${escHtml(i.status || 'open')}${linkedBadge}</div>
244
+ </div>
245
+ ${updateBtn}
246
+ </label>`;
247
+ }).join('')}
248
+ </div>
249
+ <button class="btn btn-primary btn-sm" id="gh-push-btn" onclick="window.__app.pushItemsToGitHub()"><span>Push to GitHub</span></button>`;
250
+ }
251
+ catch (err) {
252
+ el.innerHTML = `<div style="color:var(--status-blocked);font-size:13px">Error: ${escHtml(err instanceof Error ? err.message : String(err))}</div>`;
253
+ }
254
+ }
255
+ export function selectAllPushItems(checked) {
256
+ document.querySelectorAll('.gh-push-cb').forEach(cb => { cb.checked = checked; });
257
+ }
258
+ export async function pushItemsToGitHub() {
259
+ const checked = Array.from(document.querySelectorAll('.gh-push-cb:checked'));
260
+ if (checked.length === 0) {
261
+ toast('Select at least one item to push', 'info');
262
+ return;
263
+ }
264
+ const itemIds = checked.map(cb => cb.dataset['itemId'] || '').filter(Boolean);
265
+ const btn = document.getElementById('gh-push-btn');
266
+ if (btn) {
267
+ btn.disabled = true;
268
+ const sp = btn.querySelector('span');
269
+ if (sp)
270
+ sp.textContent = `Pushing ${itemIds.length}…`;
271
+ }
272
+ const resultEl = document.getElementById('github-push-result');
273
+ if (resultEl)
274
+ resultEl.style.display = 'none';
275
+ try {
276
+ const data = await api('POST', `/projects/${state.currentProject.id}/github/push`, { itemIds });
277
+ const pushed = data.pushed || [];
278
+ const errors = data.errors || [];
279
+ toast(`Pushed ${pushed.length} item${pushed.length !== 1 ? 's' : ''}${errors.length ? ' (' + errors.length + ' error' + (errors.length !== 1 ? 's' : '') + ')' : ''}`, errors.length ? 'info' : 'success');
280
+ if (resultEl) {
281
+ resultEl.style.display = '';
282
+ resultEl.innerHTML = `
283
+ <div style="background:var(--bg-card2);border:1px solid var(--border);border-radius:var(--radius);padding:12px">
284
+ <div style="font-size:12px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.5px;margin-bottom:8px">Push Results</div>
285
+ ${pushed.length > 0 ? `<div style="color:var(--status-closed);font-size:13px;margin-bottom:6px">✓ Pushed ${pushed.length}: ${pushed.map((p) => `<a href="${escHtml(p.issueUrl)}" target="_blank" style="color:var(--accent)">#${p.issueNumber}</a>`).join(', ')}</div>` : ''}
286
+ ${errors.length > 0 ? `<div style="color:var(--status-blocked);font-size:13px">✗ ${errors.length} failed: ${errors.map((e) => escHtml(String(e))).join('; ')}</div>` : ''}
287
+ </div>`;
288
+ }
289
+ loadItemsForPush();
290
+ }
291
+ catch (err) {
292
+ toast(`Push failed: ${err instanceof Error ? err.message : String(err)}`, 'error');
293
+ }
294
+ finally {
295
+ if (btn) {
296
+ btn.disabled = false;
297
+ const sp = btn.querySelector('span');
298
+ if (sp)
299
+ sp.textContent = 'Push to GitHub';
300
+ }
301
+ }
302
+ }
303
+ export async function updateGitHubIssue(itemId) {
304
+ try {
305
+ const data = await api('PATCH', `/projects/${state.currentProject.id}/github/push/${encodeURIComponent(itemId)}`);
306
+ toast(`Updated GitHub issue #${data.issueNumber}`, 'success');
307
+ loadItemsForPush();
308
+ }
309
+ catch (err) {
310
+ toast(`Update failed: ${err instanceof Error ? err.message : String(err)}`, 'error');
311
+ }
312
+ }
313
+ export async function importGitHubIssues() {
314
+ const checked = Array.from(document.querySelectorAll('.gh-issue-cb:checked'));
315
+ if (checked.length === 0) {
316
+ toast('Select at least one issue to import', 'info');
317
+ return;
318
+ }
319
+ const issueNumbers = checked.map(cb => parseInt(cb.dataset.number || '0', 10));
320
+ const btn = document.getElementById('gh-import-btn');
321
+ if (btn) {
322
+ btn.disabled = true;
323
+ const sp = btn.querySelector('span');
324
+ if (sp)
325
+ sp.textContent = `Importing ${issueNumbers.length}…`;
326
+ }
327
+ const resultEl = document.getElementById('github-import-result');
328
+ if (resultEl)
329
+ resultEl.style.display = 'none';
330
+ try {
331
+ const data = await api('POST', `/projects/${state.currentProject.id}/github/import`, { issueNumbers });
332
+ const created = data.created || [];
333
+ const errors = data.errors || [];
334
+ toast(`Imported ${created.length} issue${created.length !== 1 ? 's' : ''}${errors.length ? ' (' + errors.length + ' error' + (errors.length !== 1 ? 's' : '') + ')' : ''}`, errors.length ? 'info' : 'success');
335
+ if (resultEl) {
336
+ resultEl.style.display = '';
337
+ resultEl.innerHTML = `
338
+ <div style="background:var(--bg-card2);border:1px solid var(--border);border-radius:var(--radius);padding:12px">
339
+ <div style="font-size:12px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:0.5px;margin-bottom:8px">Import Results</div>
340
+ ${created.length > 0 ? `<div style="color:var(--status-closed);font-size:13px;margin-bottom:6px">✓ Created ${created.length} item${created.length !== 1 ? 's' : ''}: ${created.map((id) => `<span class="mono" style="font-size:11px">${escHtml(String(id))}</span>`).join(', ')}</div>` : ''}
341
+ ${errors.length > 0 ? `<div style="color:var(--status-blocked);font-size:13px">✗ ${errors.length} error${errors.length !== 1 ? 's' : ''}: ${errors.map((e) => escHtml(String(e.message || e))).join('; ')}</div>` : ''}
342
+ </div>`;
343
+ }
344
+ // loadItemsBadge is in projects.ts, import via app bridge
345
+ if (window.__app?.loadItemsBadge)
346
+ window.__app.loadItemsBadge();
347
+ }
348
+ catch (err) {
349
+ toast(`Import failed: ${err instanceof Error ? err.message : String(err)}`, 'error');
350
+ }
351
+ finally {
352
+ if (btn) {
353
+ btn.disabled = false;
354
+ const sp = btn.querySelector('span');
355
+ if (sp)
356
+ sp.textContent = 'Import Selected';
357
+ }
358
+ }
359
+ }
360
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["github.ts"],"names":[],"mappings":"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"}