133 lines
5.1 KiB
JavaScript
133 lines
5.1 KiB
JavaScript
import { del, get, put } from "./api.js";
|
|
import { errorText, h, replace, showAlert, showConfirm } from "./dom.js";
|
|
import { on, state } from "./state.js";
|
|
const kinds = [
|
|
{ key: "questions", label: "Questions" },
|
|
{ key: "reports", label: "Turn summaries" },
|
|
{ key: "errors", label: "Session errors" },
|
|
{ key: "rate_limits", label: "Rate limits" },
|
|
];
|
|
let notesProject = "";
|
|
export function mountSettings(root) {
|
|
const device = h("div", { class: "push-device" });
|
|
const prefs = h("fieldset", { class: "push-prefs" });
|
|
const renderPrefs = () => {
|
|
const me = state.me;
|
|
if (!me) {
|
|
replace(prefs);
|
|
return;
|
|
}
|
|
replace(prefs, h("legend", {}, "Notify me about"), ...kinds.map(({ key, label }) => {
|
|
const box = h("input", { type: "checkbox", checked: me.notification_prefs[key] });
|
|
box.onchange = async () => {
|
|
try {
|
|
state.me = await put("/api/me/notifications", { body: { ...me.notification_prefs, [key]: box.checked } });
|
|
}
|
|
catch (err) {
|
|
void showAlert(errorText(err));
|
|
}
|
|
renderPrefs();
|
|
};
|
|
return h("label", {}, box, " ", label);
|
|
}));
|
|
};
|
|
const renderDevice = () => {
|
|
if (!("Notification" in window)) {
|
|
replace(device, h("p", { class: "hint" }, "This browser doesn't support notifications."));
|
|
return;
|
|
}
|
|
if (Notification.permission === "denied") {
|
|
replace(device, h("p", { class: "hint" }, "Notifications are blocked for this site in the browser's settings."));
|
|
return;
|
|
}
|
|
if (Notification.permission === "granted") {
|
|
replace(device, h("p", {}, "This browser shows notifications while a byre page is open."));
|
|
return;
|
|
}
|
|
const button = h("button", {}, "Turn on for this browser");
|
|
button.onclick = async () => {
|
|
button.disabled = true;
|
|
await Notification.requestPermission();
|
|
renderDevice();
|
|
};
|
|
replace(device, h("p", {}, "This browser doesn't show notifications."), button);
|
|
};
|
|
const notes = h("div", { class: "lead-notes" });
|
|
let list;
|
|
let loads = 0;
|
|
const noteItem = (note) => {
|
|
const remove = h("button", {}, "delete");
|
|
remove.onclick = async () => {
|
|
if (!(await showConfirm([h("p", {}, "Delete this note? Your lead stops applying it."), h("p", {}, note.text)], "Delete", true, remove))) {
|
|
return;
|
|
}
|
|
try {
|
|
await del("/api/me/lead/notes/{noteId}", { path: { noteId: note.id } });
|
|
}
|
|
catch (err) {
|
|
void showAlert(errorText(err));
|
|
}
|
|
};
|
|
return h("li", {}, h("span", {}, note.text), remove);
|
|
};
|
|
const renderNotes = () => {
|
|
if (!list) {
|
|
return;
|
|
}
|
|
if (list.length === 0) {
|
|
replace(notes, h("p", { class: "hint" }, "Your lead hasn't noted anything about how you work yet."));
|
|
return;
|
|
}
|
|
const all = list;
|
|
const scoped = (id) => all.filter((note) => (note.project_id ?? "") === id);
|
|
const groups = [{ id: "", name: "Every project" }, ...state.projects.map((p) => ({ id: p.id, name: p.name }))];
|
|
if (!groups.some((g) => g.id === notesProject)) {
|
|
notesProject = "";
|
|
}
|
|
const picker = h("select", { title: "Which notes to show" }, ...groups.map((g) => h("option", { value: g.id }, `${g.name} (${scoped(g.id).length})`)));
|
|
picker.value = notesProject;
|
|
picker.onchange = () => {
|
|
notesProject = picker.value;
|
|
renderNotes();
|
|
};
|
|
const shown = scoped(notesProject);
|
|
replace(notes, picker, shown.length === 0 ? h("p", { class: "hint" }, "No notes here yet.") : h("ul", {}, ...shown.map(noteItem)));
|
|
};
|
|
const loadNotes = async () => {
|
|
const n = ++loads;
|
|
let loaded;
|
|
try {
|
|
loaded = await get("/api/me/lead/notes");
|
|
}
|
|
catch (err) {
|
|
replace(notes, h("p", { class: "hint" }, errorText(err)));
|
|
return;
|
|
}
|
|
if (n !== loads) {
|
|
return;
|
|
}
|
|
list = loaded;
|
|
renderNotes();
|
|
};
|
|
replace(root, h("div", { class: "settings-view" }, h("h2", {}, "Notifications"), device, prefs, h("h2", {}, "What your lead has learned"), h("p", { class: "hint" }, "Your lead notes your priorities and preferences as it works with you, and starts every session with them."), notes));
|
|
const offs = [
|
|
on("me", renderPrefs),
|
|
on("projects", renderNotes),
|
|
on("event", (detail) => {
|
|
const ev = detail;
|
|
if (ev.kind === "lead.note_saved" || ev.kind === "lead.note_deleted") {
|
|
void loadNotes();
|
|
}
|
|
}),
|
|
];
|
|
renderPrefs();
|
|
renderDevice();
|
|
void loadNotes();
|
|
return () => {
|
|
loads++;
|
|
for (const off of offs) {
|
|
off();
|
|
}
|
|
};
|
|
}
|
|
//# sourceMappingURL=settings.js.map
|