Full Printing Now Available (with some bugs) #20
@@ -1128,7 +1128,7 @@
|
||||
.print-preview-paper[data-start-hour="7"][data-end-hour="19"]:has(.time-slot.quarter-mode) .time-labels,
|
||||
.print-preview-paper[data-start-hour="7"][data-end-hour="19"]:has(.time-slot.quarter-mode) .week-days-grid { min-height: 1530px !important; }
|
||||
|
||||
/* Print Page Setup - Force landscape orientation */
|
||||
/* Print Page Setup - Force landscape orientation and fit to page */
|
||||
@page {
|
||||
size: landscape;
|
||||
margin: 0.5in;
|
||||
@@ -1136,6 +1136,11 @@
|
||||
|
||||
/* Print Media Rules - Show only the print-preview-copy when printing */
|
||||
@media print {
|
||||
html {
|
||||
print-color-adjust: exact; /* Preserve colors when printing */
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
|
||||
/* Hide all top-level app content */
|
||||
.app {
|
||||
display: none !important;
|
||||
@@ -1147,11 +1152,19 @@
|
||||
position: absolute !important;
|
||||
left: 0 !important;
|
||||
top: 0 !important;
|
||||
width: 960px !important;
|
||||
height: 720px !important;
|
||||
/* width: 960px !important; */
|
||||
/* height: 720px !important; */
|
||||
aspect-ratio: 1.2941176470588236 !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
box-sizing: border-box !important;
|
||||
/* Properties to help browsers scale to fit page */
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
object-fit: contain;
|
||||
page-break-inside: avoid;
|
||||
orphans: 1;
|
||||
widows: 1;
|
||||
}
|
||||
|
||||
/* Ensure print content uses the full page */
|
||||
|
||||
@@ -106,8 +106,8 @@ pub fn PrintPreviewModal(props: &PrintPreviewModalProps) -> Html {
|
||||
{
|
||||
let start_hour = *start_hour;
|
||||
let end_hour = *end_hour;
|
||||
let base_unit_value = base_unit;
|
||||
let pixels_per_hour_value = pixels_per_hour;
|
||||
let time_increment = props.time_increment;
|
||||
let original_base_unit = base_unit;
|
||||
use_effect(move || {
|
||||
if let Some(window) = web_sys::window() {
|
||||
if let Some(document) = window.document() {
|
||||
@@ -115,8 +115,6 @@ pub fn PrintPreviewModal(props: &PrintPreviewModalProps) -> Html {
|
||||
if let Some(document_element) = document.document_element() {
|
||||
if let Some(html_element) = document_element.dyn_ref::<web_sys::HtmlElement>() {
|
||||
let style = html_element.style();
|
||||
let _ = style.set_property("--print-base-unit", &format!("{:.2}", base_unit_value));
|
||||
let _ = style.set_property("--print-pixels-per-hour", &format!("{:.2}", pixels_per_hour_value));
|
||||
let _ = style.set_property("--print-start-hour", &start_hour.to_string());
|
||||
let _ = style.set_property("--print-end-hour", &end_hour.to_string());
|
||||
}
|
||||
@@ -132,22 +130,80 @@ pub fn PrintPreviewModal(props: &PrintPreviewModalProps) -> Html {
|
||||
print_copy.set_inner_html("");
|
||||
let _ = print_copy.append_child(&content_clone);
|
||||
|
||||
// Copy the CSS variables and data attributes from the print-preview-paper
|
||||
if let Some(preview_paper) = document.query_selector(".print-preview-paper").ok().flatten() {
|
||||
if let Some(_paper_element) = preview_paper.dyn_ref::<web_sys::HtmlElement>() {
|
||||
// Copy CSS custom properties (variables)
|
||||
if let Some(print_copy_html) = print_copy.dyn_ref::<web_sys::HtmlElement>() {
|
||||
let style = print_copy_html.style();
|
||||
let _ = style.set_property("--print-start-hour", &start_hour.to_string());
|
||||
let _ = style.set_property("--print-end-hour", &end_hour.to_string());
|
||||
let _ = style.set_property("--print-base-unit", &format!("{:.2}", base_unit_value));
|
||||
let _ = style.set_property("--print-pixels-per-hour", &format!("{:.2}", pixels_per_hour_value));
|
||||
// Get the actual rendered height of the print copy div and recalculate base-unit
|
||||
if let Some(print_copy_html) = print_copy.dyn_ref::<web_sys::HtmlElement>() {
|
||||
// Temporarily make visible to measure height, then hide again
|
||||
let original_display = print_copy_html.style().get_property_value("display").unwrap_or_default();
|
||||
let _ = print_copy_html.style().set_property("display", "block");
|
||||
let _ = print_copy_html.style().set_property("visibility", "hidden");
|
||||
let _ = print_copy_html.style().set_property("position", "absolute");
|
||||
let _ = print_copy_html.style().set_property("top", "-9999px");
|
||||
|
||||
// Now measure the height
|
||||
let actual_height = print_copy_html.client_height() as f64;
|
||||
|
||||
// Restore original display
|
||||
let _ = print_copy_html.style().set_property("display", &original_display);
|
||||
let _ = print_copy_html.style().remove_property("visibility");
|
||||
let _ = print_copy_html.style().remove_property("position");
|
||||
let _ = print_copy_html.style().remove_property("top");
|
||||
|
||||
// Recalculate base-unit and pixels-per-hour based on actual height
|
||||
let visible_hours = (end_hour - start_hour) as f64;
|
||||
let slots_per_hour = if time_increment == 15 { 4.0 } else { 2.0 };
|
||||
let header_height = 50.0;
|
||||
let header_border = 2.0;
|
||||
let container_spacing = 8.0;
|
||||
let total_overhead = header_height + header_border + container_spacing;
|
||||
let available_height = actual_height - total_overhead;
|
||||
let actual_base_unit = available_height / (visible_hours * slots_per_hour);
|
||||
let actual_pixels_per_hour = actual_base_unit * slots_per_hour;
|
||||
|
||||
|
||||
// Set CSS variables with recalculated values
|
||||
let style = print_copy_html.style();
|
||||
let _ = style.set_property("--print-base-unit", &format!("{:.2}", actual_base_unit));
|
||||
let _ = style.set_property("--print-pixels-per-hour", &format!("{:.2}", actual_pixels_per_hour));
|
||||
let _ = style.set_property("--print-start-hour", &start_hour.to_string());
|
||||
let _ = style.set_property("--print-end-hour", &end_hour.to_string());
|
||||
|
||||
// Copy data attributes
|
||||
let _ = print_copy.set_attribute("data-start-hour", &start_hour.to_string());
|
||||
let _ = print_copy.set_attribute("data-end-hour", &end_hour.to_string());
|
||||
|
||||
// Recalculate event positions using the new base-unit
|
||||
let events = print_copy.query_selector_all(".week-event").unwrap();
|
||||
let scale_factor = actual_base_unit / original_base_unit;
|
||||
|
||||
for i in 0..events.length() {
|
||||
if let Some(event_element) = events.get(i) {
|
||||
if let Some(event_html) = event_element.dyn_ref::<web_sys::HtmlElement>() {
|
||||
let event_style = event_html.style();
|
||||
|
||||
// Get current positioning values and recalculate
|
||||
if let Ok(current_top) = event_style.get_property_value("top") {
|
||||
if current_top.ends_with("px") {
|
||||
if let Ok(top_px) = current_top[..current_top.len()-2].parse::<f64>() {
|
||||
let new_top = top_px * scale_factor;
|
||||
let _ = event_style.set_property("top", &format!("{:.2}px", new_top));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(current_height) = event_style.get_property_value("height") {
|
||||
if current_height.ends_with("px") {
|
||||
if let Ok(height_px) = current_height[..current_height.len()-2].parse::<f64>() {
|
||||
let new_height = height_px * scale_factor;
|
||||
let _ = event_style.set_property("height", &format!("{:.2}px", new_height));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy data attributes
|
||||
let _ = print_copy.set_attribute("data-start-hour", &start_hour.to_string());
|
||||
let _ = print_copy.set_attribute("data-end-hour", &end_hour.to_string());
|
||||
}
|
||||
|
||||
web_sys::console::log_1(&format!("Height: {:.2}, Original base-unit: {:.2}, New base-unit: {:.2}, Scale factor: {:.2}",
|
||||
actual_height, original_base_unit, actual_base_unit, scale_factor).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user