...
This commit is contained in:
@@ -12,8 +12,7 @@ pub mut:
|
|||||||
title string
|
title string
|
||||||
start_time i64 // Unix timestamp
|
start_time i64 // Unix timestamp
|
||||||
end_time i64 // Unix timestamp
|
end_time i64 // Unix timestamp
|
||||||
location string
|
registration_desks []u32 //link to registration mechanism, is where we track invitees, are not attendee unless accepted
|
||||||
registration_desks []u32 //link to object for registration, is where we track invitees, are not attendee unless accepted
|
|
||||||
attendees []Attendee
|
attendees []Attendee
|
||||||
docs []EventDoc // link to docs
|
docs []EventDoc // link to docs
|
||||||
calendar_id u32 // Associated calendar
|
calendar_id u32 // Associated calendar
|
||||||
@@ -68,24 +67,6 @@ pub enum AttendanceStatus {
|
|||||||
tentative
|
tentative
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RecurrenceRule {
|
|
||||||
pub mut:
|
|
||||||
frequency RecurrenceFreq
|
|
||||||
interval int // Every N frequencies
|
|
||||||
until i64 // End date (Unix timestamp)
|
|
||||||
count int // Number of occurrences
|
|
||||||
by_weekday []int // Days of week (0=Sunday)
|
|
||||||
by_monthday []int // Days of month
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum RecurrenceFreq {
|
|
||||||
none
|
|
||||||
daily
|
|
||||||
weekly
|
|
||||||
monthly
|
|
||||||
yearly
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct EventDoc {
|
pub struct EventDoc {
|
||||||
pub mut:
|
pub mut:
|
||||||
fs_item u32
|
fs_item u32
|
||||||
@@ -93,14 +74,6 @@ pub mut:
|
|||||||
public bool // everyone can see the file, otherwise only the organizers, attendees
|
public bool // everyone can see the file, otherwise only the organizers, attendees
|
||||||
}
|
}
|
||||||
|
|
||||||
@[params]
|
|
||||||
pub struct CalendarEventListArg {
|
|
||||||
pub mut:
|
|
||||||
calendar_id u32
|
|
||||||
status EventStatus
|
|
||||||
public bool
|
|
||||||
limit int = 100 // Default limit is 100
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub struct EventLocation {
|
pub struct EventLocation {
|
||||||
@@ -117,8 +90,6 @@ pub enum EventLocationCat {
|
|||||||
hybrid
|
hybrid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub struct DBCalendarEvent {
|
pub struct DBCalendarEvent {
|
||||||
pub mut:
|
pub mut:
|
||||||
db &db.DB @[skip; str: skip]
|
db &db.DB @[skip; str: skip]
|
||||||
@@ -156,10 +127,10 @@ pub fn (self CalendarEvent) description(methodname string) string {
|
|||||||
pub fn (self CalendarEvent) example(methodname string) (string, string) {
|
pub fn (self CalendarEvent) example(methodname string) (string, string) {
|
||||||
match methodname {
|
match methodname {
|
||||||
'set' {
|
'set' {
|
||||||
return '{"calendar_event": {"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}}', '1'
|
return '{"calendar_event": {"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC", "locations": []}}', '1'
|
||||||
}
|
}
|
||||||
'get' {
|
'get' {
|
||||||
return '{"id": 1}', '{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}'
|
return '{"id": 1}', '{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC", "locations": []}'
|
||||||
}
|
}
|
||||||
'delete' {
|
'delete' {
|
||||||
return '{"id": 1}', 'true'
|
return '{"id": 1}', 'true'
|
||||||
@@ -168,7 +139,7 @@ pub fn (self CalendarEvent) example(methodname string) (string, string) {
|
|||||||
return '{"id": 1}', 'true'
|
return '{"id": 1}', 'true'
|
||||||
}
|
}
|
||||||
'list' {
|
'list' {
|
||||||
return '{}', '[{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}]'
|
return '{}', '[{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC", "locations": []}]'
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return '{}', '{}'
|
return '{}', '{}'
|
||||||
@@ -180,7 +151,6 @@ pub fn (self CalendarEvent) dump(mut e encoder.Encoder) ! {
|
|||||||
e.add_string(self.title)
|
e.add_string(self.title)
|
||||||
e.add_i64(self.start_time)
|
e.add_i64(self.start_time)
|
||||||
e.add_i64(self.end_time)
|
e.add_i64(self.end_time)
|
||||||
e.add_string(self.location)
|
|
||||||
|
|
||||||
// Encode registration_desks array
|
// Encode registration_desks array
|
||||||
e.add_list_u32(self.registration_desks)
|
e.add_list_u32(self.registration_desks)
|
||||||
@@ -193,6 +163,7 @@ pub fn (self CalendarEvent) dump(mut e encoder.Encoder) ! {
|
|||||||
e.add_bool(attendee.attendance_required)
|
e.add_bool(attendee.attendance_required)
|
||||||
e.add_bool(attendee.admin)
|
e.add_bool(attendee.admin)
|
||||||
e.add_bool(attendee.organizer)
|
e.add_bool(attendee.organizer)
|
||||||
|
e.add_string(attendee.location) // Added missing location field
|
||||||
|
|
||||||
// Encode AttendeeLog array
|
// Encode AttendeeLog array
|
||||||
e.add_u16(u16(attendee.log.len))
|
e.add_u16(u16(attendee.log.len))
|
||||||
@@ -215,8 +186,8 @@ pub fn (self CalendarEvent) dump(mut e encoder.Encoder) ! {
|
|||||||
e.add_u8(u8(self.status))
|
e.add_u8(u8(self.status))
|
||||||
e.add_bool(self.is_all_day)
|
e.add_bool(self.is_all_day)
|
||||||
e.add_bool(self.is_recurring)
|
e.add_bool(self.is_recurring)
|
||||||
e.add_bool(self.public) // Added missing public field
|
e.add_bool(self.public)
|
||||||
e.add_u8(u8(self.priority)) // Added missing priority field
|
e.add_u8(u8(self.priority))
|
||||||
|
|
||||||
// Encode recurrence array
|
// Encode recurrence array
|
||||||
e.add_u16(u16(self.recurrence.len))
|
e.add_u16(u16(self.recurrence.len))
|
||||||
@@ -229,6 +200,22 @@ pub fn (self CalendarEvent) dump(mut e encoder.Encoder) ! {
|
|||||||
e.add_list_int(rule.by_monthday)
|
e.add_list_int(rule.by_monthday)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode locations array
|
||||||
|
e.add_u16(u16(self.locations.len))
|
||||||
|
for location in self.locations {
|
||||||
|
e.add_string(location.name)
|
||||||
|
e.add_string(location.description)
|
||||||
|
e.add_u8(u8(location.cat))
|
||||||
|
|
||||||
|
// Encode location docs array
|
||||||
|
e.add_u16(u16(location.docs.len))
|
||||||
|
for fs_item in location.docs {
|
||||||
|
e.add_u32(fs_item.fs_item)
|
||||||
|
e.add_string(fs_item.cat)
|
||||||
|
e.add_bool(fs_item.public)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
e.add_list_int(self.reminder_mins)
|
e.add_list_int(self.reminder_mins)
|
||||||
e.add_string(self.color)
|
e.add_string(self.color)
|
||||||
e.add_string(self.timezone)
|
e.add_string(self.timezone)
|
||||||
@@ -238,7 +225,6 @@ pub fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e encoder.Decode
|
|||||||
o.title = e.get_string()!
|
o.title = e.get_string()!
|
||||||
o.start_time = e.get_i64()!
|
o.start_time = e.get_i64()!
|
||||||
o.end_time = e.get_i64()!
|
o.end_time = e.get_i64()!
|
||||||
o.location = e.get_string()!
|
|
||||||
|
|
||||||
// Decode registration_desks array
|
// Decode registration_desks array
|
||||||
o.registration_desks = e.get_list_u32()!
|
o.registration_desks = e.get_list_u32()!
|
||||||
@@ -252,6 +238,7 @@ pub fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e encoder.Decode
|
|||||||
attendance_required := e.get_bool()!
|
attendance_required := e.get_bool()!
|
||||||
admin := e.get_bool()!
|
admin := e.get_bool()!
|
||||||
organizer := e.get_bool()!
|
organizer := e.get_bool()!
|
||||||
|
location := e.get_string()! // Added missing location field
|
||||||
|
|
||||||
// Decode AttendeeLog array
|
// Decode AttendeeLog array
|
||||||
log_len := e.get_u16()!
|
log_len := e.get_u16()!
|
||||||
@@ -275,6 +262,7 @@ pub fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e encoder.Decode
|
|||||||
admin: admin
|
admin: admin
|
||||||
organizer: organizer
|
organizer: organizer
|
||||||
log: log_entries
|
log: log_entries
|
||||||
|
location: location // Added missing location field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o.attendees = attendees
|
o.attendees = attendees
|
||||||
@@ -324,6 +312,38 @@ pub fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e encoder.Decode
|
|||||||
}
|
}
|
||||||
o.recurrence = recurrence
|
o.recurrence = recurrence
|
||||||
|
|
||||||
|
// Decode locations array
|
||||||
|
locations_len := e.get_u16()!
|
||||||
|
mut locations := []EventLocation{}
|
||||||
|
for _ in 0 .. locations_len {
|
||||||
|
name := e.get_string()!
|
||||||
|
description := e.get_string()!
|
||||||
|
cat := unsafe { EventLocationCat(e.get_u8()!) }
|
||||||
|
|
||||||
|
// Decode location docs array
|
||||||
|
location_docs_len := e.get_u16()!
|
||||||
|
mut location_docs := []EventDoc{}
|
||||||
|
for _ in 0 .. location_docs_len {
|
||||||
|
fs_item := e.get_u32()!
|
||||||
|
doc_cat := e.get_string()!
|
||||||
|
public := e.get_bool()!
|
||||||
|
|
||||||
|
location_docs << EventDoc{
|
||||||
|
fs_item: fs_item
|
||||||
|
cat: doc_cat
|
||||||
|
public: public
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locations << EventLocation{
|
||||||
|
name: name
|
||||||
|
description: description
|
||||||
|
cat: cat
|
||||||
|
docs: location_docs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
o.locations = locations
|
||||||
|
|
||||||
o.reminder_mins = e.get_list_int()!
|
o.reminder_mins = e.get_list_int()!
|
||||||
o.color = e.get_string()!
|
o.color = e.get_string()!
|
||||||
o.timezone = e.get_string()!
|
o.timezone = e.get_string()!
|
||||||
@@ -337,7 +357,6 @@ pub mut:
|
|||||||
title string
|
title string
|
||||||
start_time string // use ourtime module to go from string to epoch
|
start_time string // use ourtime module to go from string to epoch
|
||||||
end_time string // use ourtime module to go from string to epoch
|
end_time string // use ourtime module to go from string to epoch
|
||||||
location string
|
|
||||||
attendees []u32 // IDs of user groups
|
attendees []u32 // IDs of user groups
|
||||||
docs []u32 // IDs of linked files or dirs
|
docs []u32 // IDs of linked files or dirs
|
||||||
calendar_id u32 // Associated calendar
|
calendar_id u32 // Associated calendar
|
||||||
@@ -368,7 +387,6 @@ pub fn (mut self DBCalendarEvent) new(args CalendarEventArg) !CalendarEvent {
|
|||||||
|
|
||||||
mut o := CalendarEvent{
|
mut o := CalendarEvent{
|
||||||
title: args.title
|
title: args.title
|
||||||
location: args.location
|
|
||||||
attendees: []Attendee{}
|
attendees: []Attendee{}
|
||||||
docs: fs_attachments
|
docs: fs_attachments
|
||||||
calendar_id: args.calendar_id
|
calendar_id: args.calendar_id
|
||||||
@@ -421,6 +439,15 @@ pub fn (mut self DBCalendarEvent) get(id u32) !CalendarEvent {
|
|||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@[params]
|
||||||
|
pub struct CalendarEventListArg {
|
||||||
|
pub mut:
|
||||||
|
calendar_id u32
|
||||||
|
status EventStatus
|
||||||
|
public bool
|
||||||
|
limit int = 100 // Default limit is 100
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut self DBCalendarEvent) list(args CalendarEventListArg) ![]CalendarEvent {
|
pub fn (mut self DBCalendarEvent) list(args CalendarEventListArg) ![]CalendarEvent {
|
||||||
// Require at least one parameter to be provided
|
// Require at least one parameter to be provided
|
||||||
if args.calendar_id == 0 && args.status == .draft && !args.public {
|
if args.calendar_id == 0 && args.status == .draft && !args.public {
|
||||||
|
|||||||
@@ -17,9 +17,8 @@ fn test_calendar_event_new() ! {
|
|||||||
title: 'Team Meeting'
|
title: 'Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -39,8 +38,9 @@ fn test_calendar_event_new() ! {
|
|||||||
assert calendar_event.name == 'test_event'
|
assert calendar_event.name == 'test_event'
|
||||||
assert calendar_event.description == 'Test calendar event for unit testing'
|
assert calendar_event.description == 'Test calendar event for unit testing'
|
||||||
assert calendar_event.title == 'Team Meeting'
|
assert calendar_event.title == 'Team Meeting'
|
||||||
assert calendar_event.location == 'Office'
|
// Check that locations array is empty (since we didn't add any locations)
|
||||||
assert calendar_event.fs_items.len == 0
|
assert calendar_event.locations.len == 0
|
||||||
|
assert calendar_event.docs.len == 0
|
||||||
assert calendar_event.registration_desks.len == 0
|
assert calendar_event.registration_desks.len == 0
|
||||||
assert calendar_event.calendar_id == 1
|
assert calendar_event.calendar_id == 1
|
||||||
assert calendar_event.status == .published
|
assert calendar_event.status == .published
|
||||||
@@ -71,9 +71,8 @@ fn test_calendar_event_crud_operations() ! {
|
|||||||
title: 'Team Meeting'
|
title: 'Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -90,15 +89,15 @@ fn test_calendar_event_crud_operations() ! {
|
|||||||
|
|
||||||
mut calendar_event := db_calendar_event.new(args)!
|
mut calendar_event := db_calendar_event.new(args)!
|
||||||
|
|
||||||
// Add some data for registration_desks and fs_items
|
// Add some data for registration_desks and docs
|
||||||
calendar_event.registration_desks = [u32(1001), u32(1002)]
|
calendar_event.registration_desks = [u32(1001), u32(1002)]
|
||||||
|
|
||||||
mut fs_item := FileAttachment{
|
mut fs_item := EventDoc{
|
||||||
fs_item: 2001
|
fs_item: 2001
|
||||||
cat: 'agenda'
|
cat: 'agenda'
|
||||||
public: true
|
public: true
|
||||||
}
|
}
|
||||||
calendar_event.fs_items = [fs_item]
|
calendar_event.docs = [fs_item]
|
||||||
|
|
||||||
// Test set operation
|
// Test set operation
|
||||||
calendar_event = db_calendar_event.set(calendar_event)!
|
calendar_event = db_calendar_event.set(calendar_event)!
|
||||||
@@ -109,7 +108,8 @@ fn test_calendar_event_crud_operations() ! {
|
|||||||
assert retrieved_event.name == 'crud_test_event'
|
assert retrieved_event.name == 'crud_test_event'
|
||||||
assert retrieved_event.description == 'Test calendar event for CRUD operations'
|
assert retrieved_event.description == 'Test calendar event for CRUD operations'
|
||||||
assert retrieved_event.title == 'Team Meeting'
|
assert retrieved_event.title == 'Team Meeting'
|
||||||
assert retrieved_event.location == 'Office'
|
// Check that locations array is empty (since we didn't add any locations)
|
||||||
|
assert retrieved_event.locations.len == 0
|
||||||
assert retrieved_event.calendar_id == 1
|
assert retrieved_event.calendar_id == 1
|
||||||
assert retrieved_event.status == .published
|
assert retrieved_event.status == .published
|
||||||
assert retrieved_event.is_all_day == false
|
assert retrieved_event.is_all_day == false
|
||||||
@@ -121,10 +121,10 @@ fn test_calendar_event_crud_operations() ! {
|
|||||||
assert retrieved_event.registration_desks.len == 2
|
assert retrieved_event.registration_desks.len == 2
|
||||||
assert retrieved_event.registration_desks[0] == 1001
|
assert retrieved_event.registration_desks[0] == 1001
|
||||||
assert retrieved_event.registration_desks[1] == 1002
|
assert retrieved_event.registration_desks[1] == 1002
|
||||||
assert retrieved_event.fs_items.len == 1
|
assert retrieved_event.docs.len == 1
|
||||||
assert retrieved_event.fs_items[0].fs_item == 2001
|
assert retrieved_event.docs[0].fs_item == 2001
|
||||||
assert retrieved_event.fs_items[0].cat == 'agenda'
|
assert retrieved_event.docs[0].cat == 'agenda'
|
||||||
assert retrieved_event.fs_items[0].public == true
|
assert retrieved_event.docs[0].public == true
|
||||||
|
|
||||||
// Test exist operation
|
// Test exist operation
|
||||||
exists := db_calendar_event.exist(original_id)!
|
exists := db_calendar_event.exist(original_id)!
|
||||||
@@ -137,9 +137,8 @@ fn test_calendar_event_crud_operations() ! {
|
|||||||
title: 'Updated Team Meeting'
|
title: 'Updated Team Meeting'
|
||||||
start_time: '2025-01-01 12:00:00'
|
start_time: '2025-01-01 12:00:00'
|
||||||
end_time: '2025-01-01 13:00:00'
|
end_time: '2025-01-01 13:00:00'
|
||||||
location: 'Conference Room'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 2
|
calendar_id: 2
|
||||||
status: .draft
|
status: .draft
|
||||||
is_all_day: true
|
is_all_day: true
|
||||||
@@ -156,15 +155,15 @@ fn test_calendar_event_crud_operations() ! {
|
|||||||
mut updated_event := db_calendar_event.new(updated_args)!
|
mut updated_event := db_calendar_event.new(updated_args)!
|
||||||
updated_event.id = original_id
|
updated_event.id = original_id
|
||||||
|
|
||||||
// Update registration_desks and fs_items
|
// Update registration_desks and docs
|
||||||
updated_event.registration_desks = [u32(1003)]
|
updated_event.registration_desks = [u32(1003)]
|
||||||
|
|
||||||
mut updated_fs_item := FileAttachment{
|
mut updated_fs_item := EventDoc{
|
||||||
fs_item: 2002
|
fs_item: 2002
|
||||||
cat: 'minutes'
|
cat: 'minutes'
|
||||||
public: false
|
public: false
|
||||||
}
|
}
|
||||||
updated_event.fs_items = [updated_fs_item]
|
updated_event.docs = [updated_fs_item]
|
||||||
|
|
||||||
updated_event = db_calendar_event.set(updated_event)!
|
updated_event = db_calendar_event.set(updated_event)!
|
||||||
|
|
||||||
@@ -173,7 +172,8 @@ fn test_calendar_event_crud_operations() ! {
|
|||||||
assert final_event.name == 'updated_event'
|
assert final_event.name == 'updated_event'
|
||||||
assert final_event.description == 'Updated test calendar event'
|
assert final_event.description == 'Updated test calendar event'
|
||||||
assert final_event.title == 'Updated Team Meeting'
|
assert final_event.title == 'Updated Team Meeting'
|
||||||
assert final_event.location == 'Conference Room'
|
// Check that locations array is empty (since we didn't add any locations)
|
||||||
|
assert final_event.locations.len == 0
|
||||||
assert final_event.calendar_id == 2
|
assert final_event.calendar_id == 2
|
||||||
assert final_event.status == .draft
|
assert final_event.status == .draft
|
||||||
assert final_event.is_all_day == true
|
assert final_event.is_all_day == true
|
||||||
@@ -183,10 +183,10 @@ fn test_calendar_event_crud_operations() ! {
|
|||||||
assert final_event.timezone == 'EST'
|
assert final_event.timezone == 'EST'
|
||||||
assert final_event.registration_desks.len == 1
|
assert final_event.registration_desks.len == 1
|
||||||
assert final_event.registration_desks[0] == 1003
|
assert final_event.registration_desks[0] == 1003
|
||||||
assert final_event.fs_items.len == 1
|
assert final_event.docs.len == 1
|
||||||
assert final_event.fs_items[0].fs_item == 2002
|
assert final_event.docs[0].fs_item == 2002
|
||||||
assert final_event.fs_items[0].cat == 'minutes'
|
assert final_event.docs[0].cat == 'minutes'
|
||||||
assert final_event.fs_items[0].public == false
|
assert final_event.docs[0].public == false
|
||||||
|
|
||||||
// Test delete operation
|
// Test delete operation
|
||||||
db_calendar_event.delete(original_id)!
|
db_calendar_event.delete(original_id)!
|
||||||
@@ -212,9 +212,8 @@ fn test_calendar_event_attendees_encoding_decoding() ! {
|
|||||||
title: 'Team Meeting'
|
title: 'Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -310,9 +309,8 @@ fn test_calendar_event_recurrence_encoding_decoding() ! {
|
|||||||
title: 'Weekly Team Meeting'
|
title: 'Weekly Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -392,9 +390,8 @@ fn test_calendar_event_registration_desks_encoding_decoding() ! {
|
|||||||
title: 'Team Meeting'
|
title: 'Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -429,7 +426,7 @@ fn test_calendar_event_registration_desks_encoding_decoding() ! {
|
|||||||
println('✓ CalendarEvent registration_desks encoding/decoding test passed!')
|
println('✓ CalendarEvent registration_desks encoding/decoding test passed!')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_calendar_event_fs_items_encoding_decoding() ! {
|
fn test_calendar_event_docs_encoding_decoding() ! {
|
||||||
// Initialize DBCalendarEvent for testing
|
// Initialize DBCalendarEvent for testing
|
||||||
mut mydb := db.new_test()!
|
mut mydb := db.new_test()!
|
||||||
mut db_calendar_event := DBCalendarEvent{
|
mut db_calendar_event := DBCalendarEvent{
|
||||||
@@ -438,14 +435,13 @@ fn test_calendar_event_fs_items_encoding_decoding() ! {
|
|||||||
|
|
||||||
// Create a new calendar event with file attachments
|
// Create a new calendar event with file attachments
|
||||||
mut args := CalendarEventArg{
|
mut args := CalendarEventArg{
|
||||||
name: 'fs_items_test_event'
|
name: 'docs_test_event'
|
||||||
description: 'Test calendar event for fs_items encoding/decoding'
|
description: 'Test calendar event for docs encoding/decoding'
|
||||||
title: 'Team Meeting'
|
title: 'Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -463,19 +459,19 @@ fn test_calendar_event_fs_items_encoding_decoding() ! {
|
|||||||
mut calendar_event := db_calendar_event.new(args)!
|
mut calendar_event := db_calendar_event.new(args)!
|
||||||
|
|
||||||
// Add file attachments manually
|
// Add file attachments manually
|
||||||
mut fs_item1 := FileAttachment{
|
mut fs_item1 := EventDoc{
|
||||||
fs_item: 2001
|
fs_item: 2001
|
||||||
cat: 'agenda'
|
cat: 'agenda'
|
||||||
public: true
|
public: true
|
||||||
}
|
}
|
||||||
|
|
||||||
mut fs_item2 := FileAttachment{
|
mut fs_item2 := EventDoc{
|
||||||
fs_item: 2002
|
fs_item: 2002
|
||||||
cat: 'minutes'
|
cat: 'minutes'
|
||||||
public: false
|
public: false
|
||||||
}
|
}
|
||||||
|
|
||||||
calendar_event.fs_items = [fs_item1, fs_item2]
|
calendar_event.docs = [fs_item1, fs_item2]
|
||||||
|
|
||||||
// Save the calendar event
|
// Save the calendar event
|
||||||
calendar_event = db_calendar_event.set(calendar_event)!
|
calendar_event = db_calendar_event.set(calendar_event)!
|
||||||
@@ -484,19 +480,19 @@ fn test_calendar_event_fs_items_encoding_decoding() ! {
|
|||||||
// Retrieve and verify all fields were properly encoded/decoded
|
// Retrieve and verify all fields were properly encoded/decoded
|
||||||
retrieved_event := db_calendar_event.get(calendar_event_id)!
|
retrieved_event := db_calendar_event.get(calendar_event_id)!
|
||||||
|
|
||||||
assert retrieved_event.fs_items.len == 2
|
assert retrieved_event.docs.len == 2
|
||||||
|
|
||||||
// Verify first file attachment details
|
// Verify first file attachment details
|
||||||
assert retrieved_event.fs_items[0].fs_item == 2001
|
assert retrieved_event.docs[0].fs_item == 2001
|
||||||
assert retrieved_event.fs_items[0].cat == 'agenda'
|
assert retrieved_event.docs[0].cat == 'agenda'
|
||||||
assert retrieved_event.fs_items[0].public == true
|
assert retrieved_event.docs[0].public == true
|
||||||
|
|
||||||
// Verify second file attachment details
|
// Verify second file attachment details
|
||||||
assert retrieved_event.fs_items[1].fs_item == 2002
|
assert retrieved_event.docs[1].fs_item == 2002
|
||||||
assert retrieved_event.fs_items[1].cat == 'minutes'
|
assert retrieved_event.docs[1].cat == 'minutes'
|
||||||
assert retrieved_event.fs_items[1].public == false
|
assert retrieved_event.docs[1].public == false
|
||||||
|
|
||||||
println('✓ CalendarEvent fs_items encoding/decoding test passed!')
|
println('✓ CalendarEvent docs encoding/decoding test passed!')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_calendar_event_type_name() ! {
|
fn test_calendar_event_type_name() ! {
|
||||||
@@ -513,9 +509,8 @@ fn test_calendar_event_type_name() ! {
|
|||||||
title: 'Team Meeting'
|
title: 'Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -552,9 +547,8 @@ fn test_calendar_event_description() ! {
|
|||||||
title: 'Team Meeting'
|
title: 'Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -595,9 +589,8 @@ fn test_calendar_event_example() ! {
|
|||||||
title: 'Team Meeting'
|
title: 'Team Meeting'
|
||||||
start_time: '2025-01-01 10:00:00'
|
start_time: '2025-01-01 10:00:00'
|
||||||
end_time: '2025-01-01 11:00:00'
|
end_time: '2025-01-01 11:00:00'
|
||||||
location: 'Office'
|
|
||||||
attendees: []u32{}
|
attendees: []u32{}
|
||||||
fs_items: []u32{}
|
docs: []u32{}
|
||||||
calendar_id: 1
|
calendar_id: 1
|
||||||
status: .published
|
status: .published
|
||||||
is_all_day: false
|
is_all_day: false
|
||||||
@@ -615,12 +608,12 @@ fn test_calendar_event_example() ! {
|
|||||||
|
|
||||||
// Test example method for each methodname
|
// Test example method for each methodname
|
||||||
set_call, set_result := calendar_event.example('set')
|
set_call, set_result := calendar_event.example('set')
|
||||||
assert set_call == '{"calendar_event": {"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}}'
|
assert set_call == '{"calendar_event": {"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC", "locations": []}}'
|
||||||
assert set_result == '1'
|
assert set_result == '1'
|
||||||
|
|
||||||
get_call, get_result := calendar_event.example('get')
|
get_call, get_result := calendar_event.example('get')
|
||||||
assert get_call == '{"id": 1}'
|
assert get_call == '{"id": 1}'
|
||||||
assert get_result == '{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}'
|
assert get_result == '{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC", "locations": []}'
|
||||||
|
|
||||||
delete_call, delete_result := calendar_event.example('delete')
|
delete_call, delete_result := calendar_event.example('delete')
|
||||||
assert delete_call == '{"id": 1}'
|
assert delete_call == '{"id": 1}'
|
||||||
@@ -632,7 +625,7 @@ fn test_calendar_event_example() ! {
|
|||||||
|
|
||||||
list_call, list_result := calendar_event.example('list')
|
list_call, list_result := calendar_event.example('list')
|
||||||
assert list_call == '{}'
|
assert list_call == '{}'
|
||||||
assert list_result == '[{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}]'
|
assert list_result == '[{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "attendees": [], "docs": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC", "locations": []}]'
|
||||||
|
|
||||||
unknown_call, unknown_result := calendar_event.example('unknown')
|
unknown_call, unknown_result := calendar_event.example('unknown')
|
||||||
assert unknown_call == '{}'
|
assert unknown_call == '{}'
|
||||||
|
|||||||
3
lib/hero/heromodels/planning.md
Normal file
3
lib/hero/heromodels/planning.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## notes around how to do a calendly feature
|
||||||
|
|
||||||
|
- make an agenda for the planning and call it as such, this has the timeboxes available for planning
|
||||||
191
lib/hero/heromodels/planning.v
Normal file
191
lib/hero/heromodels/planning.v
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
module heromodels
|
||||||
|
|
||||||
|
import freeflowuniverse.herolib.data.encoder
|
||||||
|
import freeflowuniverse.herolib.data.ourtime
|
||||||
|
import freeflowuniverse.herolib.hero.db
|
||||||
|
|
||||||
|
// Planning represents a collection of events
|
||||||
|
@[heap]
|
||||||
|
pub struct Planning {
|
||||||
|
db.Base
|
||||||
|
pub mut:
|
||||||
|
color string // Hex color code
|
||||||
|
timezone string
|
||||||
|
is_public bool
|
||||||
|
calendar_id u32 //link to calendarid which is relevant for this planning, the calendar has
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RecurrenceRule {
|
||||||
|
pub mut:
|
||||||
|
frequency RecurrenceFreq
|
||||||
|
interval int // Every N frequencies
|
||||||
|
until i64 // End date (Unix timestamp)
|
||||||
|
count int // Number of occurrences
|
||||||
|
by_weekday []int // Days of week (0=Sunday)
|
||||||
|
by_monthday []int // Days of month
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum RecurrenceFreq {
|
||||||
|
none
|
||||||
|
daily
|
||||||
|
weekly
|
||||||
|
monthly
|
||||||
|
yearly
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct DBPlanning {
|
||||||
|
pub mut:
|
||||||
|
db &db.DB @[skip; str: skip]
|
||||||
|
}
|
||||||
|
|
||||||
|
@[params]
|
||||||
|
pub struct PlanningListArg {
|
||||||
|
pub mut:
|
||||||
|
is_public bool
|
||||||
|
limit int = 100 // Default limit is 100
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (self Planning) type_name() string {
|
||||||
|
return 'calendar'
|
||||||
|
}
|
||||||
|
|
||||||
|
// return example rpc call and result for each methodname
|
||||||
|
pub fn (self Planning) description(methodname string) string {
|
||||||
|
match methodname {
|
||||||
|
'set' {
|
||||||
|
return 'Create or update a calendar. Returns the ID of the calendar.'
|
||||||
|
}
|
||||||
|
'get' {
|
||||||
|
return 'Retrieve a calendar by ID. Returns the calendar object.'
|
||||||
|
}
|
||||||
|
'delete' {
|
||||||
|
return 'Delete a calendar by ID. Returns true if successful.'
|
||||||
|
}
|
||||||
|
'exist' {
|
||||||
|
return 'Check if a calendar exists by ID. Returns true or false.'
|
||||||
|
}
|
||||||
|
'list' {
|
||||||
|
return 'List all calendars. Returns an array of calendar objects.'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 'This is generic method for the root object, TODO fill in, ...'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return example rpc call and result for each methodname
|
||||||
|
pub fn (self Planning) example(methodname string) (string, string) {
|
||||||
|
match methodname {
|
||||||
|
'set' {
|
||||||
|
return '{"calendar": {"name": "My Planning", "description": "A personal calendar", "color": "#FF0000", "timezone": "UTC", "is_public": true, "events": []}}', '1'
|
||||||
|
}
|
||||||
|
'get' {
|
||||||
|
return '{"id": 1}', '{"name": "My Planning", "description": "A personal calendar", "color": "#FF0000", "timezone": "UTC", "is_public": true, "events": []}'
|
||||||
|
}
|
||||||
|
'delete' {
|
||||||
|
return '{"id": 1}', 'true'
|
||||||
|
}
|
||||||
|
'exist' {
|
||||||
|
return '{"id": 1}', 'true'
|
||||||
|
}
|
||||||
|
'list' {
|
||||||
|
return '{}', '[{"name": "My Planning", "description": "A personal calendar", "color": "#FF0000", "timezone": "UTC", "is_public": true, "events": []}]'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return '{}', '{}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (self Planning) dump(mut e encoder.Encoder) ! {
|
||||||
|
e.add_string(self.color)
|
||||||
|
e.add_string(self.timezone)
|
||||||
|
e.add_bool(self.is_public)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut self DBPlanning) load(mut o Planning, mut e encoder.Decoder) ! {
|
||||||
|
o.color = e.get_string()!
|
||||||
|
o.timezone = e.get_string()!
|
||||||
|
o.is_public = e.get_bool()!
|
||||||
|
}
|
||||||
|
|
||||||
|
@[params]
|
||||||
|
pub struct PlanningArg {
|
||||||
|
pub mut:
|
||||||
|
name string
|
||||||
|
description string
|
||||||
|
color string
|
||||||
|
timezone string
|
||||||
|
is_public bool
|
||||||
|
events []u32
|
||||||
|
}
|
||||||
|
|
||||||
|
// get new calendar, not from the DB
|
||||||
|
pub fn (mut self DBPlanning) new(args PlanningArg) !Planning {
|
||||||
|
mut o := Planning{
|
||||||
|
color: args.color
|
||||||
|
timezone: args.timezone
|
||||||
|
is_public: args.is_public
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set base fields
|
||||||
|
o.name = args.name
|
||||||
|
o.description = args.description
|
||||||
|
o.updated_at = ourtime.now().unix()
|
||||||
|
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut self DBPlanning) set(o Planning) !Planning {
|
||||||
|
// Use db set function which returns the object with assigned ID
|
||||||
|
return self.db.set[Planning](o)!
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut self DBPlanning) delete(id u32) ! {
|
||||||
|
self.db.delete[Planning](id)!
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut self DBPlanning) exist(id u32) !bool {
|
||||||
|
return self.db.exists[Planning](id)!
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut self DBPlanning) get(id u32) !Planning {
|
||||||
|
mut o, data := self.db.get_data[Planning](id)!
|
||||||
|
mut e_decoder := encoder.decoder_new(data)
|
||||||
|
self.load(mut o, mut e_decoder)!
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (mut self DBPlanning) list(args PlanningListArg) ![]Planning {
|
||||||
|
// Require at least one parameter to be provided
|
||||||
|
if !args.is_public {
|
||||||
|
return error('At least one filter parameter must be provided')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all calendars from the database
|
||||||
|
all_calendars := self.db.list[Planning]()!.map(self.get(it)!)
|
||||||
|
|
||||||
|
// Apply filters
|
||||||
|
mut filtered_calendars := []Planning{}
|
||||||
|
for calendar in all_calendars {
|
||||||
|
// Filter by is_public if provided (is_public is true)
|
||||||
|
if args.is_public && !calendar.is_public {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered_calendars << calendar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit results to 100 or the specified limit
|
||||||
|
mut limit := args.limit
|
||||||
|
if limit > 100 {
|
||||||
|
limit = 100
|
||||||
|
}
|
||||||
|
if filtered_calendars.len > limit {
|
||||||
|
return filtered_calendars[..limit]
|
||||||
|
}
|
||||||
|
|
||||||
|
return filtered_calendars
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user