-
-
Notifications
You must be signed in to change notification settings - Fork 19
Add scheduling algorithm #3062
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
Merged
Merged
Add scheduling algorithm #3062
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
eec3d03
feat: add dayjs dependency and implement scheduling algorithm with tests
vhpx 9c3e8eb
Merge branch 'main' into feat/implement-scheduling-algorithm
vhpx 255996a
feat(scheduler): implement scheduling page and enhance task management
vhpx ef72422
feat(scheduler): enhance scheduling functionality with new components…
vhpx 78e9cd2
fix(tests): add default task
vhpx 58f9c3d
Merge branch 'main' into feat/implement-scheduling-algorithm
vhpx 32c065c
chore: update eslint version and adjust argument order in supabase types
vhpx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import { defaultActiveHours, defaultTasks } from './algorithm'; | ||
import dayjs from 'dayjs'; | ||
import { describe, expect, it } from 'vitest'; | ||
|
||
describe('Scheduling Algorithm', () => { | ||
describe('DateRange interface', () => { | ||
it('should create valid date ranges', () => { | ||
const start = dayjs('2024-01-01T09:00:00'); | ||
const end = dayjs('2024-01-01T17:00:00'); | ||
|
||
const range = { start, end }; | ||
|
||
expect(range.start.isValid()).toBe(true); | ||
expect(range.end.isValid()).toBe(true); | ||
expect(range.end.isAfter(range.start)).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('Event interface', () => { | ||
it('should create valid events', () => { | ||
const event = { | ||
id: 'event-1', | ||
name: 'Team Meeting', | ||
range: { | ||
start: dayjs('2024-01-01T10:00:00'), | ||
end: dayjs('2024-01-01T11:00:00'), | ||
}, | ||
}; | ||
|
||
expect(event.id).toBe('event-1'); | ||
expect(event.name).toBe('Team Meeting'); | ||
expect(event.range.start.isValid()).toBe(true); | ||
expect(event.range.end.isValid()).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('Task interface', () => { | ||
it('should create valid tasks', () => { | ||
const task = { | ||
id: 'task-1', | ||
name: 'Complete project', | ||
duration: 120, // 2 hours in minutes | ||
events: [], | ||
}; | ||
|
||
expect(task.id).toBe('task-1'); | ||
expect(task.name).toBe('Complete project'); | ||
expect(task.duration).toBe(120); | ||
expect(Array.isArray(task.events)).toBe(true); | ||
}); | ||
|
||
it('should create tasks with events', () => { | ||
const task = { | ||
id: 'task-2', | ||
name: 'Review code', | ||
duration: 60, | ||
events: [ | ||
{ | ||
id: 'event-1', | ||
name: 'Code review session', | ||
range: { | ||
start: dayjs('2024-01-01T14:00:00'), | ||
end: dayjs('2024-01-01T15:00:00'), | ||
}, | ||
}, | ||
], | ||
}; | ||
|
||
expect(task.events).toHaveLength(1); | ||
expect(task.events[0]?.name).toBe('Code review session'); | ||
}); | ||
}); | ||
|
||
describe('ActiveHours interface', () => { | ||
it('should have valid structure for active hours', () => { | ||
const activeHours = { | ||
personal: [ | ||
{ | ||
start: dayjs().hour(7).minute(0).second(0).millisecond(0), | ||
end: dayjs().hour(23).minute(0).second(0).millisecond(0), | ||
}, | ||
], | ||
work: [ | ||
{ | ||
start: dayjs().hour(9).minute(0).second(0).millisecond(0), | ||
end: dayjs().hour(17).minute(0).second(0).millisecond(0), | ||
}, | ||
], | ||
meeting: [ | ||
{ | ||
start: dayjs().hour(9).minute(0).second(0).millisecond(0), | ||
end: dayjs().hour(17).minute(0).second(0).millisecond(0), | ||
}, | ||
], | ||
}; | ||
|
||
expect(Array.isArray(activeHours.personal)).toBe(true); | ||
expect(Array.isArray(activeHours.work)).toBe(true); | ||
expect(Array.isArray(activeHours.meeting)).toBe(true); | ||
|
||
expect(activeHours.personal[0]?.start.isValid()).toBe(true); | ||
expect(activeHours.work[0]?.end.isAfter(activeHours.work[0]?.start)).toBe( | ||
true | ||
); | ||
}); | ||
}); | ||
|
||
describe('DefaultActiveHours', () => { | ||
it('should have correct default active hours configuration', () => { | ||
expect(defaultActiveHours).toBeDefined(); | ||
expect(defaultActiveHours.personal).toHaveLength(1); | ||
expect(defaultActiveHours.work).toHaveLength(1); | ||
expect(defaultActiveHours.meeting).toHaveLength(1); | ||
|
||
// Test personal hours (7:00 - 23:00) | ||
expect(defaultActiveHours.personal[0]?.start.format('HH:mm')).toBe( | ||
'07:00' | ||
); | ||
expect(defaultActiveHours.personal[0]?.end.format('HH:mm')).toBe('23:00'); | ||
|
||
// Test work hours (9:00 - 17:00) | ||
expect(defaultActiveHours.work[0]?.start.format('HH:mm')).toBe('09:00'); | ||
expect(defaultActiveHours.work[0]?.end.format('HH:mm')).toBe('17:00'); | ||
|
||
// Test meeting hours (9:00 - 17:00) | ||
expect(defaultActiveHours.meeting[0]?.start.format('HH:mm')).toBe( | ||
'09:00' | ||
); | ||
expect(defaultActiveHours.meeting[0]?.end.format('HH:mm')).toBe('17:00'); | ||
}); | ||
}); | ||
|
||
describe('DefaultTasks', () => { | ||
it('should have correct default tasks configuration', () => { | ||
expect(defaultTasks).toBeDefined(); | ||
expect(Array.isArray(defaultTasks)).toBe(true); | ||
expect(defaultTasks).toHaveLength(1); | ||
}); | ||
|
||
it('should have valid task structure', () => { | ||
const task = defaultTasks[0]; | ||
|
||
expect(task).toBeDefined(); | ||
expect(task?.id).toBe('task-1'); | ||
expect(task?.name).toBe('Task 1'); | ||
expect(task?.duration).toBe(1); | ||
expect(Array.isArray(task?.events)).toBe(true); | ||
expect(task?.events).toHaveLength(0); | ||
}); | ||
|
||
it('should have valid task properties types', () => { | ||
const task = defaultTasks[0]; | ||
|
||
expect(typeof task?.id).toBe('string'); | ||
expect(typeof task?.name).toBe('string'); | ||
expect(typeof task?.duration).toBe('number'); | ||
expect(Array.isArray(task?.events)).toBe(true); | ||
}); | ||
|
||
it('should have positive duration', () => { | ||
const task = defaultTasks[0]; | ||
|
||
expect(task?.duration).toBeGreaterThan(0); | ||
}); | ||
|
||
it('should have non-empty id and name', () => { | ||
const task = defaultTasks[0]; | ||
|
||
expect(task?.id).toBeTruthy(); | ||
expect(task?.name).toBeTruthy(); | ||
expect(task?.id.length).toBeGreaterThan(0); | ||
expect(task?.name.length).toBeGreaterThan(0); | ||
}); | ||
}); | ||
|
||
// TODO: Add tests for the schedule function once it's implemented | ||
describe('schedule function', () => { | ||
it.todo('should schedule tasks without conflicts'); | ||
it.todo('should respect active hours constraints'); | ||
it.todo('should handle overlapping events'); | ||
it.todo('should return empty schedule for no tasks'); | ||
it.todo('should prioritize tasks based on duration'); | ||
}); | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import dayjs from 'dayjs'; | ||
|
||
interface DateRange { | ||
start: dayjs.Dayjs; | ||
end: dayjs.Dayjs; | ||
} | ||
|
||
interface Event { | ||
id: string; | ||
name: string; | ||
range: DateRange; | ||
} | ||
|
||
interface Task { | ||
id: string; | ||
name: string; | ||
duration: number; | ||
events: Event[]; | ||
} | ||
|
||
interface ActiveHours { | ||
personal: DateRange[]; | ||
work: DateRange[]; | ||
meeting: DateRange[]; | ||
} | ||
vhpx marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export const defaultActiveHours: ActiveHours = { | ||
personal: [ | ||
{ | ||
start: dayjs().hour(7).minute(0).second(0).millisecond(0), | ||
end: dayjs().hour(23).minute(0).second(0).millisecond(0), | ||
}, | ||
], | ||
work: [ | ||
{ | ||
start: dayjs().hour(9).minute(0).second(0).millisecond(0), | ||
end: dayjs().hour(17).minute(0).second(0).millisecond(0), | ||
}, | ||
], | ||
meeting: [ | ||
{ | ||
start: dayjs().hour(9).minute(0).second(0).millisecond(0), | ||
end: dayjs().hour(17).minute(0).second(0).millisecond(0), | ||
}, | ||
], | ||
}; | ||
vhpx marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export const defaultTasks: Task[] = [ | ||
{ | ||
id: 'task-1', | ||
name: 'Task 1', | ||
duration: 1, | ||
events: [], | ||
}, | ||
]; | ||
|
||
// export const schedule = (events: Event[], tasks: Task[]) => {}; |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.