From 83cdbe7c7c3205db8c3e8417fd8e4864c20d6810 Mon Sep 17 00:00:00 2001 From: Rick Barrette Date: Thu, 6 Aug 2026 20:58:10 -0400 Subject: [PATCH] Refactor appointment display and styles for improved layout and tooltip functionality --- .../_calendar_event.html.erb | 61 ++----- assets/stylesheets/customer_ appointments.css | 164 ------------------ assets/stylesheets/customer_appointments.css | 116 +++++++++++++ 3 files changed, 130 insertions(+), 211 deletions(-) delete mode 100644 assets/stylesheets/customer_ appointments.css create mode 100644 assets/stylesheets/customer_appointments.css diff --git a/app/views/customer_appointments/_calendar_event.html.erb b/app/views/customer_appointments/_calendar_event.html.erb index 292620a..5607588 100644 --- a/app/views/customer_appointments/_calendar_event.html.erb +++ b/app/views/customer_appointments/_calendar_event.html.erb @@ -1,69 +1,36 @@ -<% -day_hours = 8.0 -day_height = 120 +<%= tag.div class: ['appointment-block', 'tooltip', appointment.status.to_s.parameterize] do %> -hours = appointment.estimated_hours.to_f -height = [(hours / day_hours * day_height).round, 26].max -%> - -<%= tag.div class: ['appointment-block', 'tooltip'], - style: "height: #{height}px;" do %> +
- <% if appointment.user %> - <%= avatar( - appointment.user, - size: 20, - class: "appointment-avatar" - ) %> + <%= avatar(appointment.user, size: 14, class: "appointment-avatar") %> <% end %> -
- <%= link_to( - appointment.subject, - customer_appointment_path(appointment), - class: "appointment-link" - ) %> -
+ + <%= link_to(appointment.subject, customer_appointment_path(appointment), class: "appointment-link") %> + + + <%= number_with_precision(appointment.estimated_hours.to_f, precision: 1) %>h +
<% if appointment.customer %> -
+
<%= appointment.customer.name %> + <% if appointment.vehicle %> + - <%= appointment.vehicle.name %> + <% end %>
<% end %> - <% if appointment.vehicle %> -
- <%= appointment.vehicle.name %> -
- <% end %> - - -
- <%= render( - partial: "customer_appointments/tooltip", - locals: { appointment: appointment } - ) %> + <%= render partial: "customer_appointments/tooltip", locals: { appointment: appointment } %> <% end %> \ No newline at end of file diff --git a/assets/stylesheets/customer_ appointments.css b/assets/stylesheets/customer_ appointments.css deleted file mode 100644 index c8ae757..0000000 --- a/assets/stylesheets/customer_ appointments.css +++ /dev/null @@ -1,164 +0,0 @@ -.appointment-block { - margin:2px; - padding:4px; - - border-left:5px solid #3c78d8; - background:#edf4ff; - border-radius:4px; - - overflow: visible; - - position: relative; - - font-size:11px; - transition:.15s; -} - -/* Customer appointment tooltip */ -.appointment-block .tip { - width: 420px; - max-width: 420px; - - min-height: 250px; - - padding: 12px; - - white-space: normal; - overflow: visible; - - z-index: 10000; -} - -.appointment-block .tip table.attributes { - width: 100%; - table-layout: fixed; -} - -.appointment-block .tip th { - width: 120px; - white-space: nowrap; - vertical-align: top; - text-align: left; -} - -.appointment-block .tip td { - white-space: normal; - word-break: break-word; -} - -/* .appointment-block .tip th { - width: 90px; - font-weight: bold; -} - -.appointment-block .tip td { - width: auto; -} */ - -.appointment-block .tip h3 { - margin: 0 0 8px; - font-size: 22px; -} - -.appointment-block .tip .subtitle { - margin-bottom: 12px; -} - -.appointment-block:hover{ - - transform:scale(1.02); - - box-shadow:0 2px 6px rgba(0,0,0,.25); - - z-index:100; - - position:relative; -} - -.appointment-link{ - - color:inherit; - - text-decoration:none; - - display:block; - - height:100%; -} - -.appointment-header{ - - display:flex; - - align-items:center; - - gap:6px; - - font-weight:bold; -} - -.appointment-avatar{ - - flex-shrink:0; -} - -.appointment-title{ - - overflow:hidden; - - text-overflow:ellipsis; - - white-space:nowrap; -} - -.appointment-customer{ - - margin-top:3px; - - color:#555; - - font-size:10px; -} - -.appointment-footer{ - - margin-top:6px; - - display:flex; - - justify-content:space-between; - - font-size:10px; - - font-weight:bold; -} - -.appointment-block.scheduled{ - border-left-color:#1f77d0; -} - -.appointment-block.in-progress{ - border-left-color:#e68a00; - background:#fff4df; -} - -.appointment-block.completed{ - border-left-color:#2d8a34; - background:#edf9ee; -} - -.tip table.attributes { - width: 100%; - border-collapse: collapse; -} - -.tip table.attributes th { - text-align: left; - padding-right: 10px; - white-space: nowrap; - font-weight: bold; -} - -.tip table.attributes td { - padding: 2px 0; -} \ No newline at end of file diff --git a/assets/stylesheets/customer_appointments.css b/assets/stylesheets/customer_appointments.css new file mode 100644 index 0000000..9e53aec --- /dev/null +++ b/assets/stylesheets/customer_appointments.css @@ -0,0 +1,116 @@ +/* Container Box */ +.appointment-block { + position: relative; + display: flex; + align-items: stretch; + box-sizing: border-box; + margin: 2px 0; + padding: 3px 4px 3px 0; + background: #edf4ff; + border: 1px solid #c5d8f3; + border-radius: 3px; + font-size: 10px; + line-height: 1.2; + overflow: visible !important; /* CRITICAL: Allows tooltip popover to extend outside */ + max-width: 100%; +} + +/* Left Indicator Bar */ +.appointment-block .appointment-bar { + width: 4px; + background-color: #3c78d8; + flex-shrink: 0; + margin-right: 4px; + border-radius: 1px; +} + +/* Status Colors */ +.appointment-block.scheduled .appointment-bar { background-color: #1f77d0; } +.appointment-block.scheduled { background: #edf4ff; border-color: #c5d8f3; } + +.appointment-block.in-progress .appointment-bar { background-color: #e68a00; } +.appointment-block.in-progress { background: #fff4df; border-color: #fce2b6; } + +.appointment-block.completed .appointment-bar { background-color: #2d8a34; } +.appointment-block.completed { background: #edf9ee; border-color: #c7eecb; } + +.appointment-block.cancelled .appointment-bar { background-color: #d9534f; } +.appointment-block.cancelled { background: #fdf2f2; border-color: #f8c8c8; } + +/* Card Content Area - Contains text overflow inside the card */ +.appointment-card { + display: flex; + flex-direction: column; + flex-grow: 1; + min-width: 0; + overflow: hidden; /* Truncates long text cleanly inside the card */ +} + +.appointment-header { + display: flex; + align-items: center; + gap: 4px; + font-weight: bold; + min-width: 0; +} + +.appointment-avatar { + flex-shrink: 0; + border-radius: 2px; +} + +.appointment-title { + flex-grow: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + min-width: 0; +} + +.appointment-link { + color: #111; + text-decoration: none; +} + +.appointment-hours { + flex-shrink: 0; + color: #444; + font-size: 9px; + font-weight: bold; + margin-left: auto; +} + +.appointment-detail { + color: #555; + font-size: 9px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-top: 1px; + min-width: 0; +} + +/* Hover Effect */ +.appointment-block:hover { + z-index: 999; +} + +/* Redmine Tooltip Positioning & Visibility Fixes */ +.appointment-block .tip { + display: none; + position: absolute; + top: 100%; + left: 0; + width: 320px; + padding: 10px; + background: #ffffff; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); + white-space: normal; + z-index: 10000 !important; +} + +.appointment-block:hover .tip { + display: block; +} \ No newline at end of file