<%* // ---- Prompt for org type ---- const orgType = await tp.system.suggester( ["University", "College", "Company"], ["university", "college", "company"], true, "Organization type" ); // ---- Prompt for name ---- const namePromptByType = { university: "University name (e.g., \"State University\")", college: "College / school name (e.g., \"School of Computing\")", company: "Company name (e.g., \"Acme Corp\")" }; const rawName = await tp.system.prompt(namePromptByType[orgType], "", true); const name = rawName.trim(); if (!name) { new Notice("Name is required."); throw new Error("Empty name."); } // ---- Determine folder, filename, and parent_organization YAML ---- let folder = ""; let fileBase = name; let parentBlock = ""; if (orgType === "university") { folder = "Organizations/Universities"; } else if (orgType === "college") { // College must declare its parent University const unis = app.vault.getMarkdownFiles() .filter(f => f.path.startsWith("Organizations/Universities/")) .sort((a, b) => a.basename.localeCompare(b.basename)); if (unis.length === 0) { new Notice("No Universities found. Create a University first."); throw new Error("No Universities to attach to."); } const uni = await tp.system.suggester( f => f.basename, unis, true, "Parent university" ); parentBlock = `\n - "[[${uni.basename}]]"`; folder = "Organizations/Colleges"; fileBase = `${uni.basename} — ${name}`; } else { folder = "Organizations/Companies"; } // ---- Optional contact fields ---- const email = (await tp.system.prompt("Email (optional)", "")) || ""; const phone = (await tp.system.prompt("Phone (optional)", "")) || ""; const website = (await tp.system.prompt("Website (optional)", "")) || ""; const address = (await tp.system.prompt("Address (optional)", "")) || ""; // ---- Move into the correct folder, then emit content ---- await tp.file.move(`${folder}/${fileBase}`); tR += `--- type: organization org_type: ${orgType} parent_organization:${parentBlock} email: ${email} phone: ${phone} website: ${website} address: ${address} ---`; -%> ## About ```dataviewjs // Sub-organizations — only renders header + table when this org has sub-orgs // (e.g., a University with Colleges). Hidden entirely on Colleges/Companies. const subs = dv.pages('"Organizations"') .where(p => { if (p.type !== "organization") return false; const po = p.parent_organization; if (!po) return false; const arr = Array.isArray(po) ? po : [po]; return arr.some(l => l && l.path === dv.current().file.path); }) .sort(p => p.file.name, "asc"); if (subs.length > 0) { dv.header(2, "Sub-organizations"); dv.table( ["Sub-unit", "Kind", "Email", "Phone"], subs.map(s => [ s.file.link, s.org_type || "", s.email || "", s.phone || "" ]) ); } ``` ## Departments ```dataviewjs const thisPath = dv.current().file.path; // Find any sub-organizations (e.g., colleges within a university) of this org const subs = dv.pages('"Organizations"') .where(p => { if (p.type !== "organization") return false; const po = p.parent_organization; if (!po) return false; const arr = Array.isArray(po) ? po : [po]; return arr.some(l => l && l.path === thisPath); }); const validParents = new Set(subs.map(s => s.file.path)); validParents.add(thisPath); // include this org itself // Departments whose parent_organization is this org OR any of its sub-orgs const depts = dv.pages('"Organizations/Departments"') .where(p => { const po = p.parent_organization; if (!po) return false; const arr = Array.isArray(po) ? po : [po]; return arr.some(l => l && validParents.has(l.path)); }) .sort(p => p.file.name, "asc"); if (depts.length === 0) { dv.el("p", "No departments yet.", { attr: { style: "color: var(--text-muted); font-style: italic;" } }); } else { dv.table( ["Department", "Parent", "Email", "Phone"], depts.map(d => [ d.file.link, d.parent_organization || "", d.email || "", d.phone || "" ]) ); } ``` ## People ```dataviewjs const thisPath = dv.current().file.path; // Sub-organizations of this org (e.g., colleges within a university) const subs = dv.pages('"Organizations"') .where(p => { if (p.type !== "organization") return false; const po = p.parent_organization; if (!po) return false; const arr = Array.isArray(po) ? po : [po]; return arr.some(l => l && l.path === thisPath); }); const orgPaths = new Set(subs.map(s => s.file.path)); orgPaths.add(thisPath); // All departments under this org or its sub-orgs const depts = dv.pages('"Organizations/Departments"') .where(p => { const po = p.parent_organization; if (!po) return false; const arr = Array.isArray(po) ? po : [po]; return arr.some(l => l && orgPaths.has(l.path)); }); const deptPaths = new Set(depts.map(d => d.file.path)); // People linked to any of the above const people = dv.pages('"People"') .where(p => { const orgs = p.organizations; if (orgs) { const arr = Array.isArray(orgs) ? orgs : [orgs]; if (arr.some(l => l && orgPaths.has(l.path))) return true; } const ds = p.departments; if (ds) { const arr = Array.isArray(ds) ? ds : [ds]; if (arr.some(l => l && deptPaths.has(l.path))) return true; } return false; }) .sort(p => p.file.name, "asc"); if (people.length === 0) { dv.el("p", "No people yet.", { attr: { style: "color: var(--text-muted); font-style: italic;" } }); } else { dv.table( ["Person", "Role", "Department", "Email", "Phone"], people.map(p => [ p.file.link, p.role || "", p.departments || "", p.email || "", p.phone || "" ]) ); } ``` ## Activities ```dataviewjs const thisPath = dv.current().file.path; const subs = dv.pages('"Organizations"') .where(p => { if (p.type !== "organization") return false; const po = p.parent_organization; if (!po) return false; const arr = Array.isArray(po) ? po : [po]; return arr.some(l => l && l.path === thisPath); }); const orgPaths = new Set(subs.map(s => s.file.path)); orgPaths.add(thisPath); const depts = dv.pages('"Organizations/Departments"') .where(p => { const po = p.parent_organization; if (!po) return false; const arr = Array.isArray(po) ? po : [po]; return arr.some(l => l && orgPaths.has(l.path)); }); const deptPaths = new Set(depts.map(d => d.file.path)); const people = dv.pages('"People"') .where(p => { const orgs = p.organizations; if (orgs) { const arr = Array.isArray(orgs) ? orgs : [orgs]; if (arr.some(l => l && orgPaths.has(l.path))) return true; } const ds = p.departments; if (ds) { const arr = Array.isArray(ds) ? ds : [ds]; if (arr.some(l => l && deptPaths.has(l.path))) return true; } return false; }); const peoplePaths = new Set(people.map(p => p.file.path)); const acts = dv.pages('"Activities"') .where(p => { const pep = p.people; if (!pep) return false; const arr = Array.isArray(pep) ? pep : [pep]; return arr.some(l => l && peoplePaths.has(l.path)); }) .sort(p => p.date, "desc"); if (acts.length === 0) { dv.el("p", "No activities yet.", { attr: { style: "color: var(--text-muted); font-style: italic;" } }); } else { dv.table( ["Note", "Type", "Date", "Subject", "People"], acts.map(a => [ a.file.link, a.type || "", String(a.date || ""), a.subject || a.topic || a.file.name, a.people || "" ]) ); } ```