@nanocollective/roster 0.1.0-alpha.14 → 0.1.0-alpha.15
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
|
@@ -141,5 +141,10 @@
|
|
|
141
141
|
.qfield span{font:600 12.5px var(--sans)}
|
|
142
142
|
.qfield input{background:var(--bg-elev);border:1px solid var(--border-strong);color:var(--ink);
|
|
143
143
|
border-radius:var(--r);padding:8px 10px;font:13px var(--sans)}
|
|
144
|
-
.
|
|
145
|
-
|
|
144
|
+
.modes{display:inline-flex;gap:2px;padding:3px;margin:0 0 14px;background:var(--surface-2);
|
|
145
|
+
border-radius:var(--r);flex-wrap:wrap}
|
|
146
|
+
.mode{border:0;background:none;color:var(--ink-dim);font:600 12.5px var(--sans);padding:6px 12px;
|
|
147
|
+
border-radius:calc(var(--r) - 2px);cursor:pointer}
|
|
148
|
+
.mode:hover{color:var(--ink)}
|
|
149
|
+
.mode.on{background:var(--bg-elev);color:var(--ink);box-shadow:var(--shadow-sm)}
|
|
150
|
+
.modes + div > .paste{border-top:0;margin-top:0;padding-top:0}
|
|
@@ -492,7 +492,7 @@ const BUSINESS_QUESTIONS = [
|
|
|
492
492
|
|
|
493
493
|
/** The business, as five questions in plain fields, written out as org/business.md. */
|
|
494
494
|
function businessForm(onSaved) {
|
|
495
|
-
const
|
|
495
|
+
const form = el("div");
|
|
496
496
|
const path = opsName() + "/org/business.md";
|
|
497
497
|
const fields = BUSINESS_QUESTIONS.map(([id, label, , required]) => {
|
|
498
498
|
const input = id === "line" ? el("input", { type: "text" }) : el("textarea", { className: "pastebox", rows: 3 });
|
|
@@ -504,7 +504,7 @@ function businessForm(onSaved) {
|
|
|
504
504
|
});
|
|
505
505
|
const save = el("button", { className: "btn primary", textContent: "Save" });
|
|
506
506
|
const out = el("div");
|
|
507
|
-
|
|
507
|
+
form.append(...fields.map((f) => f.wrap), el("div", { className: "row" }, [save]), out);
|
|
508
508
|
|
|
509
509
|
save.onclick = async () => {
|
|
510
510
|
const missing = fields.find((f, i) => BUSINESS_QUESTIONS[i][3] && !String(f.input.value ?? "").trim());
|
|
@@ -524,20 +524,19 @@ function businessForm(onSaved) {
|
|
|
524
524
|
await saveAndSay(save, out, path, text, "portal: write org/business.md", onSaved);
|
|
525
525
|
};
|
|
526
526
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
paste({ kind: "discover", title: "", onSaved: () => (onSaved(), recheck()) }),
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
return box;
|
|
527
|
+
return modes([
|
|
528
|
+
{ label: "Answer questions", node: form },
|
|
529
|
+
{
|
|
530
|
+
label: "Let an AI interview you",
|
|
531
|
+
node: paste({ kind: "discover", title: "", onSaved: () => (onSaved(), recheck()) }),
|
|
532
|
+
},
|
|
533
|
+
rawMode(path, onSaved),
|
|
534
|
+
]);
|
|
536
535
|
}
|
|
537
536
|
|
|
538
537
|
/** This month's priorities, as three lines and an out-of-scope list. */
|
|
539
538
|
function prioritiesForm(onSaved) {
|
|
540
|
-
const
|
|
539
|
+
const form = el("div");
|
|
541
540
|
const path = opsName() + "/org/priorities.md";
|
|
542
541
|
const ranks = [1, 2, 3].map((i) => {
|
|
543
542
|
const input = el("input", { type: "text", placeholder: i === 1 ? "e.g. Tasks can be ticked off and removed" : "" });
|
|
@@ -546,7 +545,7 @@ function prioritiesForm(onSaved) {
|
|
|
546
545
|
const scope = el("textarea", { className: "pastebox", rows: 3, placeholder: "One per line" });
|
|
547
546
|
const save = el("button", { className: "btn primary", textContent: "Save" });
|
|
548
547
|
const out = el("div");
|
|
549
|
-
|
|
548
|
+
form.append(
|
|
550
549
|
...ranks.map((r) => r.wrap),
|
|
551
550
|
el("label", { className: "qfield" }, [el("span", { textContent: "Out of scope this month (optional)" }), scope]),
|
|
552
551
|
el("div", { className: "row" }, [save]),
|
|
@@ -567,8 +566,7 @@ function prioritiesForm(onSaved) {
|
|
|
567
566
|
(outs.length ? "\n### Out of scope this month\n\n" + outs.map((t) => `- ${t}`).join("\n") + "\n" : "");
|
|
568
567
|
await saveAndSay(save, out, path, text, "portal: write org/priorities.md", onSaved);
|
|
569
568
|
};
|
|
570
|
-
|
|
571
|
-
return box;
|
|
569
|
+
return modes([{ label: "Fill in", node: form }, rawMode(path, onSaved)]);
|
|
572
570
|
}
|
|
573
571
|
|
|
574
572
|
async function saveAndSay(btn, out, path, text, message, onSaved) {
|
|
@@ -594,18 +592,18 @@ async function saveAndSay(btn, out, path, text, message, onSaved) {
|
|
|
594
592
|
}
|
|
595
593
|
|
|
596
594
|
/** The file itself, for editing what is already there rather than starting again. */
|
|
597
|
-
function
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
595
|
+
function rawMode(path, onSaved) {
|
|
596
|
+
const node = el("div");
|
|
597
|
+
const ta = el("textarea", { className: "pastebox" });
|
|
598
|
+
ta.rows = 12;
|
|
599
|
+
const save = el("button", { className: "btn primary", textContent: "Save" });
|
|
600
|
+
const out = el("div");
|
|
601
|
+
node.append(ta, el("div", { className: "row" }, [save]), out);
|
|
602
|
+
ta.addEventListener("input", () => grow(ta));
|
|
603
|
+
save.onclick = () =>
|
|
604
|
+
saveAndSay(save, out, path, ta.value, "portal: edit " + path.split("/").slice(1).join("/"), onSaved);
|
|
605
|
+
// Read when first shown, so it shows the file as it is then, not as it was at page load.
|
|
606
|
+
const load = () =>
|
|
609
607
|
// Not getFile: an absent file answers 404 with a message, and that is not what to edit.
|
|
610
608
|
fetch(fileUrl(path), { cache: "no-store" })
|
|
611
609
|
.then((r) => (r.ok ? r.text() : ""))
|
|
@@ -613,10 +611,28 @@ function changeRaw(path, onSaved) {
|
|
|
613
611
|
ta.value = text;
|
|
614
612
|
grow(ta);
|
|
615
613
|
});
|
|
616
|
-
|
|
617
|
-
|
|
614
|
+
return { label: "Edit the file", node, onShow: load };
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/** Ways to do one step, as a switcher across the top: one shown at a time. */
|
|
618
|
+
function modes(list) {
|
|
619
|
+
const box = el("div");
|
|
620
|
+
const bar = el("div", { className: "modes" });
|
|
621
|
+
const panes = el("div");
|
|
622
|
+
const buttons = list.map((m, i) => {
|
|
623
|
+
const b = el("button", { className: "mode", textContent: m.label });
|
|
624
|
+
b.onclick = () => show(i);
|
|
625
|
+
return b;
|
|
618
626
|
});
|
|
619
|
-
|
|
627
|
+
bar.append(...buttons);
|
|
628
|
+
box.append(bar, panes);
|
|
629
|
+
function show(i) {
|
|
630
|
+
buttons.forEach((b, j) => b.classList.toggle("on", i === j));
|
|
631
|
+
panes.replaceChildren(list[i].node);
|
|
632
|
+
list[i].onShow?.();
|
|
633
|
+
}
|
|
634
|
+
show(0);
|
|
635
|
+
return box;
|
|
620
636
|
}
|
|
621
637
|
|
|
622
638
|
/** The ops repo's directory name, which is what every workspace-relative path starts with. */
|