@nanocollective/roster 0.1.0-alpha.47 → 0.1.0-alpha.49

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanocollective/roster",
3
- "version": "0.1.0-alpha.47",
3
+ "version": "0.1.0-alpha.49",
4
4
  "description": "An agent-run org, powered by GitHub. Scaffold AI staff members whose brain is a repo.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -60,27 +60,16 @@
60
60
  .homerunwhat{grid-area:what}.homerunlog{grid-area:log}
61
61
  }
62
62
 
63
- .homerow{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;padding:8px 2px;
64
- border-bottom:1px solid var(--line);font-size:13px}
65
- .homerow .homeopen{font-weight:500;font-size:13.5px}
66
- .homelist{display:grid;grid-template-columns:auto 1fr;align-items:start;gap:4px 12px}
67
- .homelist > .chip{margin-top:2px}
68
- .homelist .meta{margin-top:3px}
69
- .homeclick{cursor:pointer;border-radius:8px;padding-left:8px;padding-right:8px;margin:0 -8px}
70
- .homeclick:hover{background:var(--hover)}
71
- .homeclick:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
72
- .homeclosed{display:grid;grid-template-columns:1fr auto;align-items:center;gap:4px 14px}
73
- .homeclosed .meta{margin-top:3px}
74
63
  .homerest{margin-top:26px}
75
- .homecard.gone,.homerow.gone{opacity:0;transform:translateX(12px);
64
+ .homecard.gone,.homeline.gone{opacity:0;transform:translateX(12px);
76
65
  transition:opacity .2s var(--ease),transform .2s var(--ease)}
77
66
 
78
67
  /* Activity you have not seen, as Trackers marks it: a blue edge and a bold title. Opening the
79
68
  thread marks it read, here and on GitHub. */
80
69
  .homecard.unread{box-shadow:inset 3px 0 0 var(--blue)}
81
- .homerow.unread{box-shadow:inset 3px 0 0 var(--blue);background:color-mix(in srgb,var(--blue) 6%,transparent)}
82
- .unread .homeopen{font-weight:700}
83
- .unread .homeopen::before{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;
70
+ .homeline.unread{box-shadow:inset 3px 0 0 var(--blue);margin:0 -16px;padding-left:13px;padding-right:16px}
71
+ .unread .homeopen,.unread .homerowtitle{font-weight:700}
72
+ .unread .homeopen::before,.unread .homerowtitle::before{content:"";display:inline-block;width:7px;height:7px;border-radius:50%;
84
73
  background:var(--blue);margin:0 7px 1px 0;vertical-align:middle}
85
74
 
86
75
  .homereports{display:flex;flex-direction:column;gap:14px;padding:14px 16px}
@@ -93,3 +82,12 @@
93
82
  @media (max-width:640px){
94
83
  .homehead{flex-wrap:wrap}
95
84
  }
85
+
86
+ /* Rows in a list card (Unread, Your requests, Closed today) that open a thread. */
87
+ .homeline{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:12px;
88
+ padding:12px 0;font-size:13.5px;cursor:pointer}
89
+ .homeline + .homeline{border-top:1px solid var(--line)}
90
+ .homeline .homestate{min-width:64px;justify-content:center}
91
+ .homeline:hover .homerowtitle{text-decoration:underline}
92
+ .homeline:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
93
+ .homerowtitle{font-weight:600;color:var(--ink)}
@@ -75,7 +75,7 @@ export function viewHome(m) {
75
75
 
76
76
  if (h.unread.length) {
77
77
  page.append(section("Unread", h.unread.length));
78
- for (const e of h.unread) page.append(unreadRow(e));
78
+ page.append(listBox(h.unread.map(unreadRow)));
79
79
  }
80
80
 
81
81
  page.append(section("Working now"));
@@ -83,12 +83,12 @@ export function viewHome(m) {
83
83
 
84
84
  if (h.requests.length) {
85
85
  page.append(section("Your requests", h.requests.length));
86
- for (const e of h.requests) page.append(requestRow(e));
86
+ page.append(listBox(h.requests.map(requestRow)));
87
87
  }
88
88
 
89
89
  if (h.closedToday.length) {
90
90
  page.append(section("Closed today", h.closedToday.length));
91
- for (const e of h.closedToday) page.append(closedRow(e));
91
+ page.append(listBox(h.closedToday.map(closedRow)));
92
92
  }
93
93
 
94
94
  page.append(rest(h));
@@ -247,7 +247,7 @@ async function act(note, actions, payload, ok) {
247
247
  await post(payload);
248
248
  note.textContent = ok;
249
249
  // Done is done: the card goes now, rather than when GitHub next answers.
250
- const card = actions.closest?.(".homecard, .homerow");
250
+ const card = actions.closest?.(".homecard, .homeline");
251
251
  if (card) {
252
252
  card.classList.add("gone");
253
253
  setTimeout(() => card.remove(), 220);
@@ -373,7 +373,39 @@ function poll() {
373
373
 
374
374
  /* ------------------------------ your requests ---------------------------- */
375
375
 
376
- const STATUS = { waiting: "Waiting", working: "Being worked on", answered: "Answered" };
376
+ /** A card of rows, laid out like Working now. */
377
+ function listBox(rows) {
378
+ return el("div", { className: "card homeworking" }, rows);
379
+ }
380
+
381
+ /**
382
+ * One row in a list card: a status chip, the title with one line under it, and a button on the
383
+ * right. The whole row opens the thread, except the button.
384
+ */
385
+ function listRow(e, { chip, tone = "", sub, action = null }) {
386
+ const row = el(
387
+ "div",
388
+ { className: "homeline homeclick" + (e.item.unread ? " unread" : ""), tabIndex: 0, role: "button" },
389
+ [
390
+ el("span", { className: "chip homestate " + tone, textContent: chip }),
391
+ el("div", { className: "homerunwhat" }, [
392
+ el("div", { className: "homerowtitle", textContent: e.item.title }),
393
+ el("div", { className: "homerunsub", textContent: `${whereOf(e)} · ${sub}` }),
394
+ ]),
395
+ el("div", { className: "homerunlog" }, action ? [action] : []),
396
+ ],
397
+ );
398
+ row.onclick = (ev) => {
399
+ if (!ev.target.closest("button, a")) openThread(e.item);
400
+ };
401
+ row.onkeydown = (ev) => {
402
+ if (ev.target === row && (ev.key === "Enter" || ev.key === " ")) {
403
+ ev.preventDefault();
404
+ openThread(e.item);
405
+ }
406
+ };
407
+ return row;
408
+ }
377
409
 
378
410
  const WHY = {
379
411
  status: "Status",
@@ -386,58 +418,34 @@ const WHY = {
386
418
 
387
419
  /** Something on a staff member's tracker, or elsewhere, with activity you have not seen. */
388
420
  function unreadRow(e) {
389
- return clickable(e.item, "homerow homelist", [
390
- el("span", { className: "chip", textContent: WHY[e.why] ?? "Issue" }),
391
- el("div", {}, [
392
- openLink(e.item),
393
- el("div", { className: "meta", textContent: whereOf(e) + " · " + ago(e.item.updatedAt) }),
394
- ]),
395
- ]);
421
+ return listRow(e, {
422
+ chip: WHY[e.why] ?? "Issue",
423
+ tone: "cool",
424
+ sub: ago(e.item.updatedAt),
425
+ });
396
426
  }
397
427
 
398
- function requestRow(e) {
399
- return clickable(e.item, "homerow homelist", [
400
- el("span", {
401
- className: "chip " + (e.status === "answered" ? "cool" : e.status === "working" ? "warm" : ""),
402
- textContent: STATUS[e.status],
403
- }),
404
- el("div", {}, [
405
- openLink(e.item),
406
- el("div", { className: "meta", textContent: whereOf(e) + " · " + ago(e.item.updatedAt) }),
407
- ]),
408
- ]);
409
- }
428
+ const STATUS = { waiting: "Waiting", working: "Working", answered: "Answered" };
410
429
 
411
- /** A row that opens its thread from anywhere on it, except a button inside it. */
412
- function clickable(item, className, kids) {
413
- const row = el(
414
- "div",
415
- { className: className + " homeclick" + (item.unread ? " unread" : ""), tabIndex: 0, role: "button" },
416
- kids,
417
- );
418
- row.onclick = (ev) => {
419
- if (!ev.target.closest("button, a")) openThread(item);
420
- };
421
- row.onkeydown = (ev) => {
422
- if (ev.target === row && (ev.key === "Enter" || ev.key === " ")) {
423
- ev.preventDefault();
424
- openThread(item);
425
- }
426
- };
427
- return row;
430
+ function requestRow(e) {
431
+ return listRow(e, {
432
+ chip: STATUS[e.status],
433
+ tone: e.status === "answered" ? "cool" : e.status === "working" ? "ok" : "",
434
+ sub: ago(e.item.updatedAt),
435
+ });
428
436
  }
429
437
 
430
438
  function closedRow(e) {
431
439
  const note = el("span", { className: "meta" });
432
- const reopen = button("Reopen", false, () => act(note, row, { action: "reopen", repo: e.item.repo, number: e.item.number }, "Reopened."));
433
- const row = clickable(e.item, "homerow homeclosed", [
434
- el("div", {}, [
435
- openLink(e.item),
436
- el("div", { className: "meta", textContent: whereOf(e) + " · " + (e.reason || "No reason given.") }),
437
- ]),
438
- el("div", { className: "row" }, [note, reopen]),
439
- ]);
440
- return row;
440
+ const reopen = button("Reopen", false, () =>
441
+ act(note, holder, { action: "reopen", repo: e.item.repo, number: e.item.number }, "Reopened."),
442
+ );
443
+ const holder = el("div", { className: "row" }, [note, reopen]);
444
+ return listRow(e, {
445
+ chip: "Closed",
446
+ sub: e.reason || "No reason given.",
447
+ action: holder,
448
+ });
441
449
  }
442
450
 
443
451
  /* --------------------------------- rest --------------------------------- */