@starlove/orbit 1.1.11 → 1.2.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/.dockerignore +0 -0
- package/Dockerfile +0 -0
- package/LICENSE +0 -0
- package/README.md +0 -0
- package/SKILL-ORBIT.md +0 -0
- package/build.mjs +11 -5
- package/dist/full/apple-touch-icon.png +0 -0
- package/dist/full/cursors/live_arrow.cur +0 -0
- package/dist/full/cursors/live_link.cur +0 -0
- package/dist/full/cursors/live_move.cur +0 -0
- package/dist/full/cursors/live_select.cur +0 -0
- package/dist/full/cursors/live_unavail.cur +0 -0
- package/dist/full/favicon-32x32.png +0 -0
- package/dist/full/index.html +11 -7
- package/dist/full/js/{app.55b38e12.js → app.ccc442f7.js} +85 -77
- package/dist/full/js/app.ccc442f7.js.map +7 -0
- package/dist/full/orbits-favicon.png +0 -0
- package/dist/full/orbits-logo-bg.png +0 -0
- package/dist/full/orbits-logo.png +0 -0
- package/dist/full/styles.baccc8e3.css +1 -0
- package/dist/full/version.json +2 -2
- package/docs/AGENT_PROTOCOL.md +0 -0
- package/docs/MCP_SETUP.md +0 -0
- package/docs/ORBIT_DISPATCH.md +0 -0
- package/docs/SS-Orbit-Dark.png +0 -0
- package/docs/SS-Orbit-Light.png +0 -0
- package/docs/mcp-client.example.json +0 -0
- package/docs/setup/orbit-init-wizard.md +0 -0
- package/package.json +19 -18
- package/public/apple-touch-icon.png +0 -0
- package/public/cursors/live_arrow.cur +0 -0
- package/public/cursors/live_link.cur +0 -0
- package/public/cursors/live_move.cur +0 -0
- package/public/cursors/live_select.cur +0 -0
- package/public/cursors/live_unavail.cur +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/index.html +9 -5
- package/public/js/actor-labels.js +0 -0
- package/public/js/api.js +0 -0
- package/public/js/app.js +0 -0
- package/public/js/board-menu.js +16 -2
- package/public/js/card-actions.js +0 -0
- package/public/js/config.js +0 -0
- package/public/js/create-card.js +1 -1
- package/public/js/dom.js +0 -0
- package/public/js/drawer.js +1 -1
- package/public/js/format.js +2 -3
- package/public/js/kanban.js +10 -9
- package/public/js/local-backend.js +0 -0
- package/public/js/main.js +0 -0
- package/public/js/modal.js +0 -0
- package/public/js/motion-preference.js +0 -0
- package/public/js/router.js +0 -0
- package/public/js/search.js +1 -1
- package/public/js/settings-tabs.js +0 -0
- package/public/js/settings.js +39 -27
- package/public/js/sse.js +0 -0
- package/public/js/starscape.js +0 -0
- package/public/js/state.js +0 -0
- package/public/js/theme-preference.js +0 -0
- package/public/js/ticket-detail.js +4 -4
- package/public/js/toast.js +0 -0
- package/public/js/transport.js +0 -0
- package/public/js/unread.js +0 -0
- package/public/js/url-routes.js +0 -0
- package/public/orbits-favicon.png +0 -0
- package/public/orbits-logo-bg.png +0 -0
- package/public/orbits-logo.png +0 -0
- package/public/styles.css +498 -445
- package/src/core/agent.js +0 -0
- package/src/core/agents-md.js +0 -0
- package/src/core/attachments.js +0 -0
- package/src/core/auth.js +0 -0
- package/src/core/backups.js +0 -0
- package/src/core/board.js +0 -0
- package/src/core/boards.js +0 -0
- package/src/core/bootstrap.js +0 -0
- package/src/core/css-bundle.js +29 -0
- package/src/core/db.js +0 -0
- package/src/core/delete-board.js +0 -0
- package/src/core/dispatch.js +0 -0
- package/src/core/events.js +0 -0
- package/src/core/http.js +10 -3
- package/src/core/migrate.js +0 -0
- package/src/core/paths.js +0 -0
- package/src/core/provision-repo-board.js +0 -0
- package/src/core/queries.js +0 -0
- package/src/core/registry.js +0 -0
- package/src/core/relations.js +0 -0
- package/src/core/review-verdicts.js +0 -0
- package/src/core/router.js +0 -0
- package/src/core/search.js +0 -0
- package/src/core/seed.js +0 -0
- package/src/core/snapshots.js +0 -0
- package/src/core/states.js +0 -0
- package/src/core/system-picker.js +0 -0
- package/src/core/tickets.js +0 -0
- package/src/core/util.js +0 -0
- package/src/mcp/orbit-client.js +0 -0
- package/src/mcp-server.js +0 -0
- package/src/server.js +0 -0
- package/dist/full/js/app.55b38e12.js.map +0 -7
- package/dist/full/styles.273fc37a.css +0 -6002
package/public/js/board-menu.js
CHANGED
|
@@ -23,11 +23,25 @@ export function closeMenuFlyouts() {
|
|
|
23
23
|
closeBoardFlyout();
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
const boardChipIcon = `
|
|
27
|
+
<svg
|
|
28
|
+
class="topbar-icon"
|
|
29
|
+
width="16"
|
|
30
|
+
height="16"
|
|
31
|
+
viewBox="0 0 24 24"
|
|
32
|
+
fill="none"
|
|
33
|
+
aria-hidden="true"
|
|
34
|
+
>
|
|
35
|
+
<rect x="4" y="4" width="6" height="16" rx="0.75" stroke="currentColor" stroke-width="2" />
|
|
36
|
+
<rect x="14" y="4" width="6" height="16" rx="0.75" stroke="currentColor" stroke-width="2" />
|
|
37
|
+
</svg>`;
|
|
38
|
+
|
|
26
39
|
export function updateTopbarChips() {
|
|
27
40
|
if (!state.data) return;
|
|
28
41
|
const board = (state.data.boards || []).find((b) => b.id === state.boardId);
|
|
29
42
|
if (boardMenuBtn) {
|
|
30
|
-
|
|
43
|
+
const label = board?.name || "Board";
|
|
44
|
+
boardMenuBtn.innerHTML = `${boardChipIcon}<span class="topbar-chip-label">${escapeHtml(label)}</span>`;
|
|
31
45
|
boardMenuBtn.title = board ? `${board.name} — slug: ${board.slug}` : "Choose board";
|
|
32
46
|
}
|
|
33
47
|
}
|
|
@@ -37,7 +51,7 @@ function renderBoardFlyoutInner() {
|
|
|
37
51
|
const rows = boards
|
|
38
52
|
.map(
|
|
39
53
|
(b) => `
|
|
40
|
-
<button type="button" class="menu-flyout-item ${b.id === state.boardId ? "is-current" : ""}" data-pick-board="${escapeHtml(b.id)}" role="menuitem">
|
|
54
|
+
<button type="button" class="menu-flyout-item ${b.id === state.boardId ? "is-current" : ""}" data-variant="menu-item" data-pick-board="${escapeHtml(b.id)}" role="menuitem">
|
|
41
55
|
<span class="menu-flyout-item-title">${escapeHtml(b.name)}</span>
|
|
42
56
|
<span class="menu-flyout-item-meta">${escapeHtml(b.slug)}</span>
|
|
43
57
|
</button>`
|
|
File without changes
|
package/public/js/config.js
CHANGED
|
File without changes
|
package/public/js/create-card.js
CHANGED
|
@@ -86,7 +86,7 @@ function renderCreateForm(preselectedLaneId) {
|
|
|
86
86
|
<label>
|
|
87
87
|
Type
|
|
88
88
|
<select id="createTicketType" name="type" class="select-chevron-field" aria-label="Ticket type">
|
|
89
|
-
<option value="epic">Epic
|
|
89
|
+
<option value="epic">Epic</option>
|
|
90
90
|
<option value="feature">Feature</option>
|
|
91
91
|
<option value="task" selected>Task</option>
|
|
92
92
|
<option value="bug">Bug</option>
|
package/public/js/dom.js
CHANGED
|
File without changes
|
package/public/js/drawer.js
CHANGED
|
@@ -75,7 +75,7 @@ export function renderDrawerShell({ eyebrow, title, titleAttrs, subtitleHtml, ta
|
|
|
75
75
|
// last render (e.g. the inline title editor's click handler) die with the
|
|
76
76
|
// old nodes, instead of stacking on persistent shell elements.
|
|
77
77
|
const extraTitleClass = titleAttrs?.class ? ` ${titleAttrs.class}` : "";
|
|
78
|
-
let titleAttrHtml = ` class="drawer-title-text${extraTitleClass}"`;
|
|
78
|
+
let titleAttrHtml = ` class="drawer-title drawer-title-text${extraTitleClass}"`;
|
|
79
79
|
for (const [key, value] of Object.entries(titleAttrs || {})) {
|
|
80
80
|
if (key === "class") continue;
|
|
81
81
|
titleAttrHtml += ` ${key}="${escapeHtml(String(value))}"`;
|
package/public/js/format.js
CHANGED
|
@@ -389,11 +389,10 @@ export function typeLabel(type) {
|
|
|
389
389
|
return labels[canonicalTicketType(type)] || "Task";
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
-
// Long, hierarchy-aware label for dropdowns where we have the room.
|
|
393
|
-
// pairs older vocabulary so existing terminology still resonates.
|
|
392
|
+
// Long, hierarchy-aware label for dropdowns where we have the room.
|
|
394
393
|
export function typeLabelLong(type) {
|
|
395
394
|
const labels = {
|
|
396
|
-
epic: "Epic
|
|
395
|
+
epic: "Epic",
|
|
397
396
|
feature: "Feature",
|
|
398
397
|
task: "Task",
|
|
399
398
|
bug: "Bug"
|
package/public/js/kanban.js
CHANGED
|
@@ -269,17 +269,18 @@ function renderColumn(column, tickets) {
|
|
|
269
269
|
// are the queue the claim-next MCP tool pulls from. Mark it so humans can
|
|
270
270
|
// instantly see where agent-facing staging lives.
|
|
271
271
|
const isAiReady = column.name === "AI Ready";
|
|
272
|
-
const columnClasses = ["column"];
|
|
272
|
+
const columnClasses = ["column", "lane"];
|
|
273
273
|
if (isAiReady) columnClasses.push("column--ai-ready");
|
|
274
|
+
const accentAttr = isAiReady ? ' data-accent="ai-ready"' : "";
|
|
274
275
|
|
|
275
276
|
return `
|
|
276
|
-
<section class="${columnClasses.join(" ")}" data-state-id="${column.id}" data-state-name="${escapeHtml(column.name)}">
|
|
277
|
-
<div class="column-head">
|
|
278
|
-
<h2${isAiReady ? ' title="Agent staging — cards here are picked up by the claim-next tool when unblocked"' : ""}>
|
|
277
|
+
<section class="${columnClasses.join(" ")}" data-flat${accentAttr} data-state-id="${column.id}" data-state-name="${escapeHtml(column.name)}">
|
|
278
|
+
<div class="column-head lane-head">
|
|
279
|
+
<h2 class="lane-title"${isAiReady ? ' title="Agent staging — cards here are picked up by the claim-next tool when unblocked"' : ""}>
|
|
279
280
|
${isAiReady ? '<span class="agent-dot" aria-hidden="true"></span>' : ""}${escapeHtml(column.name)}
|
|
280
281
|
</h2>
|
|
281
|
-
<div class="column-head-actions">
|
|
282
|
-
<button type="button" class="column-add-btn
|
|
282
|
+
<div class="column-head-actions lane-actions">
|
|
283
|
+
<button type="button" class="column-add-btn" data-variant="plus" data-add-to-state="${escapeHtml(column.id)}" title="New card">+</button>
|
|
283
284
|
<span class="count">${columnTickets.length}</span>
|
|
284
285
|
</div>
|
|
285
286
|
</div>
|
|
@@ -375,7 +376,7 @@ function renderEpicMiniHeader(epic) {
|
|
|
375
376
|
export function renderPriorityPill(priority) {
|
|
376
377
|
const key = priorityKeyFor(priority);
|
|
377
378
|
const label = priorityLabel(priority);
|
|
378
|
-
return `<div class="card-priority-id priority-pill
|
|
379
|
+
return `<div class="card-priority-id priority-pill" data-variant="${escapeHtml(key)}"><span class="card-priority-label">${escapeHtml(label)}</span></div>`;
|
|
379
380
|
}
|
|
380
381
|
|
|
381
382
|
export function renderTypeIcon(type) {
|
|
@@ -434,13 +435,13 @@ function renderCard(ticket, { asEpicChild = false } = {}) {
|
|
|
434
435
|
: `<span class="card-unread-dot has-count" role="status" aria-label="${unreadN} unread updates">${unreadN > 99 ? "99+" : unreadN}</span>`;
|
|
435
436
|
|
|
436
437
|
return `
|
|
437
|
-
<article class="card type-${escapeHtml(canonicalType)} priority-${escapeHtml(priorityKey)}${isExpanded ? " is-expanded" : ""}${asEpicChild ? " is-epic-child" : ""} ${ticket.id === state.selectedTicketId ? "selected" : ""}" draggable="true" data-ticket-id="${ticket.id}">
|
|
438
|
+
<article class="card type-${escapeHtml(canonicalType)} priority-${escapeHtml(priorityKey)}${isExpanded ? " is-expanded" : ""}${asEpicChild ? " is-epic-child" : ""} ${ticket.id === state.selectedTicketId ? "selected" : ""}" data-variant="${escapeHtml(canonicalType)}" draggable="true" data-ticket-id="${ticket.id}">
|
|
438
439
|
${unreadDot}
|
|
439
440
|
<h3>${escapeHtml(ticket.title)}</h3>
|
|
440
441
|
|
|
441
442
|
<div class="card-meta">
|
|
442
443
|
${hasExpandable
|
|
443
|
-
? `<button type="button" class="card-expand-trigger" data-card-toggle aria-expanded="${isExpanded ? "true" : "false"}">${triggerInner}</button>`
|
|
444
|
+
? `<button type="button" class="card-expand-trigger" data-variant="card-accordion" data-card-toggle aria-expanded="${isExpanded ? "true" : "false"}">${triggerInner}</button>`
|
|
444
445
|
: `<div class="card-expand-trigger card-expand-trigger--static">${triggerInner}</div>`}
|
|
445
446
|
</div>
|
|
446
447
|
|
|
File without changes
|
package/public/js/main.js
CHANGED
|
File without changes
|
package/public/js/modal.js
CHANGED
|
File without changes
|
|
File without changes
|
package/public/js/router.js
CHANGED
|
File without changes
|
package/public/js/search.js
CHANGED
|
@@ -32,7 +32,7 @@ export async function runSearch() {
|
|
|
32
32
|
<strong>${escapeHtml(ticketLabel(ticket))}</strong>
|
|
33
33
|
<span class="search-hit-title">${escapeHtml(ticket.title)}</span>
|
|
34
34
|
</span>
|
|
35
|
-
<span class="search-hit-state
|
|
35
|
+
<span class="search-hit-state" data-variant="${escapeHtml(stateClassFor(ticket))}">${escapeHtml(ticket.state_name || "State")}</span>
|
|
36
36
|
</div>
|
|
37
37
|
`
|
|
38
38
|
)
|
|
File without changes
|
package/public/js/settings.js
CHANGED
|
@@ -242,7 +242,7 @@ function renderMcpSetupSection(context) {
|
|
|
242
242
|
<strong data-mcp-output-title>${escapeHtml(client.label)} setup</strong>
|
|
243
243
|
<p class="description" data-mcp-helper>${escapeHtml(client.helper)}</p>
|
|
244
244
|
</div>
|
|
245
|
-
<button type="button"
|
|
245
|
+
<button type="button" data-variant="secondary" data-copy-mcp="config">Copy setup</button>
|
|
246
246
|
</div>
|
|
247
247
|
<div class="mcp-terminal">
|
|
248
248
|
<div class="mcp-terminal-chrome" aria-hidden="true"><span></span><span></span><span></span></div>
|
|
@@ -258,7 +258,7 @@ function renderMcpSetupSection(context) {
|
|
|
258
258
|
<strong>Manual run command</strong>
|
|
259
259
|
<p class="description">Use this only when an app asks you to start the MCP server yourself.</p>
|
|
260
260
|
</div>
|
|
261
|
-
<button type="button"
|
|
261
|
+
<button type="button" data-variant="secondary" data-copy-mcp="command">Copy command</button>
|
|
262
262
|
</div>
|
|
263
263
|
<div class="mcp-terminal">
|
|
264
264
|
<div class="mcp-terminal-chrome" aria-hidden="true"><span></span><span></span><span></span></div>
|
|
@@ -403,11 +403,9 @@ function renderProjectRepositoryTab(context) {
|
|
|
403
403
|
<p class="description">Image exports are embedded in the .orbit.json snapshot and may be much larger.</p>
|
|
404
404
|
` : ""}
|
|
405
405
|
<div class="deployment-actions">
|
|
406
|
-
<button type="button"
|
|
407
|
-
<
|
|
408
|
-
|
|
409
|
-
<span>Import as New Board</span>
|
|
410
|
-
</label>
|
|
406
|
+
<button type="button" data-variant="secondary" id="exportProject">Export</button>
|
|
407
|
+
<input type="file" id="importSnapshotAsNewFile" class="import-file-input" accept=".orbit.json,.json,application/json" />
|
|
408
|
+
<button type="button" data-variant="secondary" id="importSnapshotAsNewButton">Import as New Board</button>
|
|
411
409
|
</div>
|
|
412
410
|
</div>
|
|
413
411
|
|
|
@@ -419,10 +417,8 @@ function renderProjectRepositoryTab(context) {
|
|
|
419
417
|
<input id="replaceImportConfirmInput" autocomplete="off" spellcheck="false" placeholder="${escapeHtml(project.slug || "")}" />
|
|
420
418
|
</label>
|
|
421
419
|
<div class="deployment-actions">
|
|
422
|
-
<
|
|
423
|
-
|
|
424
|
-
<span>Replace Current Board</span>
|
|
425
|
-
</label>
|
|
420
|
+
<input type="file" id="replaceCurrentBoardImportFile" class="import-file-input" accept=".orbit.json,.json,application/json" disabled />
|
|
421
|
+
<button type="button" data-variant="secondary" id="replaceCurrentBoardImportButton" disabled>Replace Current Board</button>
|
|
426
422
|
</div>
|
|
427
423
|
</div>
|
|
428
424
|
|
|
@@ -440,7 +436,7 @@ function renderBoardRenameSection(project) {
|
|
|
440
436
|
<span>Display name</span>
|
|
441
437
|
<input name="name" value="${escapeHtml(project.name || "")}" maxlength="120" required />
|
|
442
438
|
</label>
|
|
443
|
-
<button type="submit">Rename Board</button>
|
|
439
|
+
<button type="submit" data-variant="secondary">Rename Board</button>
|
|
444
440
|
</form>
|
|
445
441
|
</div>
|
|
446
442
|
`;
|
|
@@ -454,9 +450,9 @@ function renderDeleteBoardSection(project) {
|
|
|
454
450
|
<h3>Delete Board</h3>
|
|
455
451
|
<p class="description">Delete this board from Orbit and remove its repo-local Orbit files. Export a snapshot first if you may need this board again.</p>
|
|
456
452
|
<div class="repository-delete-actions">
|
|
457
|
-
<button type="button"
|
|
458
|
-
<button type="button"
|
|
459
|
-
<button type="button"
|
|
453
|
+
<button type="button" data-variant="secondary" id="deleteBoardExportFirst">Export first</button>
|
|
454
|
+
<button type="button" data-variant="ghost" class="danger-button" id="deleteBoardSkipExport">Delete without exporting</button>
|
|
455
|
+
<button type="button" data-variant="ghost" id="deleteBoardCancel">Cancel</button>
|
|
460
456
|
</div>
|
|
461
457
|
</div>
|
|
462
458
|
`;
|
|
@@ -476,8 +472,8 @@ function renderDeleteBoardSection(project) {
|
|
|
476
472
|
<input id="deleteBoardConfirmInput" autocomplete="off" spellcheck="false" placeholder="${slug}" autofocus />
|
|
477
473
|
</label>
|
|
478
474
|
<div class="repository-delete-actions">
|
|
479
|
-
<button type="button" class="danger-button" id="deleteBoardConfirm" disabled>Delete board permanently</button>
|
|
480
|
-
<button type="button"
|
|
475
|
+
<button type="button" data-variant="primary" class="danger-button" id="deleteBoardConfirm" disabled>Delete board permanently</button>
|
|
476
|
+
<button type="button" data-variant="ghost" id="deleteBoardCancel">Cancel</button>
|
|
481
477
|
</div>
|
|
482
478
|
</div>
|
|
483
479
|
`;
|
|
@@ -487,7 +483,7 @@ function renderDeleteBoardSection(project) {
|
|
|
487
483
|
<div class="section repository-danger-zone">
|
|
488
484
|
<h3>Delete Board</h3>
|
|
489
485
|
<p class="description">Remove this board from Orbit and delete its repo-local Orbit files. This cannot be undone without an exported snapshot.</p>
|
|
490
|
-
<button type="button"
|
|
486
|
+
<button type="button" data-variant="ghost" class="danger-button" id="deleteBoardStart">Delete Board</button>
|
|
491
487
|
</div>
|
|
492
488
|
`;
|
|
493
489
|
}
|
|
@@ -536,7 +532,7 @@ function renderProjectLanesTab() {
|
|
|
536
532
|
${renderLaneManager()}
|
|
537
533
|
<form id="laneCreateForm" class="lane-create-form">
|
|
538
534
|
<input name="name" placeholder="New lane name..." required />
|
|
539
|
-
<button type="submit">Add Lane</button>
|
|
535
|
+
<button type="submit" data-variant="primary">Add Lane</button>
|
|
540
536
|
</form>
|
|
541
537
|
</div>
|
|
542
538
|
`;
|
|
@@ -619,7 +615,7 @@ function renderProjectJournalTab(context) {
|
|
|
619
615
|
</select>
|
|
620
616
|
<input name="title" placeholder="Entry title..." required />
|
|
621
617
|
<textarea name="body" placeholder="Decision rationale or lesson: do X instead of Y when working with Z." required></textarea>
|
|
622
|
-
<button type="submit">Add Entry</button>
|
|
618
|
+
<button type="submit" data-variant="primary">Add Entry</button>
|
|
623
619
|
</form>
|
|
624
620
|
</div>
|
|
625
621
|
`;
|
|
@@ -675,7 +671,12 @@ function bindProjectTabHandlers(context, tab) {
|
|
|
675
671
|
});
|
|
676
672
|
};
|
|
677
673
|
|
|
678
|
-
$("#importSnapshotAsNewFile")
|
|
674
|
+
const importSnapshotAsNewFile = $("#importSnapshotAsNewFile");
|
|
675
|
+
$("#importSnapshotAsNewButton")?.addEventListener("click", () => {
|
|
676
|
+
importSnapshotAsNewFile?.click();
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
importSnapshotAsNewFile?.addEventListener("change", async (event) => {
|
|
679
680
|
const input = event.currentTarget;
|
|
680
681
|
const file = input.files?.[0];
|
|
681
682
|
if (!file) return;
|
|
@@ -698,8 +699,16 @@ function bindProjectTabHandlers(context, tab) {
|
|
|
698
699
|
|
|
699
700
|
const replaceImportConfirmInput = $("#replaceImportConfirmInput");
|
|
700
701
|
const replaceCurrentBoardImportFile = $("#replaceCurrentBoardImportFile");
|
|
702
|
+
const replaceCurrentBoardImportButton = $("#replaceCurrentBoardImportButton");
|
|
701
703
|
replaceImportConfirmInput?.addEventListener("input", () => {
|
|
702
|
-
|
|
704
|
+
const disabled = replaceImportConfirmInput.value.trim() !== project.slug;
|
|
705
|
+
if (replaceCurrentBoardImportFile) replaceCurrentBoardImportFile.disabled = disabled;
|
|
706
|
+
if (replaceCurrentBoardImportButton) replaceCurrentBoardImportButton.disabled = disabled;
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
replaceCurrentBoardImportButton?.addEventListener("click", () => {
|
|
710
|
+
if (replaceCurrentBoardImportButton.disabled || replaceCurrentBoardImportFile?.disabled) return;
|
|
711
|
+
replaceCurrentBoardImportFile?.click();
|
|
703
712
|
});
|
|
704
713
|
|
|
705
714
|
replaceCurrentBoardImportFile?.addEventListener("change", async (event) => {
|
|
@@ -1054,7 +1063,8 @@ function renderProjectEntries(entries = []) {
|
|
|
1054
1063
|
<span>${escapeHtml(entry.created_by)} - ${formatDate(entry.created_at)}</span>
|
|
1055
1064
|
<button
|
|
1056
1065
|
type="button"
|
|
1057
|
-
|
|
1066
|
+
data-variant="ghost"
|
|
1067
|
+
class="project-entry-strike"
|
|
1058
1068
|
data-entry-action="toggle-struck"
|
|
1059
1069
|
data-entry-id="${escapeHtml(entry.id)}"
|
|
1060
1070
|
data-struck="${isStruck ? "true" : "false"}"
|
|
@@ -1122,14 +1132,14 @@ function renderLaneManager() {
|
|
|
1122
1132
|
: "";
|
|
1123
1133
|
return `
|
|
1124
1134
|
<div class="lane-row${isAiReady ? " lane-row--locked" : ""}" data-lane-id="${lane.id}">
|
|
1125
|
-
<button type="button" class="lane-icon-btn" data-lane-action="up" ${index === 0 ? "disabled" : ""} title="Move lane left" aria-label="Move lane left">↑</button>
|
|
1126
|
-
<button type="button" class="lane-icon-btn" data-lane-action="down" ${index === lanes.length - 1 ? "disabled" : ""} title="Move lane right" aria-label="Move lane right">↓</button>
|
|
1135
|
+
<button type="button" data-variant="ghost" class="settings-lane-icon-btn" data-lane-action="up" ${index === 0 ? "disabled" : ""} title="Move lane left" aria-label="Move lane left">↑</button>
|
|
1136
|
+
<button type="button" data-variant="ghost" class="settings-lane-icon-btn" data-lane-action="down" ${index === lanes.length - 1 ? "disabled" : ""} title="Move lane right" aria-label="Move lane right">↓</button>
|
|
1127
1137
|
<input name="name" value="${escapeHtml(lane.name)}" aria-label="Lane name" ${isAiReady ? `readonly title="${escapeHtml(nameTitle)}"` : ""} />
|
|
1128
|
-
<button type="button" class="lane-new-toggle ${lane.is_default ? "is-on" : ""}" data-lane-action="toggle-default" aria-pressed="${lane.is_default ? "true" : "false"}" title="${lane.is_default ? "Default lane for new cards — click another lane to move it" : "Make this the default lane for new cards"}" aria-label="Default lane for new cards">
|
|
1138
|
+
<button type="button" data-variant="${lane.is_default ? "secondary" : "ghost"}" class="settings-lane-new-toggle ${lane.is_default ? "is-on" : ""}" data-lane-action="toggle-default" aria-pressed="${lane.is_default ? "true" : "false"}" title="${lane.is_default ? "Default lane for new cards — click another lane to move it" : "Make this the default lane for new cards"}" aria-label="Default lane for new cards">
|
|
1129
1139
|
<span class="lane-new-sun" aria-hidden="true"></span>
|
|
1130
1140
|
<span class="lane-new-label">New</span>
|
|
1131
1141
|
</button>
|
|
1132
|
-
<button type="button" class="lane-delete-btn" data-lane-action="delete" ${deleteDisabled(lane, counts, aiEnabled) ? "disabled" : ""} title="${deleteTitle(lane, counts, aiEnabled)}" aria-label="Delete lane">×</button>
|
|
1142
|
+
<button type="button" data-variant="ghost" class="settings-lane-delete-btn danger-button" data-lane-action="delete" ${deleteDisabled(lane, counts, aiEnabled) ? "disabled" : ""} title="${deleteTitle(lane, counts, aiEnabled)}" aria-label="Delete lane">×</button>
|
|
1133
1143
|
</div>
|
|
1134
1144
|
`;
|
|
1135
1145
|
})
|
|
@@ -1158,9 +1168,11 @@ async function handleLaneAction(button) {
|
|
|
1158
1168
|
if (wasOn) return;
|
|
1159
1169
|
drawerInner.querySelectorAll('[data-lane-action="toggle-default"]').forEach((btn) => {
|
|
1160
1170
|
btn.setAttribute("aria-pressed", "false");
|
|
1171
|
+
btn.setAttribute("data-variant", "ghost");
|
|
1161
1172
|
btn.classList.remove("is-on");
|
|
1162
1173
|
});
|
|
1163
1174
|
button.setAttribute("aria-pressed", "true");
|
|
1175
|
+
button.setAttribute("data-variant", "secondary");
|
|
1164
1176
|
button.classList.add("is-on");
|
|
1165
1177
|
await updateLane(row, { silent: true });
|
|
1166
1178
|
toast.success("Default lane updated");
|
package/public/js/sse.js
CHANGED
|
File without changes
|
package/public/js/starscape.js
CHANGED
|
File without changes
|
package/public/js/state.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -480,9 +480,9 @@ export async function renderDetail(options = {}) {
|
|
|
480
480
|
const detailSubtitleHtml = `
|
|
481
481
|
<span class="ticket-number">${escapeHtml(ticketLabel(ticket))}</span>
|
|
482
482
|
<div class="detail-meta-badge-row" aria-label="Ticket metadata controls">
|
|
483
|
-
<select class="detail-meta-badge detail-state-badge
|
|
483
|
+
<select class="detail-meta-badge detail-state-badge meta-select" data-variant="${escapeHtml(stateClass)}" data-meta-field="state_id" aria-label="Ticket state">${stateOptions}</select>
|
|
484
484
|
<select class="detail-meta-badge detail-type-badge type-pill-${escapeHtml(detailCanonicalType)} meta-select" data-meta-field="type" aria-label="Ticket type">${typeOptions}</select>
|
|
485
|
-
<select class="detail-meta-badge detail-priority-badge priority-pill
|
|
485
|
+
<select class="detail-meta-badge detail-priority-badge priority-pill meta-select" data-variant="${escapeHtml(priorityKey)}" data-meta-field="priority" aria-label="Ticket priority">${priorityOptions}</select>
|
|
486
486
|
</div>
|
|
487
487
|
`;
|
|
488
488
|
|
|
@@ -1110,7 +1110,7 @@ export function renderDetailCard(ticket, options = {}) {
|
|
|
1110
1110
|
? `<span class="card-unread-dot" role="status" aria-label="1 unread update"></span>`
|
|
1111
1111
|
: `<span class="card-unread-dot has-count" role="status" aria-label="${unreadN} unread updates">${unreadN > 99 ? "99+" : unreadN}</span>`;
|
|
1112
1112
|
return `
|
|
1113
|
-
<article class="card card--detail type-${escapeHtml(canonicalType)} priority-${escapeHtml(priorityKey)}"${options.disableOpen ? "" : ` data-open-ticket="${escapeHtml(ticket.id)}"`}>
|
|
1113
|
+
<article class="card card--detail type-${escapeHtml(canonicalType)} priority-${escapeHtml(priorityKey)}" data-variant="${escapeHtml(canonicalType)}"${options.disableOpen ? "" : ` data-open-ticket="${escapeHtml(ticket.id)}"`}>
|
|
1114
1114
|
${unreadDot}
|
|
1115
1115
|
${detachBtn}
|
|
1116
1116
|
${eyebrow}
|
|
@@ -1122,7 +1122,7 @@ export function renderDetailCard(ticket, options = {}) {
|
|
|
1122
1122
|
${renderTypeIcon(ticket.type)}
|
|
1123
1123
|
<span class="card-type-label">${escapeHtml(typeText)}</span>
|
|
1124
1124
|
</div>
|
|
1125
|
-
<span class="detail-card-state
|
|
1125
|
+
<span class="detail-card-state" data-variant="${escapeHtml(stateClass)}">${escapeHtml(ticket.state_name || "State")}</span>
|
|
1126
1126
|
${state.showPriority ? renderPriorityPill(ticket.priority) : ""}
|
|
1127
1127
|
</div>
|
|
1128
1128
|
</div>
|
package/public/js/toast.js
CHANGED
|
File without changes
|
package/public/js/transport.js
CHANGED
|
File without changes
|
package/public/js/unread.js
CHANGED
|
File without changes
|
package/public/js/url-routes.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/public/orbits-logo.png
CHANGED
|
File without changes
|