const { Summary } = customJS;
Summary.All(dv);
const { ActionItems } = customJS;
ActionItems.Callout(dv);
const { SaveToMarkdown, Todoist } = customJS;
SaveToMarkdown(await Todoist.Callout(dv));
| 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; | |
| } | |
| } |
| 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'); | |
| } | |
| } |