defmodule ToweropsWeb.Layouts do
@moduledoc """
This module holds layouts and related functionality
used by your application.
"""
use ToweropsWeb, :html
alias ToweropsWeb.Components.ConsentPrompt
alias ToweropsWeb.Components.CookieConsent
alias ToweropsWeb.Live.Components.GlobalSearchComponent
require Logger
# Embed all files in layouts/* within this module.
# The default root.html.heex file contains the HTML
# skeleton of your application, namely HTML headers
# and other static content.
embed_templates "layouts/*"
@doc """
Renders your app layout.
This function is typically invoked from every template,
and it often contains your application menu, sidebar,
or similar.
## Examples
Content
"""
attr :flash, :map, required: true, doc: "the map of flash messages"
attr :current_scope, :map,
default: nil,
doc: "the current [scope](https://hexdocs.pm/phoenix/scopes.html)"
attr :timezone, :string, default: "UTC", doc: "the user's timezone"
attr :requires_cookie_consent, :boolean,
default: false,
doc: "whether to show the cookie consent banner"
slot :inner_block, required: true
def app(assigns) do
# Get cookie consent from process dictionary (set in plug for non-authenticated pages)
requires_cookie_consent = Process.get(:requires_cookie_consent, false)
assigns = Map.put(assigns, :requires_cookie_consent, requires_cookie_consent)
~H"""
<.flash_group flash={@flash} />
"""
end
@doc """
Renders the authenticated app layout with navigation.
Use this for pages that require organization context.
## Examples
Content
"""
attr :flash, :map, required: true, doc: "the map of flash messages"
attr :current_scope, :map,
default: nil,
doc: "the current scope (contains user, organization, timezone, and impersonation state)"
attr :active_page, :string,
default: nil,
doc: "the currently active page (dashboard, sites, device, or alerts)"
slot :inner_block, required: true
def authenticated(assigns) do
# Get cookie consent from process dictionary (set in on_mount hook)
requires_cookie_consent = Process.get(:requires_cookie_consent, false)
assigns = Map.put(assigns, :requires_cookie_consent, requires_cookie_consent)
# Extract organization and timezone from scope for template convenience
current_organization = assigns[:current_scope] && assigns.current_scope.organization
timezone = (assigns[:current_scope] && assigns.current_scope.timezone) || "UTC"
# Get policies needing consent from assigns (set in CheckPolicyConsent plug)
policies_needing_consent = Map.get(assigns, :policies_needing_consent, [])
# Check if this is the help page for banner display
always_show_banner = if Map.get(assigns, :active_page) == "help", do: "true", else: "false"
assigns =
assigns
|> Map.put(:current_organization, current_organization)
|> Map.put(:timezone, timezone)
|> Map.put(:policies_needing_consent, policies_needing_consent)
|> Map.put(:always_show_banner, always_show_banner)
~H"""
<%= if @current_scope && @current_scope.impersonating? do %>
We'd love to hear your feedback, suggestions, or help you with any questions. Please email us at
hi@towerops.net
for support, feature requests, or just to say hello!
"""
end
@doc """
Provides dark vs light theme toggle based on themes defined in app.css.
See in root.html.heex which applies the theme before page load.
"""
def theme_toggle(assigns) do
~H"""
JS.set_attribute({"aria-expanded", "false"}, to: "#theme-menu-button")
}
>
"""
end
@doc """
Renders the admin layout.
Use this for admin pages that require superuser access.
## Examples
Admin Content
"""
attr :flash, :map, required: true, doc: "the map of flash messages"
attr :timezone, :string, default: "UTC", doc: "the user's timezone"
attr :requires_cookie_consent, :boolean,
default: false,
doc: "whether to show the cookie consent banner"
slot :inner_block, required: true
def admin(assigns) do
# Get cookie consent from process dictionary (set in on_mount hook)
requires_cookie_consent = Process.get(:requires_cookie_consent, false)
assigns = Map.put(assigns, :requires_cookie_consent, requires_cookie_consent)
~H"""