upgrade to phoenix 1.7
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-04-13 23:29:29 -04:00
parent a1c846be33
commit 63d854ffbe
116 changed files with 1156 additions and 1111 deletions

View File

@ -88,11 +88,9 @@ defmodule MemexWeb.Components.ContextsTableComponent do
@spec get_value_for_key(atom(), Context.t(), additional_data :: map()) ::
any() | {any(), Rendered.t()}
defp get_value_for_key(:slug, %{slug: slug}, _additional_data) do
assigns = %{slug: slug}
defp get_value_for_key(:slug, %{slug: slug} = assigns, _additional_data) do
slug_block = ~H"""
<.link navigate={Routes.context_show_path(Endpoint, :show, @slug)} class="link">
<.link navigate={~p"/context/#{@slug}"} class="link">
<%= @slug %>
</.link>
"""
@ -100,16 +98,10 @@ defmodule MemexWeb.Components.ContextsTableComponent do
{slug, slug_block}
end
defp get_value_for_key(:tags, %{tags: tags}, _additional_data) do
assigns = %{tags: tags}
defp get_value_for_key(:tags, assigns, _additional_data) do
~H"""
<div class="flex flex-wrap justify-center space-x-1">
<.link
:for={tag <- @tags}
patch={Routes.context_index_path(Endpoint, :search, tag)}
class="link"
>
<.link :for={tag <- @tags} patch={~p"/contexts/#{tag}"} class="link">
<%= tag %>
</.link>
</div>

View File

@ -3,13 +3,13 @@ defmodule MemexWeb.CoreComponents do
Provides core UI components.
"""
use Phoenix.Component
import MemexWeb.{Gettext, ViewHelpers}
use MemexWeb, :verified_routes
import MemexWeb.{Gettext, HTMLHelpers}
alias Memex.{Accounts, Accounts.Invite, Accounts.User}
alias Memex.Contexts.Context
alias Memex.Notes.Note
alias Memex.Pipelines.Steps.Step
alias MemexWeb.{Endpoint, HomeLive}
alias MemexWeb.Router.Helpers, as: Routes
alias Phoenix.HTML
alias Phoenix.LiveView.JS
@ -31,13 +31,13 @@ defmodule MemexWeb.CoreComponents do
## Examples
<.modal return_to={Routes.<%= schema.singular %>_index_path(Endpoint, :index)}>
<.modal return_to={~p"/\#{<%= schema.plural %>}"}>
<.live_component
module={<%= inspect context.web_module %>.<%= inspect Module.concat(schema.web_namespace, schema.alias) %>Live.FormComponent}
id={@<%= schema.singular %>.id || :new}
title={@page_title}
action={@live_action}
return_to={Routes.<%= schema.singular %>_index_path(Endpoint, :index)}
return_to={~p"/\#{<%= schema.singular %>}"}
<%= schema.singular %>: @<%= schema.singular %>
/>
</.modal>
@ -167,7 +167,7 @@ defmodule MemexWeb.CoreComponents do
link =
HTML.Link.link(
"[[#{slug}]]",
to: Routes.note_show_path(Endpoint, :show, slug),
to: ~p"/note/#{slug}",
class: "link inline",
data: [qa: "#{data_qa_prefix}-#{slug}"]
)

View File

@ -24,7 +24,7 @@
<% end %>
<.qr_code
content={Routes.user_registration_url(Endpoint, :new, invite: @invite.token)}
content={url(MemexWeb.Endpoint, ~p"/users/register?invite=#{@invite.token}")}
filename={@invite.name}
/>
@ -38,7 +38,7 @@
class="mx-2 my-1 text-xs px-4 py-2 rounded-lg text-center break-all
text-primary-400 bg-primary-800"
phx-no-format
><%= Routes.user_registration_url(Endpoint, :new, invite: @invite.token) %></code>
><%= url(MemexWeb.Endpoint, ~p"/users/register?invite=#{@invite.token}") %></code>
<%= if @code_actions, do: render_slot(@code_actions) %>
</div>

View File

@ -1,10 +1,7 @@
<nav role="navigation" class="mb-8 px-8 py-4 w-full bg-primary-900 text-primary-400">
<div class="flex flex-col sm:flex-row justify-between items-center">
<div class="mb-4 sm:mb-0 sm:mr-8 flex flex-row justify-start items-center space-x-2">
<.link
navigate={Routes.live_path(Endpoint, HomeLive)}
class="mx-2 my-1 leading-5 text-xl text-primary-400 hover:underline"
>
<.link navigate={~p"/"} class="mx-2 my-1 leading-5 text-xl text-primary-400 hover:underline">
<%= gettext("memEx") %>
</.link>
@ -21,28 +18,19 @@
<ul class="flex flex-row flex-wrap justify-center items-center
text-lg text-primary-400 text-ellipsis">
<li class="mx-2 my-1">
<.link
navigate={Routes.note_index_path(Endpoint, :index)}
class="text-primary-400 hover:underline truncate"
>
<.link navigate={~p"/notes"} class="text-primary-400 hover:underline truncate">
<%= gettext("notes") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
navigate={Routes.context_index_path(Endpoint, :index)}
class="text-primary-400 hover:underline truncate"
>
<.link navigate={~p"/contexts"} class="text-primary-400 hover:underline truncate">
<%= gettext("contexts") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
navigate={Routes.pipeline_index_path(Endpoint, :index)}
class="text-primary-400 hover:underline truncate"
>
<.link navigate={~p"/pipelines"} class="text-primary-400 hover:underline truncate">
<%= gettext("pipelines") %>
</.link>
</li>
@ -51,25 +39,19 @@
<%= if @current_user do %>
<li :if={@current_user |> Accounts.is_already_admin?()} class="mx-2 my-1">
<.link
navigate={Routes.invite_index_path(Endpoint, :index)}
class="text-primary-400 hover:underline"
>
<.link navigate={~p"/invites"} class="text-primary-400 hover:underline">
<%= gettext("invites") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
navigate={Routes.user_settings_path(Endpoint, :edit)}
class="text-primary-400 hover:underline truncate"
>
<.link navigate={~p"/users/settings"} class="text-primary-400 hover:underline truncate">
<%= @current_user.email %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
href={Routes.user_session_path(Endpoint, :delete)}
href={~p"/users/log_out"}
method="delete"
data-confirm={dgettext("prompts", "are you sure you want to log out?")}
aria-label={gettext("log out")}
@ -84,7 +66,7 @@
class="mx-2 my-1"
>
<.link
navigate={Routes.live_dashboard_path(Endpoint, :home)}
navigate={~p"/dashboard"}
class="text-primary-400 hover:underline"
aria-label={gettext("live dashboard")}
>
@ -93,19 +75,13 @@
</li>
<% else %>
<li :if={Accounts.allow_registration?()} class="mx-2 my-1">
<.link
href={Routes.user_registration_path(Endpoint, :new)}
class="text-primary-400 hover:underline truncate"
>
<.link href={~p"/users/register"} class="text-primary-400 hover:underline truncate">
<%= dgettext("actions", "register") %>
</.link>
</li>
<li class="mx-2 my-1">
<.link
href={Routes.user_session_path(Endpoint, :new)}
class="text-primary-400 hover:underline truncate"
>
<.link href={~p"/users/log_in"} class="text-primary-400 hover:underline truncate">
<%= dgettext("actions", "log in") %>
</.link>
</li>

View File

@ -0,0 +1,17 @@
defmodule MemexWeb.Layouts do
@moduledoc """
The root layouts for the entire application
"""
use MemexWeb, :html
embed_templates "layouts/*"
def get_title(%{assigns: %{title: title}}) when title not in [nil, ""] do
gettext("memEx | %{title}", title: title)
end
def get_title(_conn) do
gettext("memEx")
end
end

View File

@ -3,11 +3,11 @@
<.topbar current_user={assigns[:current_user]} />
<div class="mx-8 my-2 flex flex-col space-y-4 text-center">
<p :if={get_flash(@conn, :info)} class="alert alert-info" role="alert">
<%= get_flash(@conn, :info) %>
<p :if={@flash["info"]} class="alert alert-info" role="alert">
<%= @flash["info"] %>
</p>
<p :if={get_flash(@conn, :error)} class="alert alert-danger" role="alert">
<%= get_flash(@conn, :error) %>
<p :if={@flash["error"]} class="alert alert-danger" role="alert">
<%= @flash["error"] %>
</p>
</div>
</header>

View File

@ -9,11 +9,8 @@
<hr style="margin: 2em auto; border-width: 1px; border-color: rgb(161, 161, 170); width: 100%; max-width: 42rem;" />
<a style="color: rgb(161, 161, 170);" href={Routes.live_url(Endpoint, HomeLive)}>
<%= dgettext(
"emails",
"This email was sent from memEx"
) %>
<a style="color: rgb(161, 161, 170);" href={~p"/"}>
<%= dgettext("emails", "This email was sent from memEx") %>
</a>
</body>
</html>

View File

@ -0,0 +1,9 @@
<%= @email.subject %>
====================
<%= @inner_content %>
=====================
<%= dgettext("emails", "This email was sent from memEx at %{url}", url: ~p"/") %>

View File

@ -8,13 +8,8 @@
<.live_title suffix={" | #{gettext("memEx")}"}>
<%= assigns[:page_title] || gettext("memEx") %>
</.live_title>
<link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/css/app.css")} />
<script
defer
phx-track-static
type="text/javascript"
src={Routes.static_path(@conn, "/js/app.js")}
>
<link phx-track-static rel="stylesheet" href={~p"/css/app.css"} />
<script defer phx-track-static type="text/javascript" src={~p"/js/app.js"}>
</script>
</head>

View File

@ -92,7 +92,7 @@ defmodule MemexWeb.Components.NotesTableComponent do
assigns = %{slug: slug}
slug_block = ~H"""
<.link navigate={Routes.note_show_path(Endpoint, :show, @slug)} class="link">
<.link navigate={~p"/note/#{@slug}"} class="link">
<%= @slug %>
</.link>
"""
@ -105,7 +105,7 @@ defmodule MemexWeb.Components.NotesTableComponent do
~H"""
<div class="flex flex-wrap justify-center space-x-1">
<.link :for={tag <- @tags} patch={Routes.note_index_path(Endpoint, :search, tag)} class="link">
<.link :for={tag <- @tags} patch={~p"/notes/#{tag}"} class="link">
<%= tag %>
</.link>
</div>

View File

@ -93,7 +93,7 @@ defmodule MemexWeb.Components.PipelinesTableComponent do
assigns = %{slug: slug}
slug_block = ~H"""
<.link navigate={Routes.pipeline_show_path(Endpoint, :show, @slug)} class="link">
<.link navigate={~p"/pipeline/#{@slug}"} class="link">
<%= @slug %>
</.link>
"""
@ -118,11 +118,7 @@ defmodule MemexWeb.Components.PipelinesTableComponent do
~H"""
<div class="flex flex-wrap justify-center space-x-1">
<.link
:for={tag <- @tags}
patch={Routes.pipeline_index_path(Endpoint, :search, tag)}
class="link"
>
<.link :for={tag <- @tags} patch={~p"/pipelines/#{tag}"} class="link">
<%= tag %>
</.link>
</div>

View File

@ -6,7 +6,8 @@ defmodule MemexWeb.EmailController do
use MemexWeb, :controller
alias Memex.Accounts.User
plug :put_layout, {MemexWeb.LayoutView, :email}
plug :put_root_layout, html: {MemexWeb.Layouts, :email_html}
plug :put_layout, false
@sample_assigns %{
email: %{subject: "Example subject"},
@ -18,6 +19,6 @@ defmodule MemexWeb.EmailController do
Debug route used to preview emails
"""
def preview(conn, %{"id" => template}) do
render(conn, "#{template |> to_string()}.html", @sample_assigns)
render(conn, String.to_existing_atom(template), @sample_assigns)
end
end

View File

@ -0,0 +1,9 @@
defmodule MemexWeb.EmailHTML do
@moduledoc """
Renders email templates
"""
use MemexWeb, :html
embed_templates "email_html/*"
end

View File

@ -15,7 +15,7 @@
<br />
<a style="margin: 1em; color: rgb(31, 31, 31);" href={@url}><%= @url %></a>
<a style="margin: 1em; color: rgb(161, 161, 170);" href={@url}><%= @url %></a>
<br />

View File

@ -9,4 +9,4 @@
<%= dgettext("emails",
"If you didn't create an account at %{url}, please ignore this.",
url: Routes.live_url(Endpoint, HomeLive)) %>
url: ~p"/") %>

View File

@ -9,7 +9,7 @@
<br />
<a style="margin: 1em; color: rgb(31, 31, 31);" href={@url}><%= @url %></a>
<a style="margin: 1em; color: rgb(161, 161, 170);" href={@url}><%= @url %></a>
<br />

View File

@ -7,4 +7,4 @@
<%= dgettext("emails",
"If you didn't request this change from %{url}, please ignore this.",
url: Routes.live_url(Endpoint, HomeLive)) %>
url: ~p"/") %>

View File

@ -9,7 +9,7 @@
<br />
<a style="margin: 1em; color: rgb(31, 31, 31);" href={@url}><%= @url %></a>
<a style="margin: 1em; color: rgb(161, 161, 170);" href={@url}><%= @url %></a>
<br />

View File

@ -7,4 +7,4 @@
<%= dgettext("emails",
"If you didn't request this change from %{url}, please ignore this.",
url: Routes.live_url(Endpoint, HomeLive)) %>
url: ~p"/") %>

View File

@ -1,15 +1,16 @@
defmodule MemexWeb.ErrorView do
use MemexWeb, :view
alias MemexWeb.HomeLive
defmodule MemexWeb.ErrorHTML do
use MemexWeb, :html
def template_not_found(error_path, _assigns) do
embed_templates "error_html/*"
def render(template, _assigns) do
error_string =
case error_path do
case template do
"404.html" -> dgettext("errors", "not found")
"401.html" -> dgettext("errors", "unauthorized")
_other_path -> dgettext("errors", "internal server error")
end
render("error.html", %{error_string: error_string})
error(%{error_string: error_string})
end
end

View File

@ -24,10 +24,7 @@
<hr class="w-full hr" />
<.link
href={Routes.live_path(Endpoint, HomeLive)}
class="link title text-primary-400 text-lg"
>
<.link href={~p"/"} class="link title text-primary-400 text-lg">
<%= dgettext("errors", "go back home") %>
</.link>
</div>

View File

@ -0,0 +1,14 @@
defmodule MemexWeb.ErrorJSON do
import MemexWeb.Gettext
def render(template, _assigns) do
error_string =
case template do
"404.json" -> dgettext("errors", "not found")
"401.json" -> dgettext("errors", "unauthorized")
_other_path -> dgettext("errors", "internal server error")
end
%{errors: %{detail: error_string}}
end
end

View File

@ -1,11 +0,0 @@
defmodule MemexWeb.HomeController do
@moduledoc """
Controller for home page
"""
use MemexWeb, :controller
def index(conn, _params) do
render(conn, "index.html")
end
end

View File

@ -0,0 +1,5 @@
defmodule MemexWeb.HomeHTML do
use MemexWeb, :html
embed_templates "home_html/*"
end

View File

@ -3,12 +3,11 @@ defmodule MemexWeb.UserAuth do
Functions for user session and authentication
"""
use MemexWeb, :verified_routes
import Plug.Conn
import Phoenix.Controller
import MemexWeb.Gettext
alias Memex.{Accounts, Accounts.User}
alias MemexWeb.HomeLive
alias MemexWeb.Router.Helpers, as: Routes
# Make the remember me cookie valid for 60 days.
# If you want bump or reduce this value, also change
@ -39,7 +38,7 @@ defmodule MemexWeb.UserAuth do
dgettext("errors", "You must confirm your account and log in to access this page.")
)
|> maybe_store_return_to()
|> redirect(to: Routes.user_session_path(conn, :new))
|> redirect(to: ~p"/users/log_in")
|> halt()
end
@ -49,8 +48,7 @@ defmodule MemexWeb.UserAuth do
conn
|> renew_session()
|> put_session(:user_token, token)
|> put_session(:live_socket_id, "users_sessions:#{Base.url_encode64(token)}")
|> put_token_in_session(token)
|> maybe_write_remember_me_cookie(token, params)
|> redirect(to: user_return_to || signed_in_path(conn))
end
@ -96,7 +94,7 @@ defmodule MemexWeb.UserAuth do
"""
def log_out_user(conn) do
user_token = get_session(conn, :user_token)
user_token && Accounts.delete_session_token(user_token)
user_token && Accounts.delete_user_session_token(user_token)
if live_socket_id = get_session(conn, :live_socket_id) do
MemexWeb.Endpoint.broadcast(live_socket_id, "disconnect", %{})
@ -105,7 +103,7 @@ defmodule MemexWeb.UserAuth do
conn
|> renew_session()
|> delete_resp_cookie(@remember_me_cookie)
|> redirect(to: "/")
|> redirect(to: ~p"/")
end
@doc """
@ -119,19 +117,110 @@ defmodule MemexWeb.UserAuth do
end
defp ensure_user_token(conn) do
if user_token = get_session(conn, :user_token) do
{user_token, conn}
if token = get_session(conn, :user_token) do
{token, conn}
else
conn = fetch_cookies(conn, signed: [@remember_me_cookie])
if user_token = conn.cookies[@remember_me_cookie] do
{user_token, put_session(conn, :user_token, user_token)}
if token = conn.cookies[@remember_me_cookie] do
{token, put_token_in_session(conn, token)}
else
{nil, conn}
end
end
end
@doc """
Handles mounting and authenticating the current_user in LiveViews.
## `on_mount` arguments
* `:mount_current_user` - Assigns current_user
to socket assigns based on user_token, or nil if
there's no user_token or no matching user.
* `:ensure_authenticated` - Authenticates the user from the session,
and assigns the current_user to socket assigns based
on user_token.
Redirects to login page if there's no logged user.
* `:redirect_if_user_is_authenticated` - Authenticates the user from the session.
Redirects to signed_in_path if there's a logged user.
## Examples
Use the `on_mount` lifecycle macro in LiveViews to mount or authenticate
the current_user:
defmodule MemexWeb.PageLive do
use MemexWeb, :live_view
on_mount {MemexWeb.UserAuth, :mount_current_user}
...
end
Or use the `live_session` of your router to invoke the on_mount callback:
live_session :authenticated, on_mount: [{MemexWeb.UserAuth, :ensure_authenticated}] do
live "/profile", ProfileLive, :index
end
"""
def on_mount(:mount_current_user, _params, session, socket) do
{:cont, mount_current_user(session, socket)}
end
def on_mount(:ensure_authenticated, _params, session, socket) do
socket = mount_current_user(session, socket)
if socket.assigns.current_user do
{:cont, socket}
else
error_flash = dgettext("errors", "You must log in to access this page.")
socket =
socket
|> Phoenix.LiveView.put_flash(:error, error_flash)
|> Phoenix.LiveView.redirect(to: ~p"/users/log_in")
{:halt, socket}
end
end
def on_mount(:ensure_admin, _params, session, socket) do
socket = mount_current_user(session, socket)
if socket.assigns.current_user && socket.assigns.current_user.role == :admin do
{:cont, socket}
else
error_flash = dgettext("errors", "You must log in as an administrator to access this page.")
socket =
socket
|> Phoenix.LiveView.put_flash(:error, error_flash)
|> Phoenix.LiveView.redirect(to: ~p"/users/log_in")
{:halt, socket}
end
end
def on_mount(:redirect_if_user_is_authenticated, _params, session, socket) do
socket = mount_current_user(session, socket)
if socket.assigns.current_user do
{:halt, Phoenix.LiveView.redirect(socket, to: signed_in_path(socket))}
else
{:cont, socket}
end
end
defp mount_current_user(session, socket) do
Phoenix.Component.assign_new(socket, :current_user, fn ->
if user_token = session["user_token"] do
Accounts.get_user_by_session_token(user_token)
end
end)
end
@doc """
Used for routes that require the user to not be authenticated.
"""
@ -161,7 +250,7 @@ defmodule MemexWeb.UserAuth do
dgettext("errors", "You must confirm your account and log in to access this page.")
)
|> maybe_store_return_to()
|> redirect(to: Routes.user_session_path(conn, :new))
|> redirect(to: ~p"/users/log_in")
|> halt()
end
end
@ -176,16 +265,34 @@ defmodule MemexWeb.UserAuth do
conn
|> put_flash(:error, dgettext("errors", "You are not authorized to view this page."))
|> maybe_store_return_to()
|> redirect(to: Routes.live_path(conn, HomeLive))
|> redirect(to: ~p"/")
|> halt()
end
end
def put_user_locale(%{assigns: %{current_user: %{locale: locale}}} = conn, _opts) do
default = Application.fetch_env!(:gettext, :default_locale)
Gettext.put_locale(locale || default)
conn |> put_session(:locale, locale || default)
end
def put_user_locale(conn, _opts) do
default = Application.fetch_env!(:gettext, :default_locale)
Gettext.put_locale(default)
conn |> put_session(:locale, default)
end
defp put_token_in_session(conn, token) do
conn
|> put_session(:user_token, token)
|> put_session(:live_socket_id, "users_sessions:#{Base.url_encode64(token)}")
end
defp maybe_store_return_to(%{method: "GET"} = conn) do
put_session(conn, :user_return_to, current_path(conn))
end
defp maybe_store_return_to(conn), do: conn
defp signed_in_path(_conn), do: "/"
defp signed_in_path(_conn), do: ~p"/"
end

View File

@ -5,14 +5,14 @@ defmodule MemexWeb.UserConfirmationController do
alias Memex.Accounts
def new(conn, _params) do
render(conn, "new.html", page_title: gettext("Confirm your account"))
render(conn, :new, page_title: gettext("Confirm your account"))
end
def create(conn, %{"user" => %{"email" => email}}) do
if user = Accounts.get_user_by_email(email) do
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(conn, :confirm, &1)
fn token -> url(MemexWeb.Endpoint, ~p"/users/confirm/#{token}") end
)
end

View File

@ -0,0 +1,6 @@
defmodule MemexWeb.UserConfirmationHTML do
use MemexWeb, :html
alias Memex.Accounts
embed_templates "user_confirmation_html/*"
end

View File

@ -7,7 +7,7 @@
:let={f}
for={%{}}
as={:user}
action={Routes.user_confirmation_path(@conn, :create)}
action={~p"/users/confirm"}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<%= label(f, :email, gettext("Email"), class: "title text-lg text-primary-400") %>
@ -21,14 +21,10 @@
<hr class="hr" />
<div class="flex flex-row justify-center items-center space-x-4">
<.link
:if={Accounts.allow_registration?()}
href={Routes.user_registration_path(@conn, :new)}
class="btn btn-primary"
>
<.link :if={Accounts.allow_registration?()} href={~p"/users/register"} class="btn btn-primary">
<%= dgettext("actions", "register") %>
</.link>
<.link href={Routes.user_session_path(@conn, :new)} class="btn btn-primary">
<.link href={~p"/users/log_in"} class="btn btn-primary">
<%= dgettext("actions", "log in") %>
</.link>
</div>

View File

@ -2,7 +2,6 @@ defmodule MemexWeb.UserRegistrationController do
use MemexWeb, :controller
import MemexWeb.Gettext
alias Memex.{Accounts, Accounts.Invites}
alias MemexWeb.HomeLive
def new(conn, %{"invite" => invite_token}) do
if Invites.valid_invite_token?(invite_token) do
@ -10,7 +9,7 @@ defmodule MemexWeb.UserRegistrationController do
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
|> redirect(to: Routes.live_path(Endpoint, HomeLive))
|> redirect(to: ~p"/")
end
end
@ -20,13 +19,13 @@ defmodule MemexWeb.UserRegistrationController do
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, public registration is disabled"))
|> redirect(to: Routes.live_path(Endpoint, HomeLive))
|> redirect(to: ~p"/")
end
end
# renders new user registration page
defp render_new(conn, invite_token \\ nil) do
render(conn, "new.html",
render(conn, :new,
changeset: Accounts.change_user_registration(),
invite_token: invite_token,
page_title: gettext("register")
@ -39,7 +38,7 @@ defmodule MemexWeb.UserRegistrationController do
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, this invite was not found or expired"))
|> redirect(to: Routes.live_path(Endpoint, HomeLive))
|> redirect(to: ~p"/")
end
end
@ -49,7 +48,7 @@ defmodule MemexWeb.UserRegistrationController do
else
conn
|> put_flash(:error, dgettext("errors", "Sorry, public registration is disabled"))
|> redirect(to: Routes.live_path(Endpoint, HomeLive))
|> redirect(to: ~p"/")
end
end
@ -58,17 +57,17 @@ defmodule MemexWeb.UserRegistrationController do
{:ok, user} ->
Accounts.deliver_user_confirmation_instructions(
user,
&Routes.user_confirmation_url(conn, :confirm, &1)
fn token -> url(MemexWeb.Endpoint, ~p"/users/confirm/#{token}") end
)
conn
|> put_flash(:info, dgettext("prompts", "please check your email to verify your account"))
|> redirect(to: Routes.user_session_path(Endpoint, :new))
|> redirect(to: ~p"/users/log_in")
{:error, :invalid_token} ->
conn
|> put_flash(:error, dgettext("errors", "sorry, this invite was not found or expired"))
|> redirect(to: Routes.live_path(Endpoint, HomeLive))
|> redirect(to: ~p"/")
{:error, %Ecto.Changeset{} = changeset} ->
conn |> render("new.html", changeset: changeset, invite_token: invite_token)

View File

@ -0,0 +1,5 @@
defmodule MemexWeb.UserRegistrationHTML do
use MemexWeb, :html
embed_templates "user_registration_html/*"
end

View File

@ -6,7 +6,7 @@
<.form
:let={f}
for={@changeset}
action={Routes.user_registration_path(@conn, :create)}
action={~p"/users/register"}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<p :if={@changeset.action && not @changeset.valid?()} class="alert alert-danger col-span-3">
@ -40,10 +40,10 @@
<hr class="hr" />
<div class="flex flex-row justify-center items-center space-x-4">
<.link href={Routes.user_session_path(@conn, :new)} class="btn btn-primary">
<.link href={~p"/users/log_in"} class="btn btn-primary">
<%= dgettext("actions", "log in") %>
</.link>
<.link href={Routes.user_reset_password_path(@conn, :new)} class="btn btn-primary">
<.link href={~p"/users/reset_password"} class="btn btn-primary">
<%= dgettext("actions", "forgot your password?") %>
</.link>
</div>

View File

@ -6,14 +6,14 @@ defmodule MemexWeb.UserResetPasswordController do
plug :get_user_by_reset_password_token when action in [:edit, :update]
def new(conn, _params) do
render(conn, "new.html", page_title: gettext("forgot your password?"))
render(conn, :new, page_title: gettext("forgot your password?"))
end
def create(conn, %{"user" => %{"email" => email}}) do
if user = Accounts.get_user_by_email(email) do
Accounts.deliver_user_reset_password_instructions(
user,
&Routes.user_reset_password_url(conn, :edit, &1)
fn token -> url(MemexWeb.Endpoint, ~p"/users/reset_password/#{token}") end
)
end
@ -31,7 +31,7 @@ defmodule MemexWeb.UserResetPasswordController do
end
def edit(conn, _params) do
render(conn, "edit.html",
render(conn, :edit,
changeset: Accounts.change_user_password(conn.assigns.user),
page_title: gettext("Reset your password")
)
@ -44,10 +44,10 @@ defmodule MemexWeb.UserResetPasswordController do
{:ok, _} ->
conn
|> put_flash(:info, dgettext("prompts", "Password reset successfully."))
|> redirect(to: Routes.user_session_path(conn, :new))
|> redirect(to: ~p"/users/log_in")
{:error, changeset} ->
render(conn, "edit.html", changeset: changeset)
render(conn, :edit, changeset: changeset)
end
end

View File

@ -0,0 +1,6 @@
defmodule MemexWeb.UserResetPasswordHTML do
use MemexWeb, :html
alias Memex.Accounts
embed_templates "user_reset_password_html/*"
end

View File

@ -6,7 +6,7 @@
<.form
:let={f}
for={@changeset}
action={Routes.user_reset_password_path(@conn, :update, @token)}
action={~p"/users/reset_password/#{@token}"}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<p :if={@changeset.action && not @changeset.valid?()} class="alert alert-danger col-span-3">
@ -34,14 +34,10 @@
<hr class="hr" />
<div class="flex flex-row justify-center items-center space-x-4">
<.link
:if={Accounts.allow_registration?()}
href={Routes.user_registration_path(@conn, :new)}
class="btn btn-primary"
>
<.link :if={Accounts.allow_registration?()} href={~p"/users/register"} class="btn btn-primary">
<%= dgettext("actions", "register") %>
</.link>
<.link href={Routes.user_session_path(@conn, :new)} class="btn btn-primary">
<.link href={~p"/users/log_in"} class="btn btn-primary">
<%= dgettext("actions", "log in") %>
</.link>
</div>

View File

@ -7,7 +7,7 @@
:let={f}
for={%{}}
as={:user}
action={Routes.user_reset_password_path(@conn, :create)}
action={~p"/users/reset_password"}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<%= label(f, :email, gettext("email"), class: "title text-lg text-primary-400") %>
@ -21,14 +21,10 @@
<hr class="hr" />
<div class="flex flex-row justify-center items-center space-x-4">
<.link
:if={Accounts.allow_registration?()}
href={Routes.user_registration_path(@conn, :new)}
class="btn btn-primary"
>
<.link :if={Accounts.allow_registration?()} href={~p"/users/register"} class="btn btn-primary">
<%= dgettext("actions", "register") %>
</.link>
<.link href={Routes.user_session_path(@conn, :new)} class="btn btn-primary">
<.link href={~p"/users/log_in"} class="btn btn-primary">
<%= dgettext("actions", "log in") %>
</.link>
</div>

View File

@ -5,7 +5,7 @@ defmodule MemexWeb.UserSessionController do
alias MemexWeb.UserAuth
def new(conn, _params) do
render(conn, "new.html", error_message: nil, page_title: gettext("log in"))
render(conn, :new, error_message: nil, page_title: gettext("log in"))
end
def create(conn, %{"user" => user_params}) do
@ -14,7 +14,7 @@ defmodule MemexWeb.UserSessionController do
if user = Accounts.get_user_by_email_and_password(email, password) do
UserAuth.log_in_user(conn, user, user_params)
else
render(conn, "new.html", error_message: dgettext("errors", "Invalid email or password"))
render(conn, :new, error_message: dgettext("errors", "Invalid email or password"))
end
end

View File

@ -0,0 +1,6 @@
defmodule MemexWeb.UserSessionHTML do
use MemexWeb, :html
alias Memex.Accounts
embed_templates "user_session_html/*"
end

View File

@ -6,8 +6,8 @@
<.form
:let={f}
for={@conn}
action={Routes.user_session_path(@conn, :create)}
as="user"
action={~p"/users/log_in"}
as={:user}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<p :if={@error_message} class="alert alert-danger col-span-3">
@ -31,14 +31,10 @@
<hr class="hr" />
<div class="flex flex-row justify-center items-center space-x-4">
<.link
:if={Accounts.allow_registration?()}
href={Routes.user_registration_path(@conn, :new)}
class="btn btn-primary"
>
<.link :if={Accounts.allow_registration?()} href={~p"/users/register"} class="btn btn-primary">
<%= dgettext("actions", "register") %>
</.link>
<.link href={Routes.user_reset_password_path(@conn, :new)} class="btn btn-primary">
<.link href={~p"/users/reset_password"} class="btn btn-primary">
<%= dgettext("actions", "forgot your password?") %>
</.link>
</div>

View File

@ -2,12 +2,12 @@ defmodule MemexWeb.UserSettingsController do
use MemexWeb, :controller
import MemexWeb.Gettext
alias Memex.Accounts
alias MemexWeb.{HomeLive, UserAuth}
alias MemexWeb.UserAuth
plug :assign_email_and_password_changesets
def edit(conn, _params) do
render(conn, "edit.html", page_title: gettext("settings"))
render(conn, :edit, page_title: gettext("settings"))
end
def update(%{assigns: %{current_user: user}} = conn, %{
@ -20,7 +20,7 @@ defmodule MemexWeb.UserSettingsController do
Accounts.deliver_update_email_instructions(
applied_user,
user.email,
&Routes.user_settings_url(conn, :confirm_email, &1)
fn token -> url(MemexWeb.Endpoint, ~p"/users/settings/confirm_email/#{token}") end
)
conn
@ -31,10 +31,10 @@ defmodule MemexWeb.UserSettingsController do
"a link to confirm your email change has been sent to the new address."
)
)
|> redirect(to: Routes.user_settings_path(conn, :edit))
|> redirect(to: ~p"/users/settings")
{:error, changeset} ->
conn |> render("edit.html", email_changeset: changeset)
conn |> render(:edit, email_changeset: changeset)
end
end
@ -47,11 +47,11 @@ defmodule MemexWeb.UserSettingsController do
{:ok, user} ->
conn
|> put_flash(:info, dgettext("prompts", "password updated successfully."))
|> put_session(:user_return_to, Routes.user_settings_path(conn, :edit))
|> put_session(:user_return_to, ~p"/users/settings")
|> UserAuth.log_in_user(user)
{:error, changeset} ->
conn |> render("edit.html", password_changeset: changeset)
conn |> render(:edit, password_changeset: changeset)
end
end
@ -63,10 +63,10 @@ defmodule MemexWeb.UserSettingsController do
{:ok, _user} ->
conn
|> put_flash(:info, dgettext("prompts", "language updated successfully."))
|> redirect(to: Routes.user_settings_path(conn, :edit))
|> redirect(to: ~p"/users/settings")
{:error, changeset} ->
conn |> render("edit.html", locale_changeset: changeset)
conn |> render(:edit, locale_changeset: changeset)
end
end
@ -75,7 +75,7 @@ defmodule MemexWeb.UserSettingsController do
:ok ->
conn
|> put_flash(:info, dgettext("prompts", "email changed successfully."))
|> redirect(to: Routes.user_settings_path(conn, :edit))
|> redirect(to: ~p"/users/settings")
:error ->
conn
@ -83,7 +83,7 @@ defmodule MemexWeb.UserSettingsController do
:error,
dgettext("errors", "email change link is invalid or it has expired.")
)
|> redirect(to: Routes.user_settings_path(conn, :edit))
|> redirect(to: ~p"/users/settings")
end
end
@ -93,11 +93,11 @@ defmodule MemexWeb.UserSettingsController do
conn
|> put_flash(:error, dgettext("prompts", "your account has been deleted"))
|> redirect(to: Routes.live_path(conn, HomeLive))
|> redirect(to: ~p"/")
else
conn
|> put_flash(:error, dgettext("errors", "unable to delete user"))
|> redirect(to: Routes.user_settings_path(conn, :edit))
|> redirect(to: ~p"/users/settings")
end
end

View File

@ -0,0 +1,5 @@
defmodule MemexWeb.UserSettingsHTML do
use MemexWeb, :html
embed_templates "user_settings_html/*"
end

View File

@ -8,7 +8,7 @@
<.form
:let={f}
for={@email_changeset}
action={Routes.user_settings_path(@conn, :update)}
action={~p"/users/settings"}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<h3 class="title text-primary-400 text-lg text-center col-span-3">
@ -50,7 +50,7 @@
<.form
:let={f}
for={@password_changeset}
action={Routes.user_settings_path(@conn, :update)}
action={~p"/users/settings"}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<h3 class="title text-primary-400 text-lg text-center col-span-3">
@ -104,7 +104,7 @@
<.form
:let={f}
for={@locale_changeset}
action={Routes.user_settings_path(@conn, :update)}
action={~p"/users/settings"}
class="flex flex-col space-y-4 sm:space-y-0 sm:grid sm:grid-cols-3 sm:gap-4 justify-center items-center"
>
<%= label(f, :locale, dgettext("actions", "change language"),
@ -134,17 +134,13 @@
<hr class="hr" />
<div class="flex justify-end items-center">
<.link
href={Routes.export_path(@conn, :export, :json)}
class="mx-4 my-2 btn btn-primary"
target="_blank"
>
<.link href={~p"/export/json"} class="mx-4 my-2 btn btn-primary" target="_blank">
<%= dgettext("actions", "export data as json") %>
</.link>
<.link
href={Routes.user_settings_path(@conn, :delete, @current_user)}
method={:delete}
href={~p"/users/settings/#{@current_user}"}
method="delete"
class="mx-4 my-2 btn btn-alert"
data-confirm={dgettext("prompts", "are you sure you want to delete your account?")}
>

View File

@ -20,7 +20,7 @@ defmodule MemexWeb.Endpoint do
at: "/",
from: :memex,
gzip: false,
only: ~w(css fonts images js favicon.ico robots.txt)
only: MemexWeb.static_paths()
# Code reloading can be explicitly enabled under the
# :code_reloader configuration of your endpoint.

View File

@ -60,11 +60,11 @@ defmodule MemexWeb.ContextLive.Index do
end
def handle_event("search", %{"search" => %{"search_term" => ""}}, socket) do
{:noreply, socket |> push_patch(to: Routes.context_index_path(Endpoint, :index))}
{:noreply, socket |> push_patch(to: ~p"/contexts")}
end
def handle_event("search", %{"search" => %{"search_term" => search_term}}, socket) do
redirect_to = Routes.context_index_path(Endpoint, :search, search_term)
redirect_to = ~p"/contexts/#{search_term}"
{:noreply, socket |> push_patch(to: redirect_to)}
end

View File

@ -34,7 +34,7 @@
<:actions :let={context}>
<.link
:if={Contexts.is_owner?(context, @current_user)}
patch={Routes.context_index_path(@socket, :edit, context.slug)}
patch={~p"/contexts/#{context}/edit"}
aria-label={dgettext("actions", "edit %{context_slug}", context_slug: context.slug)}
>
<%= dgettext("actions", "edit") %>
@ -53,16 +53,12 @@
</.live_component>
<% end %>
<.link
:if={@current_user}
patch={Routes.context_index_path(@socket, :new)}
class="self-end btn btn-primary"
>
<.link :if={@current_user} patch={~p"/contexts/new"} class="self-end btn btn-primary">
<%= dgettext("actions", "new context") %>
</.link>
</div>
<.modal :if={@live_action in [:new, :edit]} return_to={Routes.context_index_path(@socket, :index)}>
<.modal :if={@live_action in [:new, :edit]} return_to={~p"/contexts"}>
<.live_component
module={MemexWeb.ContextLive.FormComponent}
id={@context.id || :new}
@ -70,6 +66,6 @@
title={@page_title}
action={@live_action}
context={@context}
return_to={Routes.context_index_path(@socket, :index)}
return_to={~p"/contexts"}
/>
</.modal>

View File

@ -38,7 +38,7 @@ defmodule MemexWeb.ContextLive.Show do
socket =
socket
|> put_flash(:info, gettext("%{slug} deleted", slug: slug))
|> push_navigate(to: Routes.context_index_path(Endpoint, :index))
|> push_navigate(to: ~p"/contexts")
{:noreply, socket}
end

View File

@ -4,11 +4,7 @@
</h1>
<div class="flex flex-wrap space-x-1">
<.link
:for={tag <- @context.tags}
navigate={Routes.context_index_path(Endpoint, :search, tag)}
class="link"
>
<.link :for={tag <- @context.tags} navigate={~p"/contexts/#{tag}"} class="link">
<%= tag %>
</.link>
</div>
@ -23,7 +19,7 @@
<.link
:if={Contexts.is_owner?(@context, @current_user)}
class="btn btn-primary"
patch={Routes.context_show_path(@socket, :edit, @context.slug)}
patch={~p"/context/#{@context}/edit"}
>
<%= dgettext("actions", "edit") %>
</.link>
@ -40,10 +36,7 @@
</div>
</div>
<.modal
:if={@live_action == :edit}
return_to={Routes.context_show_path(@socket, :show, @context.slug)}
>
<.modal :if={@live_action == :edit} return_to={~p"/context/#{@context}"}>
<.live_component
module={MemexWeb.ContextLive.FormComponent}
id={@context.id}
@ -51,6 +44,6 @@
title={@page_title}
action={@live_action}
context={@context}
return_to={Routes.context_show_path(@socket, :show, @context.slug)}
return_to={~p"/context/#{@context}"}
/>
</.modal>

View File

@ -5,7 +5,6 @@ defmodule MemexWeb.HomeLive do
use MemexWeb, :live_view
alias Memex.Accounts
alias MemexWeb.FaqLive
@version Mix.Project.config()[:version]

View File

@ -32,7 +32,7 @@
</li>
<li class="flex flex-col justify-center items-center text-right space-y-2">
<.link navigate={Routes.live_path(Endpoint, FaqLive)} class="btn btn-primary">
<.link navigate={~p"/faq"} class="btn btn-primary">
<%= gettext("read more on how to use memEx") %>
</.link>
</li>
@ -86,7 +86,7 @@
</b>
<p class="flex flex-col justify-center items-center space-y-2">
<%= if @admins |> Enum.empty?() do %>
<.link href={Routes.user_registration_path(Endpoint, :new)} class="link">
<.link href={~p"/users/register"} class="link">
<%= dgettext("prompts", "register to setup memEx") %>
</.link>
<% else %>

View File

@ -8,7 +8,7 @@
<%= gettext("no invites 😔") %>
</h1>
<.link patch={Routes.invite_index_path(Endpoint, :new)} class="btn btn-primary">
<.link patch={~p"/invites"} class="btn btn-primary">
<%= dgettext("actions", "invite someone new!") %>
</.link>
<% end %>
@ -35,7 +35,7 @@
</form>
</:code_actions>
<.link
patch={Routes.invite_index_path(Endpoint, :edit, invite)}
patch={~p"/invites/#{invite}/edit"}
class="text-primary-400 link"
aria-label={
dgettext("actions", "edit invite for %{invite_name}", invite_name: invite.name)
@ -86,11 +86,7 @@
</.link>
</.invite_card>
<.link
:if={@invites != []}
patch={Routes.invite_index_path(Endpoint, :new)}
class="btn btn-primary ml-auto"
>
<.link :if={@invites != []} patch={~p"/invites/new"} class="btn btn-primary ml-auto">
<%= dgettext("actions", "create invite") %>
</.link>
</div>
@ -152,14 +148,14 @@
<% end %>
</div>
<.modal :if={@live_action in [:new, :edit]} return_to={Routes.invite_index_path(Endpoint, :index)}>
<.modal :if={@live_action in [:new, :edit]} return_to={~p"/invites"}>
<.live_component
module={MemexWeb.InviteLive.FormComponent}
id={@invite.id || :new}
title={@page_title}
action={@live_action}
invite={@invite}
return_to={Routes.invite_index_path(Endpoint, :index)}
return_to={~p"/invites"}
current_user={@current_user}
/>
</.modal>

View File

@ -60,11 +60,11 @@ defmodule MemexWeb.NoteLive.Index do
end
def handle_event("search", %{"search" => %{"search_term" => ""}}, socket) do
{:noreply, socket |> push_patch(to: Routes.note_index_path(Endpoint, :index))}
{:noreply, socket |> push_patch(to: ~p"/notes")}
end
def handle_event("search", %{"search" => %{"search_term" => search_term}}, socket) do
{:noreply, socket |> push_patch(to: Routes.note_index_path(Endpoint, :search, search_term))}
{:noreply, socket |> push_patch(to: ~p"/notes/#{search_term}")}
end
defp display_notes(%{assigns: %{current_user: current_user, search: search}} = socket)

View File

@ -34,7 +34,7 @@
<:actions :let={note}>
<.link
:if={Notes.is_owner?(note, @current_user)}
patch={Routes.note_index_path(@socket, :edit, note.slug)}
patch={~p"/notes/#{note}/edit"}
aria-label={dgettext("actions", "edit %{note_slug}", note_slug: note.slug)}
>
<%= dgettext("actions", "edit") %>
@ -53,16 +53,12 @@
</.live_component>
<% end %>
<.link
:if={@current_user}
patch={Routes.note_index_path(@socket, :new)}
class="self-end btn btn-primary"
>
<.link :if={@current_user} patch={~p"/notes/new"} class="self-end btn btn-primary">
<%= dgettext("actions", "new note") %>
</.link>
</div>
<.modal :if={@live_action in [:new, :edit]} return_to={Routes.note_index_path(@socket, :index)}>
<.modal :if={@live_action in [:new, :edit]} return_to={~p"/notes"}>
<.live_component
module={MemexWeb.NoteLive.FormComponent}
id={@note.id || :new}
@ -70,6 +66,6 @@
title={@page_title}
action={@live_action}
note={@note}
return_to={Routes.note_index_path(@socket, :index)}
return_to={~p"/notes"}
/>
</.modal>

View File

@ -38,7 +38,7 @@ defmodule MemexWeb.NoteLive.Show do
socket =
socket
|> put_flash(:info, gettext("%{slug} deleted", slug: slug))
|> push_navigate(to: Routes.note_index_path(Endpoint, :index))
|> push_navigate(to: ~p"/notes")
{:noreply, socket}
end

View File

@ -4,11 +4,7 @@
</h1>
<div class="flex flex-wrap space-x-1">
<.link
:for={tag <- @note.tags}
navigate={Routes.note_index_path(Endpoint, :search, tag)}
class="link"
>
<.link :for={tag <- @note.tags} navigate={~p"/notes/#{tag}"} class="link">
<%= tag %>
</.link>
</div>
@ -23,7 +19,7 @@
<.link
:if={Notes.is_owner?(@note, @current_user)}
class="btn btn-primary"
patch={Routes.note_show_path(@socket, :edit, @note.slug)}
patch={~p"/note/#{@note}/edit"}
>
<%= dgettext("actions", "edit") %>
</.link>
@ -40,7 +36,7 @@
</div>
</div>
<.modal :if={@live_action == :edit} return_to={Routes.note_show_path(@socket, :show, @note.slug)}>
<.modal :if={@live_action == :edit} return_to={~p"/note/#{@note}"}>
<.live_component
module={MemexWeb.NoteLive.FormComponent}
id={@note.id}
@ -48,6 +44,6 @@
title={@page_title}
action={@live_action}
note={@note}
return_to={Routes.note_show_path(@socket, :show, @note.slug)}
return_to={~p"/note/#{@note}"}
/>
</.modal>

View File

@ -60,12 +60,11 @@ defmodule MemexWeb.PipelineLive.Index do
end
def handle_event("search", %{"search" => %{"search_term" => ""}}, socket) do
{:noreply, socket |> push_patch(to: Routes.pipeline_index_path(Endpoint, :index))}
{:noreply, socket |> push_patch(to: ~p"/pipelines")}
end
def handle_event("search", %{"search" => %{"search_term" => search_term}}, socket) do
redirect_to = Routes.pipeline_index_path(Endpoint, :search, search_term)
{:noreply, socket |> push_patch(to: redirect_to)}
{:noreply, socket |> push_patch(to: ~p"/pipelines/#{search_term}")}
end
defp display_pipelines(%{assigns: %{current_user: current_user, search: search}} = socket)

View File

@ -34,7 +34,7 @@
<:actions :let={pipeline}>
<.link
:if={Pipelines.is_owner?(pipeline, @current_user)}
patch={Routes.pipeline_index_path(@socket, :edit, pipeline.slug)}
patch={~p"/pipelines/#{pipeline}/edit"}
aria-label={dgettext("actions", "edit %{pipeline_slug}", pipeline_slug: pipeline.slug)}
>
<%= dgettext("actions", "edit") %>
@ -55,19 +55,12 @@
</.live_component>
<% end %>
<.link
:if={@current_user}
patch={Routes.pipeline_index_path(@socket, :new)}
class="self-end btn btn-primary"
>
<.link :if={@current_user} patch={~p"/pipelines/new"} class="self-end btn btn-primary">
<%= dgettext("actions", "new pipeline") %>
</.link>
</div>
<.modal
:if={@live_action in [:new, :edit]}
return_to={Routes.pipeline_index_path(@socket, :index)}
>
<.modal :if={@live_action in [:new, :edit]} return_to={~p"/pipelines"}>
<.live_component
module={MemexWeb.PipelineLive.FormComponent}
id={@pipeline.id || :new}
@ -75,6 +68,6 @@
title={@page_title}
action={@live_action}
pipeline={@pipeline}
return_to={Routes.pipeline_index_path(@socket, :index)}
return_to={~p"/pipelines"}
/>
</.modal>

View File

@ -73,7 +73,7 @@ defmodule MemexWeb.PipelineLive.Show do
socket =
socket
|> put_flash(:info, gettext("%{slug} deleted", slug: slug))
|> push_navigate(to: Routes.pipeline_index_path(Endpoint, :index))
|> push_navigate(to: ~p"/pipelines")
{:noreply, socket}
end
@ -91,7 +91,7 @@ defmodule MemexWeb.PipelineLive.Show do
socket =
socket
|> put_flash(:info, gettext("%{title} deleted", title: title))
|> push_patch(to: Routes.pipeline_show_path(Endpoint, :show, pipeline_slug))
|> push_patch(to: ~p"/pipeline/#{pipeline_slug}")
{:noreply, socket}
end
@ -110,7 +110,7 @@ defmodule MemexWeb.PipelineLive.Show do
socket =
socket
|> push_patch(to: Routes.pipeline_show_path(Endpoint, :show, pipeline_slug))
|> push_patch(to: ~p"/pipeline/#{pipeline_slug}")
{:noreply, socket}
end

View File

@ -4,11 +4,7 @@
</h1>
<div class="flex flex-wrap space-x-1">
<.link
:for={tag <- @pipeline.tags}
navigate={Routes.pipeline_index_path(Endpoint, :search, tag)}
class="link"
>
<.link :for={tag <- @pipeline.tags} navigate={~p"/pipelines/#{tag}"} class="link">
<%= tag %>
</.link>
</div>
@ -31,7 +27,7 @@
<.link
:if={Pipelines.is_owner?(@pipeline, @current_user)}
class="btn btn-primary"
patch={Routes.pipeline_show_path(@socket, :edit, @pipeline.slug)}
patch={~p"/pipeline/#{@pipeline}/edit"}
>
<%= dgettext("actions", "edit") %>
</.link>
@ -100,7 +96,7 @@
<.link
class="self-end btn btn-primary"
patch={Routes.pipeline_show_path(@socket, :edit_step, @pipeline.slug, step_id)}
patch={~p"/pipeline/#{@pipeline}/#{step_id}"}
aria-label={dgettext("actions", "edit %{step_title}", step_title: step.title)}
>
<%= dgettext("actions", "edit") %>
@ -127,7 +123,7 @@
<.link
:if={Pipelines.is_owner?(@pipeline, @current_user)}
class="self-end btn btn-primary"
patch={Routes.pipeline_show_path(@socket, :add_step, @pipeline.slug)}
patch={~p"/pipeline/#{@pipeline}/add_step"}
>
<%= dgettext("actions", "add step") %>
</.link>
@ -135,7 +131,7 @@
<%= case @live_action do %>
<% :edit -> %>
<.modal return_to={Routes.pipeline_show_path(@socket, :show, @pipeline.slug)}>
<.modal return_to={~p"/pipeline/#{@pipeline}"}>
<.live_component
module={MemexWeb.PipelineLive.FormComponent}
id={@pipeline.id}
@ -143,11 +139,11 @@
title={@page_title}
action={@live_action}
pipeline={@pipeline}
return_to={Routes.pipeline_show_path(@socket, :show, @pipeline.slug)}
return_to={~p"/pipeline/#{@pipeline}"}
/>
</.modal>
<% action when action in [:add_step, :edit_step] -> %>
<.modal return_to={Routes.pipeline_show_path(@socket, :show, @pipeline.slug)}>
<.modal return_to={~p"/pipeline/#{@pipeline}"}>
<.live_component
module={MemexWeb.StepLive.FormComponent}
id={@pipeline.id || :new}
@ -156,7 +152,7 @@
action={@live_action}
pipeline={@pipeline}
step={@step}
return_to={Routes.pipeline_show_path(@socket, :show, @pipeline.slug)}
return_to={~p"/pipeline/#{@pipeline}"}
/>
</.modal>
<% _ -> %>

View File

@ -7,25 +7,13 @@ defmodule MemexWeb.Router do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {MemexWeb.LayoutView, :root}
plug :put_root_layout, {MemexWeb.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
plug :fetch_current_user
plug :put_user_locale
end
defp put_user_locale(%{assigns: %{current_user: %{locale: locale}}} = conn, _opts) do
default = Application.fetch_env!(:gettext, :default_locale)
Gettext.put_locale(locale || default)
conn |> put_session(:locale, locale || default)
end
defp put_user_locale(conn, _opts) do
default = Application.fetch_env!(:gettext, :default_locale)
Gettext.put_locale(default)
conn |> put_session(:locale, default)
end
pipeline :require_admin do
plug :require_role, role: :admin
end
@ -34,13 +22,6 @@ defmodule MemexWeb.Router do
plug :accepts, ["json"]
end
scope "/", MemexWeb do
pipe_through :browser
live "/", HomeLive
live "/faq", FaqLive
end
## Authentication routes
scope "/", MemexWeb do
@ -56,10 +37,10 @@ defmodule MemexWeb.Router do
put "/users/reset_password/:token", UserResetPasswordController, :update
end
live_session :default do
scope "/", MemexWeb do
pipe_through [:browser, :require_authenticated_user]
scope "/", MemexWeb do
pipe_through [:browser, :require_authenticated_user]
live_session :default, on_mount: [{MemexWeb.UserAuth, :ensure_authenticated}] do
live "/notes/new", NoteLive.Index, :new
live "/notes/:slug/edit", NoteLive.Index, :edit
live "/note/:slug/edit", NoteLive.Show, :edit
@ -73,16 +54,21 @@ defmodule MemexWeb.Router do
live "/pipeline/:slug/edit", PipelineLive.Show, :edit
live "/pipeline/:slug/add_step", PipelineLive.Show, :add_step
live "/pipeline/:slug/:step_id", PipelineLive.Show, :edit_step
get "/users/settings", UserSettingsController, :edit
put "/users/settings", UserSettingsController, :update
delete "/users/settings/:id", UserSettingsController, :delete
get "/users/settings/confirm_email/:token", UserSettingsController, :confirm_email
get "/export/:mode", ExportController, :export
end
scope "/", MemexWeb do
pipe_through [:browser]
get "/users/settings", UserSettingsController, :edit
put "/users/settings", UserSettingsController, :update
delete "/users/settings/:id", UserSettingsController, :delete
get "/users/settings/confirm_email/:token", UserSettingsController, :confirm_email
get "/export/:mode", ExportController, :export
end
scope "/", MemexWeb do
pipe_through [:browser]
live_session :public, on_mount: [{MemexWeb.UserAuth, :mount_current_user}] do
live "/", HomeLive
live "/faq", FaqLive
live "/notes", NoteLive.Index, :index
live "/notes/:search", NoteLive.Index, :search
@ -98,10 +84,10 @@ defmodule MemexWeb.Router do
end
end
live_session :admin do
scope "/", MemexWeb do
pipe_through [:browser, :require_authenticated_user, :require_admin]
scope "/", MemexWeb do
pipe_through [:browser, :require_authenticated_user, :require_admin]
live_session :admin, on_mount: [{MemexWeb.UserAuth, :ensure_admin}] do
live "/invites", InviteLive.Index, :index
live "/invites/new", InviteLive.Index, :new
live "/invites/:id/edit", InviteLive.Index, :edit
@ -132,9 +118,6 @@ defmodule MemexWeb.Router do
pipe_through :browser
forward "/mailbox", Plug.Swoosh.MailboxPreview
end
scope "/dev" do
get "/preview/:id", MemexWeb.EmailController, :preview
end
end

View File

@ -1,11 +0,0 @@
<%= @email.subject %>
====================
<%= @inner_content %>
=====================
<%= dgettext("emails",
"This email was sent from memEx at %{url}",
url: Routes.live_url(Endpoint, HomeLive)) %>

View File

@ -1,7 +0,0 @@
defmodule MemexWeb.EmailView do
@moduledoc """
A view for email-related helper functions
"""
use MemexWeb, :view
alias MemexWeb.HomeLive
end

View File

@ -1,3 +0,0 @@
defmodule MemexWeb.PageView do
use MemexWeb, :view
end

View File

@ -1,8 +1,6 @@
defmodule MemexWeb.ViewHelpers do
defmodule MemexWeb.HTMLHelpers do
@moduledoc """
Contains common helpers that can be used in liveviews and regular views. These
are automatically imported into any Phoenix View using `use MemexWeb,
:view`
Contains common helpers that are used for rendering
"""
use Phoenix.Component

View File

@ -1,16 +0,0 @@
defmodule MemexWeb.LayoutView do
use MemexWeb, :view
alias MemexWeb.HomeLive
# Phoenix LiveDashboard is available only in development by default,
# so we instruct Elixir to not warn if the dashboard route is missing.
@compile {:no_warn_undefined, {Routes, :live_dashboard_path, 2}}
def get_title(%{assigns: %{title: title}}) when title not in [nil, ""] do
gettext("memEx | %{title}", title: title)
end
def get_title(_conn) do
gettext("memEx")
end
end

View File

@ -1,4 +0,0 @@
defmodule MemexWeb.UserConfirmationView do
use MemexWeb, :view
alias Memex.Accounts
end

View File

@ -1,3 +0,0 @@
defmodule MemexWeb.UserRegistrationView do
use MemexWeb, :view
end

View File

@ -1,4 +0,0 @@
defmodule MemexWeb.UserResetPasswordView do
use MemexWeb, :view
alias Memex.Accounts
end

View File

@ -1,4 +0,0 @@
defmodule MemexWeb.UserSessionView do
use MemexWeb, :view
alias Memex.Accounts
end

View File

@ -1,3 +0,0 @@
defmodule MemexWeb.UserSettingsView do
use MemexWeb, :view
end