Skip to content

Commit

Permalink
Add command to display the currently opened file in the calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
bartkessels committed Jan 12, 2025
1 parent 25acea7 commit b0b541b
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/daily-note-calendar.plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {CalendarSettingsTab} from 'src/plugin/settings/calendar.settings-tab';
import {createDependencies, Dependencies} from 'src/dependencies';
import 'src/extensions/extensions';
import {ManageAction} from 'src/domain/events/manage.event';
import {DisplayInCalendarCommand} from 'src/plugin/commands/display-in-calendar.command';

export default class DailyNoteCalendarPlugin extends Plugin {
private readonly dependencies: Dependencies = createDependencies(this);
Expand Down Expand Up @@ -41,6 +42,7 @@ export default class DailyNoteCalendarPlugin extends Plugin {
this.app.vault.on('create', this.dependencies.notesManager.refreshNotes.bind(this.dependencies.notesManager));
this.app.vault.on('rename', this.dependencies.notesManager.refreshNotes.bind(this.dependencies.notesManager));
this.app.vault.on('delete', this.dependencies.notesManager.refreshNotes.bind(this.dependencies.notesManager));
this.registerCommands();
this.app.workspace.onLayoutReady(this.initializePlugin.bind(this));
}

Expand All @@ -56,4 +58,8 @@ export default class DailyNoteCalendarPlugin extends Plugin {
type: CalendarView.VIEW_TYPE
});
}

private registerCommands(): void {
this.addCommand(new DisplayInCalendarCommand(this.dependencies.displayInCalendarCommandHandler));
}
}
12 changes: 11 additions & 1 deletion src/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ import {ManageEvent} from 'src/domain/events/manage.event';
import {PeriodicManageEvent} from 'src/implementation/events/periodic.manage-event';
import {Quarter} from 'src/domain/models/quarter';
import {NoteManageEvent} from 'src/implementation/events/note.manage-event';
import {CommandHandler} from 'src/domain/command-handlers/command-handler';
import {DisplayInCalendarCommandHandler} from 'src/implementation/command-handlers/display-in-calendar.command-handler';

export interface Dependencies {
readonly dateManager: DateManager;
Expand Down Expand Up @@ -84,6 +86,8 @@ export interface Dependencies {

readonly calendarEnhancer: Enhancer<CalendarUiModel>;
readonly notesEnhancer :Enhancer<NoteUiModel[]>;

readonly displayInCalendarCommandHandler: CommandHandler;
}

export function createDependencies(plugin: Plugin): Dependencies {
Expand Down Expand Up @@ -180,6 +184,10 @@ export function createDependencies(plugin: Plugin): Dependencies {
const notesEnhancer = new DefaultEnhancer<NoteUiModel[]>()
.withStep(notesDisplayDateEnhancerStep);

const displayInCalendarCommandHandler = new DisplayInCalendarCommandHandler(
notesSettingsRepository, noteAdapter, dateRepository, manageDayEvent, dateParser
);

return <Dependencies>{
dateManager: dateManager,
dateParser: dateParser,
Expand Down Expand Up @@ -209,6 +217,8 @@ export function createDependencies(plugin: Plugin): Dependencies {
yearlyNoteSettingsRepository: yearlyNoteSettingsRepository,

calendarEnhancer: calendarEnhancer,
notesEnhancer: notesEnhancer
notesEnhancer: notesEnhancer,

displayInCalendarCommandHandler: displayInCalendarCommandHandler
};
}
3 changes: 3 additions & 0 deletions src/domain/command-handlers/command-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface CommandHandler {
execute(): Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { DisplayInCalendarCommandHandler } from 'src/implementation/command-handlers/display-in-calendar.command-handler';
import { NoteAdapter } from 'src/domain/adapters/note.adapter';
import { DateRepository } from 'src/domain/repositories/date.repository';
import { ManageEvent } from 'src/domain/events/manage.event';
import {Day, DayOfWeek} from 'src/domain/models/day';
import { SettingsRepository } from 'src/domain/repositories/settings.repository';
import { NotesSettings } from 'src/domain/models/settings/notes.settings';
import { DateParser } from 'src/domain/parsers/date.parser';
import { Note } from 'src/domain/models/note';
import { ManageAction } from 'src/domain/events/manage.event';

describe('DisplayInCalendarCommandHandler', () => {
let handler: DisplayInCalendarCommandHandler;
let settingsRepository: jest.Mocked<SettingsRepository<NotesSettings>>;
let noteAdapter: jest.Mocked<NoteAdapter>;
let dateRepository: jest.Mocked<DateRepository>;
let manageDayEvent: jest.Mocked<ManageEvent<Day>>;
let dateParser: jest.Mocked<DateParser>;

beforeEach(() => {
settingsRepository = {
getSettings: jest.fn()
} as unknown as jest.Mocked<SettingsRepository<NotesSettings>>;
noteAdapter = {
getActiveNote: jest.fn()
} as unknown as jest.Mocked<NoteAdapter>;
dateRepository = {
getDay: jest.fn()
} as unknown as jest.Mocked<DateRepository>;
manageDayEvent = {
emitEvent: jest.fn()
} as unknown as jest.Mocked<ManageEvent<Day>>;
dateParser = {
parseString: jest.fn()
} as unknown as jest.Mocked<DateParser>;

handler = new DisplayInCalendarCommandHandler(
settingsRepository,
noteAdapter,
dateRepository,
manageDayEvent,
dateParser
);
});

it('should emit an event with the day from the createdOn property of the note', async () => {
const note: Note = {
name: 'My note',
path: 'path/to/note',
createdOn: new Date(2023, 9, 2),
properties: new Map()
};
const day: Day = { name: '2', date: new Date(2023, 9, 2), dayOfWeek: DayOfWeek.Monday };
settingsRepository.getSettings.mockResolvedValue({
useCreatedOnDateFromProperties: false
} as NotesSettings);
noteAdapter.getActiveNote.mockResolvedValue(note);
dateRepository.getDay.mockReturnValue(day);

await handler.execute();

expect(dateParser.parseString).not.toHaveBeenCalled();
expect(dateRepository.getDay).toHaveBeenCalledWith(note.createdOn);
expect(manageDayEvent.emitEvent).toHaveBeenCalledWith(ManageAction.Preview, day);
});

it('should emit an event with the day from the property if specified in the settings', async () => {
const note: Note = {
name: 'My note',
path: 'path/to/note',
createdOn: new Date(2023, 9, 2),
properties: new Map([['createdOn', '2023-10-02']])
};
const day: Day = { name: '2', date: new Date(2023, 10, 2), dayOfWeek: DayOfWeek.Monday };
settingsRepository.getSettings.mockResolvedValue({
useCreatedOnDateFromProperties: true,
createdOnDatePropertyName: 'createdOn',
createdOnPropertyFormat: 'yyyy-MM-dd'
} as NotesSettings);
noteAdapter.getActiveNote.mockResolvedValue(note);
dateParser.parseString.mockReturnValue(new Date(2023, 10, 2));
dateRepository.getDay.mockReturnValue(day);

await handler.execute();

expect(dateParser.parseString).toHaveBeenCalledWith('2023-10-02', 'yyyy-MM-dd');
expect(dateRepository.getDay).toHaveBeenCalledWith(new Date(2023, 10, 2));
expect(manageDayEvent.emitEvent).toHaveBeenCalledWith(ManageAction.Preview, day);
});

it('should emit an event with the day from the createdOn value if the property is not set', async () => {
const note: Note = {
name: 'My note',
path: 'path/to/note',
createdOn: new Date(2023, 9, 2),
properties: new Map()
};
const day: Day = { name: '2', date: new Date(2023, 9, 2), dayOfWeek: DayOfWeek.Monday };
settingsRepository.getSettings.mockResolvedValue({
useCreatedOnDateFromProperties: true,
createdOnDatePropertyName: 'createdOn',
createdOnPropertyFormat: 'yyyy-MM-dd'
} as NotesSettings);
noteAdapter.getActiveNote.mockResolvedValue(note);
dateRepository.getDay.mockReturnValue(day);

await handler.execute();

expect(dateParser.parseString).not.toHaveBeenCalled();
expect(dateRepository.getDay).toHaveBeenCalledWith(note.createdOn);
expect(manageDayEvent.emitEvent).toHaveBeenCalledWith(ManageAction.Preview, day);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {CommandHandler} from 'src/domain/command-handlers/command-handler';
import {NoteAdapter} from 'src/domain/adapters/note.adapter';
import { DateRepository } from 'src/domain/repositories/date.repository';
import {ManageAction, ManageEvent} from 'src/domain/events/manage.event';
import { Day } from 'src/domain/models/day';
import {SettingsRepository} from 'src/domain/repositories/settings.repository';
import {NotesSettings} from 'src/domain/models/settings/notes.settings';
import {DateParser} from 'src/domain/parsers/date.parser';
import {Note} from 'src/domain/models/note';

export class DisplayInCalendarCommandHandler implements CommandHandler {
constructor(
private readonly settingsRepository: SettingsRepository<NotesSettings>,
private readonly noteAdapter: NoteAdapter,
private readonly dateRepository: DateRepository,
private readonly manageDayEvent: ManageEvent<Day>,
private readonly dateParser: DateParser
) {

}

public async execute(): Promise<void> {
const activeNote = await this.noteAdapter.getActiveNote();
const activeDay = await this.getDayFromNote(activeNote);
this.manageDayEvent.emitEvent(ManageAction.Preview, activeDay);
}

private async getDayFromNote(note: Note | null): Promise<Day | undefined> {
if (!note) {
return;
}

const settings = await this.settingsRepository.getSettings();
const date = await this.getDateFromNote(note, settings);
return this.dateRepository.getDay(date);
}

private async getDateFromNote(note: Note, settings: NotesSettings): Promise<Date> {
const property = note.properties?.get(settings.createdOnDatePropertyName);
let date: Date | null = null;

if (settings.useCreatedOnDateFromProperties && property) {
date = this.dateParser.parseString(property, settings.createdOnPropertyFormat);
}

return date ?? note.createdOn;
}
}
17 changes: 17 additions & 0 deletions src/plugin/commands/display-in-calendar.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {Command} from 'obsidian';
import {CommandHandler} from 'src/domain/command-handlers/command-handler';

export class DisplayInCalendarCommand implements Command {
public id: string = 'dnc-display-in-calendar';
public name: string = 'Display the current note in the calendar';

constructor(
private readonly commandHandler: CommandHandler
) {

}

public callback: (() => any) = (): void => {
this.commandHandler.execute().then();
};
}

0 comments on commit b0b541b

Please sign in to comment.