Packages
ash_admin
0.13.19
1.1.0
1.0.0-rc.0
0.14.0
0.13.26
0.13.25
0.13.24
0.13.23
0.13.22
0.13.21
0.13.20
0.13.19
0.13.18
0.13.17
0.13.16
0.13.15
0.13.14
0.13.13
0.13.12
0.13.11
0.13.10
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.6
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.11
0.11.10
0.11.9
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.12
0.10.11
0.10.10
retired
0.10.10-rc.1
0.10.10-rc.0
0.10.9
0.10.8
0.10.7
0.10.6
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0-rc.2
0.6.0-rc.1
0.6.0-rc.0
0.5.2
0.5.1-rc.0
0.5.0
0.4.5-rc.0
0.4.4
0.4.2
0.4.0
0.3.0-rc.0
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16-rc.1
0.2.16-rc.0
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.1
0.1.6
0.1.5
0.1.3
0.1.2
0.1.0
A super-admin UI for Ash Framework, built with Phoenix LiveView.
Current section
Files
Jump to
Current section
Files
lib/ash_admin/components/layouts.ex
defmodule AshAdmin.Layouts do
@moduledoc false
use AshAdmin.Web, :html
use Phoenix.Component
phoenix_js_paths =
for app <- ~w(phoenix phoenix_html phoenix_live_view)a do
path = Application.app_dir(app, ["priv", "static", "#{app}.js"])
Module.put_attribute(__MODULE__, :external_resource, path)
path
end
@static_path Application.app_dir(:ash_admin, ["priv", "static"])
@vendor_path Application.app_dir(:ash_admin, ["priv", "vendor"])
@external_resource js_path = Path.join(@static_path, "assets/app.js")
@external_resource css_path = Path.join(@static_path, "assets/app.css")
# Vendor files
@external_resource easymde_js_path = Path.join(@vendor_path, "easymde.min.js")
@external_resource easymde_css_path = Path.join(@vendor_path, "easymde.min.css")
@external_resource jsoneditor_js_path = Path.join(@vendor_path, "jsoneditor.min.js")
@external_resource jsoneditor_css_path = Path.join(@vendor_path, "jsoneditor.min.css")
@app_js """
#{for path <- phoenix_js_paths, do: path |> File.read!() |> String.replace("//# sourceMappingURL=", "// ")}
#{File.read!(js_path)}
"""
@app_css File.read!(css_path)
# Read vendor files at compile time
@easymde_js if File.exists?(easymde_js_path), do: File.read!(easymde_js_path), else: ""
@easymde_css if File.exists?(easymde_css_path), do: File.read!(easymde_css_path), else: ""
@jsoneditor_js if File.exists?(jsoneditor_js_path), do: File.read!(jsoneditor_js_path), else: ""
@jsoneditor_css if File.exists?(jsoneditor_css_path),
do: File.read!(jsoneditor_css_path),
else: ""
def render("app.js", _), do: @app_js
def render("app.css", _), do: @app_css
def render("easymde.js", _), do: @easymde_js
def render("easymde.css", _), do: @easymde_css
def render("jsoneditor.js", _), do: @jsoneditor_js
def render("jsoneditor.css", _), do: @jsoneditor_css
def render("root.html", assigns) do
~H"""
<!DOCTYPE html>
<html lang="en" phx-socket={live_socket_path(@conn)}>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
<meta name="csrf-token" content={get_csrf_token()} />
<title>{assigns[:page_title] || "Ash Admin"}</title>
<style nonce={csp_nonce(@conn, :style)}>
<%= raw(render("app.css", %{})) %>
</style>
<style nonce={csp_nonce(@conn, :style)}>
<%= raw(render("jsoneditor.css", %{})) %>
</style>
<style nonce={csp_nonce(@conn, :style)}>
<%= raw(render("easymde.css", %{})) %>
</style>
<script nonce={csp_nonce(@conn, :script)}>
<%= raw(render("jsoneditor.js", %{})) %>
</script>
<script nonce={csp_nonce(@conn, :script)}>
<%= raw(render("easymde.js", %{})) %>
</script>
</head>
<body>
{@inner_content}
</body>
<script nonce={csp_nonce(@conn, :script)}>
<%= raw(render("app.js", %{})) %>
</script>
</html>
"""
end
def render(assigns) do
~H"""
...
"""
end
def live_socket_path(conn) do
[Enum.map(conn.script_name, &["/" | &1]) | conn.private.live_socket_path]
end
defp csp_nonce(conn, type) when type in [:script, :style, :img] do
csp_nonce_value = conn.private.ash_admin_csp_nonce[type]
case csp_nonce_value do
key when is_atom(key) -> conn.assigns[csp_nonce_value]
key when is_bitstring(key) -> csp_nonce_value
_ -> raise("Unexpected type of :csp_nonce_assign_key")
end
end
end