Files
sure/app/views/layouts/shared/_htmldoc.html.erb
T

81 lines
3.7 KiB
ERB

<%# locals: (sidebar_aware: false) %>
<!DOCTYPE html>
<% theme = Current.user&.theme || "system" %>
<html
lang="en"
data-theme="<%= theme %>"
data-controller="theme viewport"
data-theme-user-preference-value="<%= Current.user&.theme || "system" %>"
class="h-[var(--app-height, 100dvh)] text-primary bg-surface overflow-hidden overscroll-none font-sans <%= @os %>">
<head>
<%= render "layouts/shared/head" %>
<%= yield :head %>
</head>
<body class="h-[var(--app-height)] overflow-hidden antialiased"<% if sidebar_aware %> data-controller="notification-tray"<% end %>>
<% if Rails.env.development? %>
<button hidden data-controller="hotkey" data-hotkey="t t /" data-action="theme#toggle"></button>
<% end %>
<% if Current.family %>
<%= turbo_stream_from Current.family %>
<% end %>
<%= turbo_frame_tag "modal" %>
<%= turbo_frame_tag "drawer" %>
<%# Custom overrides for browser's confirm API %>
<%= render "layouts/shared/confirm_dialog" %>
<% super_admin_bar_visible = Current.true_user&.super_admin? && show_super_admin_bar? %>
<% approval_bar_visible = Current.true_user&.impersonated_support_sessions&.initiated&.any? %>
<%= render "impersonation_sessions/super_admin_bar" if super_admin_bar_visible %>
<%= render "impersonation_sessions/approval_bar" if approval_bar_visible %>
<%# Only surface the Sidekiq nudge to operators who can act on it. The
Redis round-trip and banner render are both skipped for non-super-admins
and for managed-mode deployments — `current_sidekiq_health` returns
nil in those cases. %>
<% if Current.user&.super_admin? && current_sidekiq_health && !current_sidekiq_health.healthy? %>
<% if sidebar_aware %>
<% content_for :system_alerts do %>
<div class="mx-auto w-full max-w-2xl">
<%= render "shared/sidekiq_health_banner", health: current_sidekiq_health %>
</div>
<% end %>
<% else %>
<%# Stack below any sticky impersonation bars instead of hard-coding
80px (`top-20`). Each bar is ~60px tall (`py-4` + content), so
adjust the fixed offset based on how many are visible. %>
<% banner_top_class = if super_admin_bar_visible && approval_bar_visible
"top-36"
elsif super_admin_bar_visible || approval_bar_visible
"top-20"
else
"top-4"
end %>
<div class="fixed z-40 <%= banner_top_class %> left-1/2 -translate-x-1/2 w-full max-w-2xl px-4">
<%= render "shared/sidekiq_health_banner", health: current_sidekiq_health %>
</div>
<% end %>
<% end %>
<%= yield %>
<%# `left-1/2 -translate-x-1/2` centers on the viewport by default, correct
for every single-column layout. Layouts with a persistent sidebar
(settings, application) pass sidebar_aware: true, which wires up
notification_tray_controller.js to override `left` with the actual
content pane's center instead — see that controller for why a
ResizeObserver beats hand-rolled sidebar-width math, and for why it
also has to guard that inline style against turbo_refreshes_with's
morph reconciliation. %>
<div class="fixed z-50 top-6 md:top-4 left-1/2 -translate-x-1/2 w-full md:w-80 px-4 md:px-0 mx-auto md:mx-0 md:right-auto pt-[env(safe-area-inset-top)]"<% if sidebar_aware %> data-notification-tray-target="tray" data-action="turbo:before-morph-attribute->notification-tray#preserveStyle"<% end %>>
<%= render "layouts/shared/notification_tray" %>
</div>
</body>
</html>