Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add command to display the currently opened file in the calendar #70

Merged
merged 1 commit into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
};
}
Loading