Fix print preview event positioning to respond to hour range changes
- Add print_start_hour parameter to calculate_event_position function - Implement proper hour offset calculation for events in print mode - Remove CSS transform hacks for event positioning - Use dynamic pixels_per_hour for proper scaling with hour ranges - Increase modal max-width to 1600px for better visibility - Events now correctly reposition when start/end hours change 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -139,6 +139,7 @@ pub fn PrintPreviewModal(props: &PrintPreviewModalProps) -> Html {
|
||||
|
||||
// Calculate print dimensions for the current hour range
|
||||
let (base_unit, pixels_per_hour, _available_height) = calculate_print_dimensions(*start_hour, *end_hour, props.time_increment);
|
||||
|
||||
|
||||
html! {
|
||||
<div class="modal-backdrop print-preview-modal-backdrop" onclick={backdrop_click}>
|
||||
@@ -239,6 +240,7 @@ pub fn PrintPreviewModal(props: &PrintPreviewModalProps) -> Html {
|
||||
time_increment={props.time_increment}
|
||||
print_mode={true}
|
||||
print_pixels_per_hour={Some(pixels_per_hour)}
|
||||
print_start_hour={Some(*start_hour)}
|
||||
/>
|
||||
},
|
||||
ViewMode::Month => html! {
|
||||
|
||||
@@ -46,6 +46,8 @@ pub struct WeekViewProps {
|
||||
pub print_mode: bool,
|
||||
#[prop_or_default]
|
||||
pub print_pixels_per_hour: Option<f64>,
|
||||
#[prop_or_default]
|
||||
pub print_start_hour: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
@@ -730,7 +732,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
<div class="events-container">
|
||||
{
|
||||
day_events.iter().enumerate().filter_map(|(event_idx, event)| {
|
||||
let (start_pixels, duration_pixels, is_all_day) = calculate_event_position(event, *date, props.time_increment, props.print_pixels_per_hour);
|
||||
let (start_pixels, duration_pixels, is_all_day) = calculate_event_position(event, *date, props.time_increment, props.print_pixels_per_hour, props.print_start_hour);
|
||||
|
||||
// Skip all-day events (they're rendered in the header)
|
||||
if is_all_day {
|
||||
@@ -760,6 +762,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
let date_for_drag = *date;
|
||||
let time_increment = props.time_increment;
|
||||
let print_pixels_per_hour = props.print_pixels_per_hour;
|
||||
let print_start_hour = props.print_start_hour;
|
||||
Callback::from(move |e: MouseEvent| {
|
||||
e.stop_propagation(); // Prevent drag-to-create from starting on event clicks
|
||||
|
||||
@@ -773,7 +776,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
let click_y_relative = if click_y_relative > 0.0 { click_y_relative } else { e.offset_y() as f64 };
|
||||
|
||||
// Get event's current position in day column coordinates
|
||||
let (event_start_pixels, _, _) = calculate_event_position(&event_for_drag, date_for_drag, time_increment, print_pixels_per_hour);
|
||||
let (event_start_pixels, _, _) = calculate_event_position(&event_for_drag, date_for_drag, time_increment, print_pixels_per_hour, print_start_hour);
|
||||
let event_start_pixels = event_start_pixels as f64;
|
||||
|
||||
// Convert click position to day column coordinates
|
||||
@@ -1059,7 +1062,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
};
|
||||
|
||||
// Calculate positions for the preview
|
||||
let (original_start_pixels, _, _) = calculate_event_position(event, drag.start_date, props.time_increment, props.print_pixels_per_hour);
|
||||
let (original_start_pixels, _, _) = calculate_event_position(event, drag.start_date, props.time_increment, props.print_pixels_per_hour, props.print_start_hour);
|
||||
let original_duration = original_end.signed_duration_since(event.dtstart.with_timezone(&chrono::Local).naive_local());
|
||||
let original_end_pixels = original_start_pixels + (original_duration.num_minutes() as f32);
|
||||
|
||||
@@ -1089,7 +1092,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
let original_start = event.dtstart.with_timezone(&chrono::Local).naive_local();
|
||||
|
||||
// Calculate positions for the preview
|
||||
let (original_start_pixels, _, _) = calculate_event_position(event, drag.start_date, props.time_increment, props.print_pixels_per_hour);
|
||||
let (original_start_pixels, _, _) = calculate_event_position(event, drag.start_date, props.time_increment, props.print_pixels_per_hour, props.print_start_hour);
|
||||
|
||||
let new_end_pixels = drag.current_y;
|
||||
let new_height = (new_end_pixels - original_start_pixels as f64).max(20.0);
|
||||
@@ -1223,7 +1226,7 @@ fn pixels_to_time(pixels: f64, time_increment: u32) -> NaiveTime {
|
||||
NaiveTime::from_hms_opt(hours, minutes, 0).unwrap_or(NaiveTime::from_hms_opt(0, 0, 0).unwrap())
|
||||
}
|
||||
|
||||
fn calculate_event_position(event: &VEvent, date: NaiveDate, time_increment: u32, print_pixels_per_hour: Option<f64>) -> (f32, f32, bool) {
|
||||
fn calculate_event_position(event: &VEvent, date: NaiveDate, time_increment: u32, print_pixels_per_hour: Option<f64>, print_start_hour: Option<u32>) -> (f32, f32, bool) {
|
||||
// Convert UTC times to local time for display
|
||||
let local_start = event.dtstart.with_timezone(&Local);
|
||||
let event_date = local_start.date_naive();
|
||||
@@ -1243,15 +1246,23 @@ fn calculate_event_position(event: &VEvent, date: NaiveDate, time_increment: u32
|
||||
return (0.0, 30.0, true); // Position at top, 30px height, is_all_day = true
|
||||
}
|
||||
|
||||
// Calculate start position in pixels from midnight
|
||||
// Calculate start position in pixels
|
||||
let start_hour = local_start.hour() as f32;
|
||||
let start_minute = local_start.minute() as f32;
|
||||
let pixels_per_hour = if let Some(print_pph) = print_pixels_per_hour {
|
||||
print_pph as f32 // Use print mode calculation
|
||||
print_pph as f32 // Use the dynamic print mode calculation
|
||||
} else {
|
||||
if time_increment == 15 { 120.0 } else { 60.0 } // Default values
|
||||
};
|
||||
let start_pixels = (start_hour + start_minute / 60.0) * pixels_per_hour;
|
||||
|
||||
// In print mode, offset by the start hour to show relative position within visible range
|
||||
let hour_offset = if let Some(print_start) = print_start_hour {
|
||||
print_start as f32
|
||||
} else {
|
||||
0.0 // No offset for normal view (starts at midnight)
|
||||
};
|
||||
|
||||
let start_pixels = ((start_hour + start_minute / 60.0) - hour_offset) * pixels_per_hour;
|
||||
|
||||
// Calculate duration and height
|
||||
let duration_pixels = if let Some(end) = event.dtend {
|
||||
@@ -1260,19 +1271,19 @@ fn calculate_event_position(event: &VEvent, date: NaiveDate, time_increment: u32
|
||||
|
||||
// Handle events that span multiple days by capping at midnight
|
||||
if end_date > date {
|
||||
// Event continues past midnight, cap at 24:00
|
||||
let max_pixels = 24.0 * pixels_per_hour;
|
||||
max_pixels - start_pixels
|
||||
// Event continues past midnight, cap at end of visible range
|
||||
let max_hour = if let Some(_print_start) = print_start_hour { 24.0 } else { 24.0 };
|
||||
let max_pixels = (max_hour - hour_offset) * pixels_per_hour;
|
||||
(max_pixels - start_pixels).max(20.0)
|
||||
} else {
|
||||
let end_hour = local_end.hour() as f32;
|
||||
let end_minute = local_end.minute() as f32;
|
||||
let end_pixels = (end_hour + end_minute / 60.0) * pixels_per_hour;
|
||||
let end_pixels = ((end_hour + end_minute / 60.0) - hour_offset) * pixels_per_hour;
|
||||
(end_pixels - start_pixels).max(20.0) // Minimum 20px height
|
||||
}
|
||||
} else {
|
||||
pixels_per_hour // Default 1 hour if no end time
|
||||
};
|
||||
|
||||
(start_pixels, duration_pixels, false) // is_all_day = false
|
||||
}
|
||||
|
||||
@@ -1313,7 +1324,7 @@ fn calculate_event_layout(events: &[VEvent], date: NaiveDate, time_increment: u3
|
||||
return None;
|
||||
}
|
||||
|
||||
let (_, _, _) = calculate_event_position(event, date, time_increment, None);
|
||||
let (_, _, _) = calculate_event_position(event, date, time_increment, None, None);
|
||||
let local_start = event.dtstart.with_timezone(&Local);
|
||||
let event_date = local_start.date_naive();
|
||||
if event_date == date ||
|
||||
|
||||
Reference in New Issue
Block a user