Skip to content

Instantly share code, notes, and snippets.

@dangle
Created September 25, 2024 20:22
Show Gist options
  • Save dangle/80672eed48d535e8e25cae148ec6f995 to your computer and use it in GitHub Desktop.
Save dangle/80672eed48d535e8e25cae148ec6f995 to your computer and use it in GitHub Desktop.
Meeting Summary Scripts
class ActionItems {
actionItems(dv) {
const file = app.workspace.activeLeaf.view.file.basename;
return dv
.pages('#Meetings')
.where((page) => page.file.name.startsWith(file))
.file.tasks.where((task) => task.section.subpath == 'My Action Items');
}
Callout(dv) {
const actionItems = this.actionItems(dv);
if (actionItems.length > 0) {
const callout = actionItems.array().reduce((acc, task) => {
acc += `> ${dv.markdownTaskList([task])}`;
return acc;
}, '> [!action-items]+ Action Items\n');
if (dv.constructor.name === 'DataviewInlineApi') {
dv.span(callout);
}
return callout;
}
return '';
}
TaskList(dv) {
const md = dv.markdownTaskList(this.actionItems(dv));
if (dv.constructor.name === 'DataviewInlineApi') {
dv.span(md);
}
return md;
}
}

[[Work]]

[[Meetings]]

const { Summary } = customJS;
Summary.All(dv);

[[Tasks]]

const { ActionItems } = customJS;
ActionItems.Callout(dv);
const { SaveToMarkdown, Todoist } = customJS;
SaveToMarkdown(await Todoist.Callout(dv));
class SaveToMarkdown extends Function {
constructor() {
function save(content) {
window['customJS'].state.saveToMarkdown = content;
}
Object.setPrototypeOf(save, SaveToMarkdown.prototype);
return save;
}
async invoke() {
const fence1 =
/```(?<lang>dataview|dataviewjs)[\s]*\n(?:(?<code>(?:(?!```).)*)\n)```/gs;
const fence2 =
/~~~(?<lang>dataview|dataviewjs)[\s]*\n(?:(?<code>(?:(?!~~~).)*)\n)~~~/gs;
const file = app.workspace.activeLeaf.view.file;
const content = await app.vault.read(file);
let replaced = await this.replace(content, fence1);
replaced = await this.replace(replaced, fence2);
await app.vault.modify(file, replaced);
}
async replace(string, regexp) {
const replacements = await Promise.all(
Array.from(string.matchAll(regexp), async (match) => {
const { lang, code } = match.groups;
if (lang === 'dataview') {
const dv = window['DataviewAPI'];
return dv.tryQueryMarkdown(code);
}
if (code.contains('await')) {
window['customJS'].state.saveToMarkdown = '';
await Object.getPrototypeOf(async function () {}).constructor(`
const dv = window['DataviewAPI'];
${code}
`)();
const md = window['customJS'].state.saveToMarkdown;
window['customJS'].state.saveToMarkdown = '';
return md === undefined ? '' : md.trim();
}
const md = (1, eval)(`
const dv = window['DataviewAPI'];
${code}
`);
return md.trim();
}),
);
let i = 0;
return string.replace(regexp, () => replacements[i++]);
}
}
class Summary {
OneOnOnes(dv) {
const file = app.workspace.activeLeaf.view.file.basename;
const pages = dv
.pages('#Meetings/One-on-Ones')
.where((page) => page.file.name.startsWith(file));
switch (dv.constructor.name) {
case 'DataviewInlineApi':
return this.inlineOneOnOnes(dv, pages);
case 'DataviewApi':
return this.mdOneOnOnes(dv, pages);
}
}
inlineOneOnOnes(dv, pages) {
let list = '<ul class="has-list-bullet summary">';
list += pages.array().reduce((acc, page) => {
const person = page.file.name.split(' with ')[1];
acc += '<li>';
acc += '<div class="list-bullet"></div>';
acc += `<a href="${page.file.path}" class="internal-link"> One-on-one</a> with <a href="${person}" class="internal-link">${person}</a>`;
acc += '</li>';
return acc;
}, '');
list += '</ul>';
dv.span(list);
}
mdOneOnOnes(_, pages) {
return pages
.array()
.map((page) => {
const name = page.file.name.split(' with ')[1];
return `- [[${page.file.path}|One-on-one meeting]] with [[${name}]]`;
})
.join('\n');
}
Meetings(dv) {
const file = app.workspace.activeLeaf.view.file.basename;
const pages = dv
.pages('#Meetings')
.where((page) => page.file.name.startsWith(file))
.where((page) => !page.tags.includes('Meetings/One-on-Ones'));
switch (dv.constructor.name) {
case 'DataviewInlineApi':
return this.inlineMeetings(dv, pages);
case 'DataviewApi':
return this.mdMeetings(dv, pages);
}
}
inlineMeetings(dv, pages) {
let list = '<ul class="has-list-bullet summary">';
list += pages.array().reduce((acc, page) => {
const meeting = page.file.name.split(' - ')[1];
acc += '<li>';
acc += '<div class="list-bullet"></div>';
acc += `<a href="${page.file.path}" class="internal-link">${meeting}</a>`;
acc += '</li>';
return acc;
}, '');
list += '</ul>';
dv.span(list);
}
mdMeetings(_, pages) {
return pages
.array()
.map((page) => {
const meeting = page.file.name.split(' - ')[1];
return `- [[${page.file.path}|${meeting}]]`;
})
.join('\n');
}
All(dv) {
return [this.OneOnOnes(dv), this.Meetings(dv)].join('\n');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment