mirror of
https://github.com/brendan-ch/todo-tracker-obsidian.git
synced 2026-04-16 23:00:32 +00:00
Add move to daily note support
This commit is contained in:
@@ -22,6 +22,14 @@ npm run build
|
|||||||
npm run lint
|
npm run lint
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
After every code change, run **both**:
|
||||||
|
1. `npm run build` — type-checks and bundles
|
||||||
|
2. `npm run lint` — ESLint (Obsidian-specific rules + TypeScript strict checks)
|
||||||
|
|
||||||
|
Fix all lint errors before considering a change complete.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### Entry Points & Build Process
|
### Entry Points & Build Process
|
||||||
|
|||||||
@@ -1,29 +1,102 @@
|
|||||||
import { TodoItem } from 'core/types';
|
import { App, Modal, Notice, Setting, TFile } from 'obsidian';
|
||||||
import { App, Modal, Setting, TFile } from 'obsidian';
|
import type { TodoItem } from '../core/types';
|
||||||
|
import { HeadingSelectModal } from './heading-select-modal';
|
||||||
|
import {
|
||||||
|
removeTodoBlock,
|
||||||
|
insertTodoAtBeginning,
|
||||||
|
collectTodoBlockLines,
|
||||||
|
} from '../core/todo-transformer';
|
||||||
|
|
||||||
export class DailyNoteSelectModal extends Modal {
|
export class DailyNoteSelectModal extends Modal {
|
||||||
constructor(app: App, todo: TodoItem, file: TFile) {
|
private todo: TodoItem;
|
||||||
super(app);
|
private sourceFile: TFile;
|
||||||
this.setTitle('Select a daily note');
|
private selectedDate = '';
|
||||||
|
|
||||||
let name = '';
|
constructor(app: App, todo: TodoItem, sourceFile: TFile) {
|
||||||
new Setting(this.contentEl)
|
super(app);
|
||||||
.setName('Date')
|
this.todo = todo;
|
||||||
.addMomentFormat((component) => {
|
this.sourceFile = sourceFile;
|
||||||
component.onChange((value) => {
|
this.setTitle('Select a daily note');
|
||||||
name = value;
|
|
||||||
});
|
new Setting(this.contentEl)
|
||||||
});
|
.setName('Date')
|
||||||
|
.addText((text) => {
|
||||||
new Setting(this.contentEl)
|
text.inputEl.type = 'date';
|
||||||
.addButton((btn) =>
|
text.onChange((value) => {
|
||||||
btn
|
this.selectedDate = value;
|
||||||
.setButtonText('Submit')
|
});
|
||||||
.setCta()
|
});
|
||||||
.onClick(() => {
|
|
||||||
this.close();
|
new Setting(this.contentEl)
|
||||||
// do some stuff
|
.addButton((btn) =>
|
||||||
console.debug(name);
|
btn
|
||||||
}));
|
.setButtonText('Submit')
|
||||||
}
|
.setCta()
|
||||||
|
.onClick(() => {
|
||||||
|
this.onSubmit();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onSubmit(): void {
|
||||||
|
if (!this.selectedDate) {
|
||||||
|
new Notice('Please select a date.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetFile = this.findDailyNote(this.selectedDate);
|
||||||
|
if (!targetFile) {
|
||||||
|
new Notice(`No daily note found for ${this.selectedDate}.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.close();
|
||||||
|
this.openTargetFile(targetFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private findDailyNote(dateString: string): TFile | null {
|
||||||
|
interface DailyNotesOptions { format?: string; folder?: string; }
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
|
||||||
|
const options = ((this.app as any).internalPlugins?.plugins?.['daily-notes']?.instance?.options ?? {}) as DailyNotesOptions;
|
||||||
|
const format = options.format ?? 'YYYY-MM-DD';
|
||||||
|
const folder = options.folder ?? '';
|
||||||
|
|
||||||
|
const fileName = window.moment(dateString).format(format);
|
||||||
|
const filePath = folder ? `${folder}/${fileName}.md` : `${fileName}.md`;
|
||||||
|
|
||||||
|
const file = this.app.vault.getAbstractFileByPath(filePath);
|
||||||
|
return file instanceof TFile ? file : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private openTargetFile(targetFile: TFile): void {
|
||||||
|
const fileCache = this.app.metadataCache.getFileCache(targetFile);
|
||||||
|
const headings = fileCache?.headings ?? [];
|
||||||
|
|
||||||
|
if (headings.length > 0) {
|
||||||
|
new HeadingSelectModal(
|
||||||
|
this.app,
|
||||||
|
this.todo,
|
||||||
|
this.sourceFile,
|
||||||
|
targetFile,
|
||||||
|
headings
|
||||||
|
).open();
|
||||||
|
} else {
|
||||||
|
void this.moveTodo(targetFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async moveTodo(targetFile: TFile): Promise<void> {
|
||||||
|
let blockLines: string[] = [];
|
||||||
|
|
||||||
|
await this.app.vault.process(this.sourceFile, (content) => {
|
||||||
|
const lines = content.split('\n');
|
||||||
|
const blockLineNumbers = [this.todo.lineNumber, ...collectTodoBlockLines(content, this.todo.lineNumber)];
|
||||||
|
blockLines = blockLineNumbers.map((ln) => lines[ln]!);
|
||||||
|
return removeTodoBlock(content, this.todo.lineNumber);
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.app.vault.process(targetFile, (content) => {
|
||||||
|
return insertTodoAtBeginning(content, blockLines.join('\n'));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user