Assignment Template
<%* // =================================== // ๐ฟ STUDY NOOK ASSIGNMENT TEMPLATE // ===================================
// 1. Ask for the assignment name const titleInput = await tp.system.prompt( "Assignment name" );
if (!titleInput || !titleInput.trim()) { new Notice("Assignment creation cancelled."); return; }
const title = titleInput.trim();
// 2. Find existing class notes const classFiles = app.vault.getMarkdownFiles() .filter(f โฅ f.path.startsWith("study nook/School/Classes/") ) .sort((a, b) โฅ a.basename.localeCompare(b.basename) );
if (classFiles.length === 0) { new Notice("No class notes found."); return; }
// 3. Choose the class const selectedClass = await tp.system.suggester( f โฅ f.basename, classFiles );
if (!selectedClass) return;
// Preserve the correct class link const classPath = selectedClass.path.replace(/.md$/, ""); const className = selectedClass.basename;
// 4. Ask for due date (MM/DD/YY) const dateInput = await tp.system.prompt( "Due date (MM/DD/YY)" );
if (!dateInput) return;
const parsedDate = window.moment( dateInput, "MM/DD/YY", true );
if (!parsedDate.isValid()) { new Notice("Please enter a valid date (MM/DD/YY)."); return; }
const due = parsedDate.format("YYYY-MM-DD");
// 5. Choose priority const priority = await tp.system.suggester( ["High", "Medium", "Low"], ["High", "Medium", "Low"] );
if (!priority) return;
// =================================== // โณ 6. CHOOSE ESTIMATED WORK TIME // ===================================
const timeLabels = [ "๐ฑ 15 minutes", "๐ท 30 minutes", "โ 45 minutes", "๐ 1 hour", "๐ธ 1.5 hours", "๐ 2 hours", "๐ 2.5 hours", "๐ฏ๏ธ 3 hours", "โ๏ธ Custom estimate" ];
const timeValues = [ 15, 30, 45, 60, 90, 120, 150, 180, "custom" ];
let estimateMinutes = await tp.system.suggester( timeLabels, timeValues, false, "โณ How long will this assignment take?" );
if ( estimateMinutes === null || estimateMinutes === undefined ) { return; }
// Allow a custom estimate if (estimateMinutes === "custom") { const customInput = await tp.system.prompt( "Enter estimated time in minutes", "60" );
if (customInput === null) return;
const trimmed = customInput.trim();
if (!/^\d+$/.test(trimmed)) { new Notice("Please enter a whole number of minutes."); return; }
estimateMinutes = Number(trimmed); }
if ( !Number.isSafeInteger(estimateMinutes) || estimateMinutes โค 0 ) { new Notice("Please enter a valid positive time estimate."); return; }
// =================================== // ๐ชท 7. ASSIGNMENT STATUS STATION // ===================================
// This code is written INTO the new assignment. // It runs later through DataviewJS.
const statusStation = [
"dataviewjs", "// ๐ชท STUDY NOOK STATUS STATION", "", "const filePath = dv.current().file.path;", "const options = [", ' { name: "Not started", emoji: "๐ฑ" },', ' { name: "In progress", emoji: "โ" },', ' { name: "Done", emoji: "๐ธ" }', "];", "", "let currentStatus = String(", ' dv.current().status ?? "Not started"', ");", "", "const station = dv.container.createDiv();", 'station.style.margin = "16px 0 28px";', "", 'station.createEl("p", {', ' text: "How is this assignment coming along?"', "});", "", "const buttons = station.createDiv();", 'buttons.style.display = "flex";', 'buttons.style.flexWrap = "wrap";', 'buttons.style.gap = "10px";', "", "const controls = [];", "", "function refreshButtons() {", " for (const control of controls) {", " const selected = control.name === currentStatus;", "", " control.button.style.background = selected", ' ? "var(--interactive-accent)"', ' : "var(--background-secondary)";', "", " control.button.style.color = selected", ' ? "var(--text-on-accent)"', ' : "var(--text-normal)";', "", " control.button.style.border = selected", ' ? "2px solid var(--interactive-accent)"', ' : "1px solid var(--background-modifier-border)";', "", " control.button.style.fontWeight = selected", ' ? "600" : "400";', "", ' control.button.setAttribute(', ' "aria-pressed", String(selected)', " );", " }", "}", "", "for (const option of options) {", ' const button = buttons.createEl("button", {', ' text: option.emoji + " " + option.name', " });", "", ' button.style.borderRadius = "12px";', ' button.style.padding = "10px 16px";', ' button.style.cursor = "pointer";', ' button.style.flex = "1 1 120px";', "", " controls.push({", " name: option.name, button", " });", "", ' button.addEventListener("click", async () => {', " if (currentStatus === option.name) return;", "", " const previousStatus = currentStatus;", " currentStatus = option.name;", "", " controls.forEach(c => c.button.disabled = true);", " refreshButtons();", "", " try {", " const file = app.vault.getAbstractFileByPath(filePath);", "", " if (!file) {", ' throw new Error("Assignment file not found.");', " }", "", " await app.fileManager.processFrontMatter(", " file,", " fm => { fm.status = option.name; }", " );", "", " new Notice(", ' "๐ฟ Status updated: " + option.name', " );", "", " } catch (error) {", " currentStatus = previousStatus;", " refreshButtons();", ' new Notice("Could not update status.");', " console.error(error);", "", " } finally {", " controls.forEach(c => c.button.disabled = false);", " }", " });", "}", "", "refreshButtons();", ""
].join("\n");
// =================================== // ๐ธ 8. GENERATE THE ASSIGNMENT // ===================================
tR = [
"โ",
"type: assignment",
class: "[[${classPath}๎${className}]]",
due: ${due},
priority: ${priority},
"status: Not started",
estimate: ${estimateMinutes},
"work_days: []",
"โ",
"",
# ๐ฟ ${title} ๐ฟ,
"",
"## ๐ชท Assignment Status",
"",
statusStation,
"",
"## ๐ฑ Next step",
"",
"- [ ] First 10-minute action",
"",
"## ๐ Work notes",
"",
"- What needs to be submitted?",
"- Submission location:",
"- Instructions / rubric link:",
"",
"### ๐ชท Notes",
"",
"- ",
"",
"## ๐ Completion checklist",
"",
"- [ ] Start the assignment",
"- [ ] Complete the main work",
"- [ ] Check answers / review instructions",
"- [ ] Submit assignment",
"",
"## ๐ชป Planning",
"",
"- Work session scheduled for:",
- **Estimated time (minutes):** ${estimateMinutes},
"- Questions to ask:",
"",
"## ๐ธ Wrap-up",
"",
"- Actual time spent:",
"- What I learned:",
"- Follow-up / review needed:"
].join("\n");
// =================================== // ๐ 9. MOVE TO ASSIGNMENTS FOLDER // ===================================
await tp.file.move( "study nook/School/Assignments/" + title ); %>