implement notes

This commit is contained in:
shibao 2022-11-17 22:38:52 -05:00
parent 0aa7df0b37
commit 1a508a42ef
21 changed files with 1096 additions and 574 deletions

View File

@ -2,7 +2,21 @@
// update. https://github.com/phoenixframework/phoenix_live_view/issues/1011 // update. https://github.com/phoenixframework/phoenix_live_view/issues/1011
export default { export default {
attrs () { return this.el.getAttribute('data-attrs').split(', ') }, attrs () {
beforeUpdate () { this.prevAttrs = this.attrs().map(name => [name, this.el.getAttribute(name)]) }, if (this.el && this.el.getAttribute('data-attrs')) {
updated () { this.prevAttrs.forEach(([name, val]) => this.el.setAttribute(name, val)) } return this.el.getAttribute('data-attrs').split(', ')
} else {
return []
}
},
beforeUpdate () {
if (this.el) {
this.prevAttrs = this.attrs().map(name => [name, this.el.getAttribute(name)])
}
},
updated () {
if (this.el) {
this.prevAttrs.forEach(([name, val]) => this.el.setAttribute(name, val))
}
}
} }

View File

@ -4,21 +4,40 @@ defmodule Memex.Notes do
""" """
import Ecto.Query, warn: false import Ecto.Query, warn: false
alias Memex.Repo alias Ecto.Changeset
alias Memex.{Accounts.User, Notes.Note, Repo}
alias Memex.Notes.Note
@doc """ @doc """
Returns the list of notes. Returns the list of notes.
## Examples ## Examples
iex> list_notes() iex> list_notes(%User{id: 123})
[%Note{}, ...] [%Note{}, ...]
iex> list_notes("my note", %User{id: 123})
[%Note{title: "my note"}, ...]
""" """
def list_notes do @spec list_notes(User.t()) :: [Note.t()]
Repo.all(Note) def list_notes(%{id: user_id}) do
Repo.all(from n in Note, where: n.user_id == ^user_id, order_by: n.title)
end
@doc """
Returns the list of public notes for viewing
## Examples
iex> list_public_notes()
[%Note{}, ...]
iex> list_public_notes("my note")
[%Note{title: "my note"}, ...]
"""
@spec list_public_notes() :: [Note.t()]
def list_public_notes do
Repo.all(from n in Note, where: n.visibility == :public, order_by: n.title)
end end
@doc """ @doc """
@ -28,31 +47,46 @@ defmodule Memex.Notes do
## Examples ## Examples
iex> get_note!(123) iex> get_note!(123, %User{id: 123})
%Note{} %Note{}
iex> get_note!(456) iex> get_note!(456, %User{id: 123})
** (Ecto.NoResultsError) ** (Ecto.NoResultsError)
""" """
def get_note!(id), do: Repo.get!(Note, id) @spec get_note!(Note.id(), User.t()) :: Note.t()
def get_note!(id, %{id: user_id}) do
Repo.one!(
from n in Note,
where: n.id == ^id,
where: n.user_id == ^user_id or n.visibility in [:public, :unlisted]
)
end
def get_note!(id, _invalid_user) do
Repo.one!(
from n in Note,
where: n.id == ^id,
where: n.visibility in [:public, :unlisted]
)
end
@doc """ @doc """
Creates a note. Creates a note.
## Examples ## Examples
iex> create_note(%{field: value}) iex> create_note(%{field: value}, %User{id: 123})
{:ok, %Note{}} {:ok, %Note{}}
iex> create_note(%{field: bad_value}) iex> create_note(%{field: bad_value}, %User{id: 123})
{:error, %Ecto.Changeset{}} {:error, %Ecto.Changeset{}}
""" """
def create_note(attrs \\ %{}) do @spec create_note(User.t()) :: {:ok, Note.t()} | {:error, Note.changeset()}
%Note{} @spec create_note(attrs :: map(), User.t()) :: {:ok, Note.t()} | {:error, Note.changeset()}
|> Note.changeset(attrs) def create_note(attrs \\ %{}, user) do
|> Repo.insert() Note.create_changeset(attrs, user) |> Repo.insert()
end end
@doc """ @doc """
@ -60,16 +94,18 @@ defmodule Memex.Notes do
## Examples ## Examples
iex> update_note(note, %{field: new_value}) iex> update_note(note, %{field: new_value}, %User{id: 123})
{:ok, %Note{}} {:ok, %Note{}}
iex> update_note(note, %{field: bad_value}) iex> update_note(note, %{field: bad_value}, %User{id: 123})
{:error, %Ecto.Changeset{}} {:error, %Ecto.Changeset{}}
""" """
def update_note(%Note{} = note, attrs) do @spec update_note(Note.t(), attrs :: map(), User.t()) ::
{:ok, Note.t()} | {:error, Note.changeset()}
def update_note(%Note{} = note, attrs, user) do
note note
|> Note.changeset(attrs) |> Note.update_changeset(attrs, user)
|> Repo.update() |> Repo.update()
end end
@ -78,15 +114,23 @@ defmodule Memex.Notes do
## Examples ## Examples
iex> delete_note(note) iex> delete_note(%Note{user_id: 123}, %User{id: 123})
{:ok, %Note{}} {:ok, %Note{}}
iex> delete_note(note) iex> delete_note(%Note{}, %User{role: :admin})
{:ok, %Note{}}
iex> delete_note(%Note{}, %User{id: 123})
{:error, %Ecto.Changeset{}} {:error, %Ecto.Changeset{}}
""" """
def delete_note(%Note{} = note) do @spec delete_note(Note.t(), User.t()) :: {:ok, Note.t()} | {:error, Note.changeset()}
Repo.delete(note) def delete_note(%Note{user_id: user_id} = note, %{id: user_id}) do
note |> Repo.delete()
end
def delete_note(%Note{} = note, %{role: :admin}) do
note |> Repo.delete()
end end
@doc """ @doc """
@ -94,11 +138,30 @@ defmodule Memex.Notes do
## Examples ## Examples
iex> change_note(note) iex> change_note(note, %User{id: 123})
%Ecto.Changeset{data: %Note{}}
iex> change_note(note, %{title: "new title"}, %User{id: 123})
%Ecto.Changeset{data: %Note{}} %Ecto.Changeset{data: %Note{}}
""" """
def change_note(%Note{} = note, attrs \\ %{}) do @spec change_note(Note.t(), User.t()) :: Note.changeset()
Note.changeset(note, attrs) @spec change_note(Note.t(), attrs :: map(), User.t()) :: Note.changeset()
def change_note(%Note{} = note, attrs \\ %{}, user) do
note |> Note.update_changeset(attrs, user)
end
@doc """
Gets a canonical string representation of the `:tags` field for a Note
"""
@spec get_tags_string(Note.t() | Note.changeset() | [String.t()] | nil) :: String.t()
def get_tags_string(nil), do: ""
def get_tags_string(tags) when tags |> is_list(), do: tags |> Enum.join(",")
def get_tags_string(%Note{tags: tags}), do: tags |> get_tags_string()
def get_tags_string(%Changeset{} = changeset) do
changeset
|> Changeset.get_field(:tags)
|> get_tags_string()
end end
end end

View File

@ -1,22 +1,58 @@
defmodule Memex.Notes.Note do defmodule Memex.Notes.Note do
@moduledoc """
Schema for a user-written note
"""
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
alias Ecto.{Changeset, UUID}
alias Memex.{Accounts.User, Notes.Note}
@primary_key {:id, :binary_id, autogenerate: true} @primary_key {:id, :binary_id, autogenerate: true}
@foreign_key_type :binary_id @foreign_key_type :binary_id
schema "notes" do schema "notes" do
field :content, :string field :content, :string
field :tag, {:array, :string} field :tags, {:array, :string}
field :tags_string, :string, virtual: true
field :title, :string field :title, :string
field :visibility, Ecto.Enum, values: [:public, :private, :unlisted] field :visibility, Ecto.Enum, values: [:public, :private, :unlisted]
belongs_to :user, User
timestamps() timestamps()
end end
@type t :: %Note{}
@type id :: UUID.t()
@type changeset :: Changeset.t(t())
@doc false @doc false
def changeset(note, attrs) do @spec create_changeset(attrs :: map(), User.t()) :: changeset()
note def create_changeset(attrs, %User{id: user_id}) do
|> cast(attrs, [:title, :content, :tag, :visibility]) %Note{}
|> validate_required([:title, :content, :tag, :visibility]) |> cast(attrs, [:title, :content, :tags, :visibility])
|> change(user_id: user_id)
|> cast_tags_string(attrs)
|> validate_required([:title, :content, :user_id, :visibility])
end end
@spec update_changeset(Note.t(), attrs :: map(), User.t()) :: changeset()
def update_changeset(%{user_id: user_id} = note, attrs, %User{id: user_id}) do
note
|> cast(attrs, [:title, :content, :tags, :visibility])
|> cast_tags_string(attrs)
|> validate_required([:title, :content, :visibility])
end
defp cast_tags_string(changeset, %{"tags_string" => tags_string})
when tags_string |> is_binary() do
tags =
tags_string
|> String.split(",", trim: true)
|> Enum.map(fn str -> str |> String.trim() end)
|> Enum.sort()
changeset |> change(tags: tags)
end
defp cast_tags_string(changeset, _attrs), do: changeset
end end

View File

@ -0,0 +1,29 @@
defmodule MemexWeb.Components.NoteCard do
@moduledoc """
Display card for an note
"""
use MemexWeb, :component
def note_card(assigns) do
~H"""
<div class="mx-4 my-2 px-8 py-4 flex flex-col justify-center items-center space-y-4
border border-gray-400 rounded-lg shadow-lg hover:shadow-md
transition-all duration-300 ease-in-out">
<h1 class="title text-xl">
<%= @note.name %>
</h1>
<h2 class="title text-md">
<%= gettext("visibility: %{visibility}", visibility: @note.visibility) %>
</h2>
<%= if @inner_block do %>
<div class="flex space-x-4 justify-center items-center">
<%= render_slot(@inner_block) %>
</div>
<% end %>
</div>
"""
end
end

View File

@ -0,0 +1,136 @@
defmodule MemexWeb.Components.NotesTableComponent do
@moduledoc """
A component that displays a list of notes
"""
use MemexWeb, :live_component
alias Ecto.UUID
alias Memex.{Accounts.User, Notes, Notes.Note}
alias MemexWeb.Endpoint
alias Phoenix.LiveView.{Rendered, Socket}
@impl true
@spec update(
%{
required(:id) => UUID.t(),
required(:current_user) => User.t(),
required(:notes) => [Note.t()],
optional(any()) => any()
},
Socket.t()
) :: {:ok, Socket.t()}
def update(%{id: _id, notes: _notes, current_user: _current_user} = assigns, socket) do
socket =
socket
|> assign(assigns)
|> assign_new(:actions, fn -> [] end)
|> display_notes()
{:ok, socket}
end
defp display_notes(
%{
assigns: %{
notes: notes,
current_user: current_user,
actions: actions
}
} = socket
) do
columns =
if actions == [] or current_user |> is_nil() do
[]
else
[%{label: nil, key: :actions, sortable: false}]
end
columns = [
%{label: gettext("title"), key: :title},
%{label: gettext("content"), key: :content},
%{label: gettext("tags"), key: :tags},
%{label: gettext("visibility"), key: :visibility}
| columns
]
rows =
notes
|> Enum.map(fn note ->
note
|> get_row_data_for_note(%{
columns: columns,
current_user: current_user,
actions: actions
})
end)
socket |> assign(columns: columns, rows: rows)
end
@impl true
def render(assigns) do
~H"""
<div class="w-full">
<.live_component
module={MemexWeb.Components.TableComponent}
id={@id}
columns={@columns}
rows={@rows}
/>
</div>
"""
end
@spec get_row_data_for_note(Note.t(), additional_data :: map()) :: map()
defp get_row_data_for_note(note, %{columns: columns} = additional_data) do
columns
|> Map.new(fn %{key: key} ->
{key, get_value_for_key(key, note, additional_data)}
end)
end
@spec get_value_for_key(atom(), Note.t(), additional_data :: map()) ::
any() | {any(), Rendered.t()}
defp get_value_for_key(:title, %{id: id, title: title}, _additional_data) do
assigns = %{id: id, title: title}
title_block = ~H"""
<.link
navigate={Routes.note_show_path(Endpoint, :show, @id)}
class="link"
data-qa={"note-show-#{@id}"}
>
<%= @title %>
</.link>
"""
{title, title_block}
end
defp get_value_for_key(:content, %{content: content}, _additional_data) do
assigns = %{content: content}
content_block = ~H"""
<div class="truncate max-w-sm">
<%= @content %>
</div>
"""
{content, content_block}
end
defp get_value_for_key(:tags, %{tags: tags}, _additional_data) do
tags |> Notes.get_tags_string()
end
defp get_value_for_key(:actions, note, %{actions: actions}) do
assigns = %{actions: actions, note: note}
~H"""
<div class="flex justify-center items-center space-x-4">
<%= render_slot(@actions, @note) %>
</div>
"""
end
defp get_value_for_key(key, note, _additional_data), do: note |> Map.get(key)
end

View File

@ -4,8 +4,8 @@ defmodule MemexWeb.NoteLive.FormComponent do
alias Memex.Notes alias Memex.Notes
@impl true @impl true
def update(%{note: note} = assigns, socket) do def update(%{note: note, current_user: current_user} = assigns, socket) do
changeset = Notes.change_note(note) changeset = Notes.change_note(note, current_user)
{:ok, {:ok,
socket socket
@ -14,39 +14,51 @@ defmodule MemexWeb.NoteLive.FormComponent do
end end
@impl true @impl true
def handle_event("validate", %{"note" => note_params}, socket) do def handle_event(
"validate",
%{"note" => note_params},
%{assigns: %{note: note, current_user: current_user}} = socket
) do
changeset = changeset =
socket.assigns.note note
|> Notes.change_note(note_params) |> Notes.change_note(note_params, current_user)
|> Map.put(:action, :validate) |> Map.put(:action, :validate)
{:noreply, assign(socket, :changeset, changeset)} {:noreply, assign(socket, :changeset, changeset)}
end end
def handle_event("save", %{"note" => note_params}, socket) do def handle_event("save", %{"note" => note_params}, %{assigns: %{action: action}} = socket) do
save_note(socket, socket.assigns.action, note_params) save_note(socket, action, note_params)
end end
defp save_note(socket, :edit, note_params) do defp save_note(
case Notes.update_note(socket.assigns.note, note_params) do %{assigns: %{note: note, return_to: return_to, current_user: current_user}} = socket,
{:ok, _note} -> :edit,
note_params
) do
case Notes.update_note(note, note_params, current_user) do
{:ok, %{title: title}} ->
{:noreply, {:noreply,
socket socket
|> put_flash(:info, gettext("%{title} saved", title: title)) |> put_flash(:info, gettext("%{title} saved", title: title))
|> push_navigate(to: socket.assigns.return_to)} |> push_navigate(to: return_to)}
{:error, %Ecto.Changeset{} = changeset} -> {:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :changeset, changeset)} {:noreply, assign(socket, :changeset, changeset)}
end end
end end
defp save_note(socket, :new, note_params) do defp save_note(
case Notes.create_note(note_params) do %{assigns: %{return_to: return_to, current_user: current_user}} = socket,
{:ok, _note} -> :new,
note_params
) do
case Notes.create_note(note_params, current_user) do
{:ok, %{title: title}} ->
{:noreply, {:noreply,
socket socket
|> put_flash(:info, gettext("%{title} created", title: title)) |> put_flash(:info, gettext("%{title} created", title: title))
|> push_navigate(to: socket.assigns.return_to)} |> push_navigate(to: return_to)}
{:error, %Ecto.Changeset{} = changeset} -> {:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, changeset: changeset)} {:noreply, assign(socket, changeset: changeset)}

View File

@ -1,6 +1,4 @@
<div> <div class="h-full flex flex-col justify-start items-stretch space-y-4">
<h2><%= @title %></h2>
<.form <.form
:let={f} :let={f}
for={@changeset} for={@changeset}
@ -8,27 +6,44 @@
phx-target={@myself} phx-target={@myself}
phx-change="validate" phx-change="validate"
phx-submit="save" phx-submit="save"
phx-debounce="300"
class="flex flex-col justify-start items-stretch space-y-4"
> >
<%= label(f, :title) %> <%= text_input(f, :title,
<%= text_input(f, :title) %> class: "input input-primary",
placeholder: gettext("title")
) %>
<%= error_tag(f, :title) %> <%= error_tag(f, :title) %>
<%= label(f, :content) %> <%= textarea(f, :content,
<%= textarea(f, :content) %> id: "note-form-content",
class: "input input-primary h-64 min-h-64",
phx_hook: "MaintainAttrs",
phx_update: "ignore",
placeholder: gettext("content")
) %>
<%= error_tag(f, :content) %> <%= error_tag(f, :content) %>
<%= label(f, :tag) %> <%= text_input(f, :tags_string,
<%= multiple_select(f, :tag, "Option 1": "option1", "Option 2": "option2") %> id: "tags-input",
<%= error_tag(f, :tag) %> class: "input input-primary",
placeholder: gettext("tag1,tag2"),
<%= label(f, :visibility) %> phx_update: "ignore",
<%= select(f, :visibility, Ecto.Enum.values(Memex.Notes.Note, :visibility), value: Notes.get_tags_string(@changeset)
prompt: "Choose a value"
) %> ) %>
<%= error_tag(f, :visibility) %> <%= error_tag(f, :tags_string) %>
<div> <div class="flex justify-center items-stretch space-x-4">
<%= submit("Save", phx_disable_with: "Saving...") %> <%= select(f, :visibility, Ecto.Enum.values(Memex.Notes.Note, :visibility),
class: "grow input input-primary",
prompt: gettext("select privacy")
) %>
<%= submit(dgettext("actions", "save"),
phx_disable_with: gettext("saving..."),
class: "mx-auto btn btn-primary"
) %>
</div> </div>
<%= error_tag(f, :visibility) %>
</.form> </.form>
</div> </div>

View File

@ -1,45 +1,52 @@
defmodule MemexWeb.NoteLive.Index do defmodule MemexWeb.NoteLive.Index do
use MemexWeb, :live_view use MemexWeb, :live_view
alias Memex.{Notes, Notes.Note}
alias Memex.Notes
alias Memex.Notes.Note
@impl true @impl true
def mount(_params, _session, %{assigns: %{current_user: current_user}} = socket)
when not (current_user |> is_nil()) do
{:ok, socket |> assign(notes: Notes.list_notes(current_user))}
end
def mount(_params, _session, socket) do def mount(_params, _session, socket) do
{:ok, assign(socket, :notes, list_notes())} {:ok, socket |> assign(notes: Notes.list_public_notes())}
end end
@impl true @impl true
def handle_params(params, _url, socket) do def handle_params(params, _url, %{assigns: %{live_action: live_action}} = socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)} {:noreply, apply_action(socket, live_action, params)}
end end
defp apply_action(socket, :edit, %{"id" => id}) do defp apply_action(%{assigns: %{current_user: current_user}} = socket, :edit, %{"id" => id}) do
%{title: title} = note = Notes.get_note!(id, current_user)
socket socket
|> assign(page_title: gettext("edit %{title}", title: title)) |> assign(page_title: gettext("edit %{title}", title: title))
|> assign(:note, Notes.get_note!(id)) |> assign(note: note)
end end
defp apply_action(socket, :new, _params) do defp apply_action(%{assigns: %{current_user: %{id: current_user_id}}} = socket, :new, _params) do
socket socket
|> assign(page_title: "new note") |> assign(page_title: "new note")
|> assign(:note, %Note{}) |> assign(note: %Note{user_id: current_user_id})
end end
defp apply_action(socket, :index, _params) do defp apply_action(socket, :index, _params) do
socket socket
|> assign(page_title: "notes") |> assign(page_title: "notes")
|> assign(:note, nil) |> assign(note: nil)
end end
@impl true @impl true
def handle_event("delete", %{"id" => id}, socket) do def handle_event("delete", %{"id" => id}, %{assigns: %{current_user: current_user}} = socket) do
note = Notes.get_note!(id) %{title: title} = note = Notes.get_note!(id, current_user)
{:ok, _} = Notes.delete_note(note) {:ok, _} = Notes.delete_note(note, current_user)
socket =
socket
|> assign(notes: Notes.list_notes(current_user))
|> put_flash(:info, gettext("%{title} deleted", title: title)) |> put_flash(:info, gettext("%{title} deleted", title: title))
defp list_notes do {:noreply, socket}
Notes.list_notes()
end end
end end

View File

@ -1,10 +1,54 @@
<h1>Listing Notes</h1> <div class="mx-auto flex flex-col justify-center items-start space-y-4 max-w-3xl">
<h1 class="text-xl">
<%= gettext("notes") %>
</h1>
<%= if @notes |> Enum.empty?() do %>
<h1 class="self-center text-primary-500">
<%= gettext("no notes found") %>
</h1>
<% else %>
<.live_component
module={MemexWeb.Components.NotesTableComponent}
id="notes-index-table"
current_user={@current_user}
notes={@notes}
>
<:actions :let={note}>
<%= if @current_user do %>
<.link
patch={Routes.note_index_path(@socket, :edit, note)}
data-qa={"note-edit-#{note.id}"}
>
<%= dgettext("actions", "edit") %>
</.link>
<.link
href="#"
phx-click="delete"
phx-value-id={note.id}
data-confirm={dgettext("prompts", "are you sure?")}
data-qa={"delete-note-#{note.id}"}
>
<%= dgettext("actions", "delete") %>
</.link>
<% end %>
</:actions>
</.live_component>
<% end %>
<%= if @current_user do %>
<.link patch={Routes.note_index_path(@socket, :new)} class="self-end btn btn-primary">
<%= dgettext("actions", "new note") %>
</.link>
<% end %>
</div>
<%= if @live_action in [:new, :edit] do %> <%= if @live_action in [:new, :edit] do %>
<.modal return_to={Routes.note_index_path(@socket, :index)}> <.modal return_to={Routes.note_index_path(@socket, :index)}>
<.live_component <.live_component
module={MemexWeb.NoteLive.FormComponent} module={MemexWeb.NoteLive.FormComponent}
id={@note.id || :new} id={@note.id || :new}
current_user={@current_user}
title={@page_title} title={@page_title}
action={@live_action} action={@live_action}
note={@note} note={@note}
@ -12,55 +56,3 @@
/> />
</.modal> </.modal>
<% end %> <% end %>
<table>
<thead>
<tr>
<th>Title</th>
<th>Content</th>
<th>Tag</th>
<th>Visibility</th>
<th></th>
</tr>
</thead>
<tbody id="notes">
<%= for note <- @notes do %>
<tr id={"note-#{note.id}"}>
<td><%= note.title %></td>
<td><%= note.content %></td>
<td><%= note.tag %></td>
<td><%= note.visibility %></td>
<td>
<span>
<.link navigate={Routes.note_show_path(@socket, :show, note)}>
<%= dgettext("actions", "Show") %>
</.link>
</span>
<span>
<.link patch={Routes.note_index_path(@socket, :edit, note)}>
<%= dgettext("actions", "Edit") %>
</.link>
</span>
<span>
<.link
href="#"
phx-click="delete"
phx-value-id={note.id}
data-confirm={dgettext("prompts", "Are you sure?")}
>
<%= dgettext("actions", "Delete") %>
</.link>
</span>
</td>
</tr>
<% end %>
</tbody>
</table>
<span>
<.link patch={Routes.note_index_path(@socket, :new)}>
<%= dgettext("actions", "New Note") %>
</.link>
</span>

View File

@ -9,11 +9,15 @@ defmodule MemexWeb.NoteLive.Show do
end end
@impl true @impl true
def handle_params(%{"id" => id}, _, socket) do def handle_params(
%{"id" => id},
_,
%{assigns: %{live_action: live_action, current_user: current_user}} = socket
) do
{:noreply, {:noreply,
socket socket
|> assign(:page_title, page_title(socket.assigns.live_action)) |> assign(:page_title, page_title(live_action))
|> assign(:note, Notes.get_note!(id))} |> assign(:note, Notes.get_note!(id, current_user))}
end end
defp page_title(:show), do: "show note" defp page_title(:show), do: "show note"

View File

@ -1,10 +1,41 @@
<h1>Show Note</h1> <div class="mx-auto flex flex-col justify-center items-stretch space-y-4 max-w-3xl">
<h1 class="text-xl">
<%= @note.title %>
</h1>
<p><%= if @note.tags, do: @note.tags |> Enum.join(", ") %></p>
<textarea
id="show-note-content"
class="input input-primary h-128 min-h-128"
phx-hook="MaintainAttrs"
phx-update="ignore"
readonly
phx-no-format
><%= @note.content %></textarea>
<p class="self-end">
<%= gettext("Visibility: %{visibility}", visibility: @note.visibility) %>
</p>
<div class="self-end flex space-x-4">
<.link class="btn btn-primary" patch={Routes.note_index_path(@socket, :index)}>
<%= dgettext("actions", "Back") %>
</.link>
<%= if @current_user do %>
<.link class="btn btn-primary" patch={Routes.note_show_path(@socket, :edit, @note)}>
<%= dgettext("actions", "edit") %>
</.link>
<% end %>
</div>
</div>
<%= if @live_action in [:edit] do %> <%= if @live_action in [:edit] do %>
<.modal return_to={Routes.note_show_path(@socket, :show, @note)}> <.modal return_to={Routes.note_show_path(@socket, :show, @note)}>
<.live_component <.live_component
module={MemexWeb.NoteLive.FormComponent} module={MemexWeb.NoteLive.FormComponent}
id={@note.id} id={@note.id}
current_user={@current_user}
title={@page_title} title={@page_title}
action={@live_action} action={@live_action}
note={@note} note={@note}
@ -12,37 +43,3 @@
/> />
</.modal> </.modal>
<% end %> <% end %>
<ul>
<li>
<strong>Title:</strong>
<%= @note.title %>
</li>
<li>
<strong>Content:</strong>
<%= @note.content %>
</li>
<li>
<strong>Tag:</strong>
<%= @note.tag %>
</li>
<li>
<strong>Visibility:</strong>
<%= @note.visibility %>
</li>
</ul>
<span>
<.link patch={Routes.note_show_path(@socket, :edit, @note)} class="button">
<%= dgettext("actions", "Edit") %>
</.link>
</span>
|
<span>
<.link patch={Routes.note_index_path(@socket, :index)}>
<%= dgettext("actions", "Back") %>
</.link>
</span>

View File

@ -10,95 +10,141 @@
msgid "" msgid ""
msgstr "" msgstr ""
#: lib/memex_web/live/context_live/show.html.heex:46
#: lib/memex_web/live/note_live/show.html.heex:23
#: lib/memex_web/live/pipeline_live/show.html.heex:41
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:113 msgid "Back"
msgid "Change Language"
msgstr "" msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:30
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:15
#: lib/memex_web/templates/user_settings/edit.html.heex:44
msgid "Change email"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:131
msgid "Change language"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:58
#: lib/memex_web/templates/user_settings/edit.html.heex:99
msgid "Change password"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:32
msgid "Copy to clipboard" msgid "Copy to clipboard"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:16
msgid "Create Invite"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:139
msgid "Delete User"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_registration/new.html.heex:51 #: lib/memex_web/templates/user_registration/new.html.heex:51
#: lib/memex_web/templates/user_reset_password/new.html.heex:3 #: lib/memex_web/templates/user_reset_password/new.html.heex:3
#: lib/memex_web/templates/user_session/new.html.heex:44 #: lib/memex_web/templates/user_session/new.html.heex:44
#, elixir-autogen, elixir-format
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_confirmation/new.html.heex:3
#: lib/memex_web/templates/user_confirmation/new.html.heex:15
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:11 msgid "Resend confirmation instructions"
msgid "Invite someone new!"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_reset_password/edit.html.heex:3
#: lib/memex_web/templates/user_reset_password/edit.html.heex:33
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/components/topbar.ex:119 msgid "Reset password"
msgstr ""
#: lib/memex_web/live/invite_live/form_component.html.heex:28
#, elixir-autogen, elixir-format
msgid "Save"
msgstr ""
#: lib/memex_web/templates/user_reset_password/new.html.heex:15
#, elixir-autogen, elixir-format
msgid "Send instructions to reset password"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:15
#: lib/memex_web/templates/user_settings/edit.html.heex:44
#, elixir-autogen, elixir-format
msgid "change email"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:113
#: lib/memex_web/templates/user_settings/edit.html.heex:131
#, elixir-autogen, elixir-format
msgid "change language"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:58
#: lib/memex_web/templates/user_settings/edit.html.heex:99
#, elixir-autogen, elixir-format
msgid "change password"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:16
#, elixir-autogen, elixir-format
msgid "create invite"
msgstr ""
#: lib/memex_web/live/context_live/index.html.heex:53
#: lib/memex_web/live/note_live/index.html.heex:32
#: lib/memex_web/live/pipeline_live/index.html.heex:51
#, elixir-autogen, elixir-format
msgid "delete"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:145
#, elixir-autogen, elixir-format
msgid "delete user"
msgstr ""
#: lib/memex_web/live/context_live/index.html.heex:43
#: lib/memex_web/live/context_live/show.html.heex:40
#: lib/memex_web/live/note_live/index.html.heex:23
#: lib/memex_web/live/note_live/show.html.heex:27
#: lib/memex_web/live/pipeline_live/index.html.heex:41
#: lib/memex_web/live/pipeline_live/show.html.heex:35
#, elixir-autogen, elixir-format
msgid "edit"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:12
#, elixir-autogen, elixir-format
msgid "invite someone new!"
msgstr ""
#: lib/memex_web/components/topbar.ex:125
#: lib/memex_web/templates/user_confirmation/new.html.heex:29 #: lib/memex_web/templates/user_confirmation/new.html.heex:29
#: lib/memex_web/templates/user_registration/new.html.heex:47 #: lib/memex_web/templates/user_registration/new.html.heex:48
#: lib/memex_web/templates/user_reset_password/edit.html.heex:47 #: lib/memex_web/templates/user_reset_password/edit.html.heex:47
#: lib/memex_web/templates/user_reset_password/new.html.heex:29 #: lib/memex_web/templates/user_reset_password/new.html.heex:29
#: lib/memex_web/templates/user_session/new.html.heex:3 #: lib/memex_web/templates/user_session/new.html.heex:3
#: lib/memex_web/templates/user_session/new.html.heex:32 #: lib/memex_web/templates/user_session/new.html.heex:32
msgid "Log in" #, elixir-autogen, elixir-format
msgid "log in"
msgstr "" msgstr ""
#: lib/memex_web/live/context_live/index.html.heex:64
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/components/topbar.ex:111 msgid "new context"
#: lib/memex_web/templates/user_confirmation/new.html.heex:24 msgstr ""
#: lib/memex_web/live/note_live/index.html.heex:41
#, elixir-autogen, elixir-format
msgid "new note"
msgstr ""
#: lib/memex_web/live/pipeline_live/index.html.heex:62
#, elixir-autogen, elixir-format
msgid "new pipeline"
msgstr ""
#: lib/memex_web/components/topbar.ex:115
#: lib/memex_web/templates/user_confirmation/new.html.heex:25
#: lib/memex_web/templates/user_registration/new.html.heex:3 #: lib/memex_web/templates/user_registration/new.html.heex:3
#: lib/memex_web/templates/user_registration/new.html.heex:41 #: lib/memex_web/templates/user_registration/new.html.heex:41
#: lib/memex_web/templates/user_reset_password/edit.html.heex:42 #: lib/memex_web/templates/user_reset_password/edit.html.heex:43
#: lib/memex_web/templates/user_reset_password/new.html.heex:24 #: lib/memex_web/templates/user_reset_password/new.html.heex:25
#: lib/memex_web/templates/user_session/new.html.heex:39 #: lib/memex_web/templates/user_session/new.html.heex:40
msgid "Register" #, elixir-autogen, elixir-format
msgid "register"
msgstr "" msgstr ""
#: lib/memex_web/live/note_live/form_component.html.heex:42
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_confirmation/new.html.heex:3 msgid "save"
#: lib/memex_web/templates/user_confirmation/new.html.heex:15
msgid "Resend confirmation instructions"
msgstr "" msgstr ""
#: lib/memex_web/live/context_live/index.html.heex:38
#: lib/memex_web/live/pipeline_live/index.html.heex:36
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_reset_password/edit.html.heex:3 msgid "show"
#: lib/memex_web/templates/user_reset_password/edit.html.heex:33
msgid "Reset password"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/form_component.html.heex:28
msgid "Save"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_reset_password/new.html.heex:15
msgid "Send instructions to reset password"
msgstr "" msgstr ""

View File

@ -10,297 +10,391 @@
msgid "" msgid ""
msgstr "" msgstr ""
#: lib/memex_web/live/note_live/form_component.ex:60
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:73 msgid "%{title} created"
msgid "Accessible from any internet-capable device"
msgstr "" msgstr ""
#: lib/memex_web/live/note_live/index.ex:48
#, elixir-autogen, elixir-format
msgid "%{title} deleted"
msgstr ""
#: lib/memex_web/live/note_live/form_component.ex:43
#, elixir-autogen, elixir-format
msgid "%{title} saved"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:90
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:89
msgid "Admins" msgid "Admins"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:53
msgid "Built with sharing and collaboration in mind"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:78
msgid "Confirm new password"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_confirmation_controller.ex:8 #: lib/memex_web/controllers/user_confirmation_controller.ex:8
#, elixir-autogen, elixir-format
msgid "Confirm your account" msgid "Confirm your account"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/components/topbar.ex:63
msgid "Contexts"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:22
msgid "Contexts:"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:70
msgid "Convenient:"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:32
#: lib/memex_web/templates/user_settings/edit.html.heex:87
msgid "Current password"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:58
msgid "Disable"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:15
msgid "Document notes about individual items or concepts"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:35
msgid "Document your processes, attaching contexts to each step"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:33
msgid "Edit Invite"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:62
msgid "Enable"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_registration/new.html.heex:36 #: lib/memex_web/templates/user_registration/new.html.heex:36
#: lib/memex_web/templates/user_settings/edit.html.heex:126 #, elixir-autogen, elixir-format
msgid "English" msgid "English"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:44
msgid "Features"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_reset_password_controller.ex:9 #: lib/memex_web/controllers/user_reset_password_controller.ex:9
#, elixir-autogen, elixir-format
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.ex:12 #: lib/memex_web/live/home_live.ex:12
#, elixir-autogen, elixir-format
msgid "Home" msgid "Home"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/components/invite_card.ex:25
msgid "Invite Disabled"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/components/topbar.ex:78
#: lib/memex_web/live/invite_live/index.ex:41
#: lib/memex_web/live/invite_live/index.html.heex:3
msgid "Invites"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_session/new.html.heex:27 #: lib/memex_web/templates/user_session/new.html.heex:27
#, elixir-autogen, elixir-format
msgid "Keep me logged in for 60 days" msgid "Keep me logged in for 60 days"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_registration/new.html.heex:32 #: lib/memex_web/templates/user_registration/new.html.heex:32
#, elixir-autogen, elixir-format
msgid "Language" msgid "Language"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/layout/live.html.heex:37 #: lib/memex_web/templates/layout/live.html.heex:37
#, elixir-autogen, elixir-format
msgid "Loading..." msgid "Loading..."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_session_controller.ex:8
msgid "Log in"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:50
msgid "Multi-user:"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/form_component.html.heex:20 #: lib/memex_web/live/invite_live/form_component.html.heex:20
#, elixir-autogen, elixir-format
msgid "Name" msgid "Name"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:37
msgid "New Invite"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:71
msgid "New password"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:8
msgid "No invites 😔"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/components/topbar.ex:70
msgid "Notes"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:12
msgid "Notes:"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/components/topbar.ex:56
msgid "Pipelines"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:32
msgid "Pipelines:"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:63
msgid "Privacy controls on a per-note, context or pipeline basis"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:60
msgid "Privacy:"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:25
msgid "Provide context around a single topic and hotlink to your notes"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/layout/live.html.heex:50 #: lib/memex_web/templates/layout/live.html.heex:50
#, elixir-autogen, elixir-format
msgid "Reconnecting..." msgid "Reconnecting..."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_registration_controller.ex:35
msgid "Register"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_reset_password_controller.ex:36 #: lib/memex_web/controllers/user_reset_password_controller.ex:36
#, elixir-autogen, elixir-format
msgid "Reset your password" msgid "Reset your password"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:78
msgid "Set Unlimited"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_settings_controller.ex:10 #: lib/memex_web/controllers/user_settings_controller.ex:10
#: lib/memex_web/templates/user_settings/edit.html.heex:3 #, elixir-autogen, elixir-format
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
#: lib/memex_web/components/user_card.ex:33
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/components/user_card.ex:30
msgid "User registered on" msgid "User registered on"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:118
msgid "Users"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/components/invite_card.ex:20 #: lib/memex_web/components/invite_card.ex:20
#, elixir-autogen, elixir-format
msgid "Uses Left:" msgid "Uses Left:"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/form_component.html.heex:24 #: lib/memex_web/live/invite_live/form_component.html.heex:24
#, elixir-autogen, elixir-format
msgid "Uses left" msgid "Uses left"
msgstr "" msgstr ""
#: lib/memex_web/live/note_live/show.html.heex:18
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
msgid "Visibility: %{visibility}"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:73
#, elixir-autogen, elixir-format
msgid "accessible from any internet-capable device"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:87
#, elixir-autogen, elixir-format
msgid "admins:"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:53
#, elixir-autogen, elixir-format
msgid "built with sharing and collaboration in mind"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:78
#, elixir-autogen, elixir-format
msgid "confirm new password"
msgstr ""
#: lib/memex_web/components/notes_table_component.ex:49
#: lib/memex_web/live/note_live/form_component.html.heex:23
#, elixir-autogen, elixir-format
msgid "content"
msgstr ""
#: lib/memex_web/components/topbar.ex:53
#, elixir-autogen, elixir-format
msgid "contexts"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:22
#, elixir-autogen, elixir-format
msgid "contexts:"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:70
#, elixir-autogen, elixir-format
msgid "convenient:"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:32
#: lib/memex_web/templates/user_settings/edit.html.heex:87
#, elixir-autogen, elixir-format
msgid "current password"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:59
#, elixir-autogen, elixir-format
msgid "disable"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:15
#, elixir-autogen, elixir-format
msgid "document notes about individual items or concepts"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:35
#, elixir-autogen, elixir-format
msgid "document your processes, attaching contexts to each step"
msgstr ""
#: lib/memex_web/live/note_live/index.ex:24
#, elixir-autogen, elixir-format
msgid "edit %{title}"
msgstr ""
#: lib/memex_web/live/invite_live/index.ex:33
#, elixir-autogen, elixir-format
msgid "edit invite"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:28
#, elixir-autogen, elixir-format
msgid "email"
msgstr ""
#: lib/memex_web/components/user_card.ex:23
#, elixir-autogen, elixir-format
msgid "email unconfirmed"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:63
#, elixir-autogen, elixir-format
msgid "enable"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:126
#, elixir-autogen, elixir-format
msgid "english"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:44
#, elixir-autogen, elixir-format
msgid "features"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:138
#, elixir-autogen, elixir-format
msgid "get involved!"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:159
#, elixir-autogen, elixir-format
msgid "help translate"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:82
#, elixir-autogen, elixir-format
msgid "instance information"
msgstr ""
#: lib/memex_web/components/invite_card.ex:25
#, elixir-autogen, elixir-format
msgid "invite disabled"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:115
#, elixir-autogen, elixir-format
msgid "invite only"
msgstr ""
#: lib/memex_web/components/topbar.ex:74
#: lib/memex_web/live/invite_live/index.ex:41
#: lib/memex_web/live/invite_live/index.html.heex:3
#, elixir-autogen, elixir-format
msgid "invites"
msgstr ""
#: lib/memex_web/controllers/user_session_controller.ex:8
#, elixir-autogen, elixir-format
msgid "log in"
msgstr ""
#: lib/memex_web/components/topbar.ex:23
#: lib/memex_web/live/home_live.html.heex:3 #: lib/memex_web/live/home_live.html.heex:3
#: lib/memex_web/templates/layout/root.html.heex:8
#: lib/memex_web/templates/layout/root.html.heex:9
#, elixir-autogen, elixir-format
msgid "memex" msgid "memex"
msgstr "" msgstr ""
#: lib/memex_web/live/home_live.html.heex:50
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:87 msgid "multi-user:"
msgid "Admins:"
msgstr "" msgstr ""
#: lib/memex_web/live/invite_live/index.ex:37
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/note_live/form_component.html.heex:20 msgid "new invite"
msgid "Content"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:71
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:134 msgid "new password"
msgid "Get involved!"
msgstr "" msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:8
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:151 msgid "no invites 😔"
msgid "Help translate"
msgstr "" msgstr ""
#: lib/memex_web/live/note_live/index.html.heex:8
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:82 msgid "no notes found"
msgid "Instance Information"
msgstr "" msgstr ""
#: lib/memex_web/components/topbar.ex:44
#: lib/memex_web/live/note_live/index.html.heex:3
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:113 msgid "notes"
msgid "Invite Only"
msgstr "" msgstr ""
#: lib/memex_web/live/home_live.html.heex:12
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:112 msgid "notes:"
msgid "Public Signups"
msgstr "" msgstr ""
#: lib/memex_web/components/topbar.ex:62
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:160 msgid "pipelines"
msgid "Report bugs or request features"
msgstr "" msgstr ""
#: lib/memex_web/live/home_live.html.heex:32
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/note_live/form_component.html.heex:35 msgid "pipelines:"
msgid "Save"
msgstr "" msgstr ""
#: lib/memex_web/live/home_live.html.heex:63
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/note_live/form_component.html.heex:36 msgid "privacy controls on a per-note, context or pipeline basis"
msgid "Saving..."
msgstr "" msgstr ""
#: lib/memex_web/live/home_live.html.heex:60
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/note_live/form_component.html.heex:13 msgid "privacy:"
msgid "Title"
msgstr "" msgstr ""
#: lib/memex_web/live/home_live.html.heex:25
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:142 msgid "provide context around a single topic and hotlink to your notes"
msgid "View the source code" msgstr ""
#: lib/memex_web/live/home_live.html.heex:114
#, elixir-autogen, elixir-format
msgid "public signups"
msgstr ""
#: lib/memex_web/controllers/user_registration_controller.ex:35
#, elixir-autogen, elixir-format
msgid "register"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:110
#, elixir-autogen, elixir-format
msgid "registration:"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:170
#, elixir-autogen, elixir-format
msgid "report bugs or request features"
msgstr ""
#: lib/memex_web/live/note_live/form_component.html.heex:43
#, elixir-autogen, elixir-format
msgid "saving..."
msgstr ""
#: lib/memex_web/live/note_live/form_component.html.heex:39
#, elixir-autogen, elixir-format
msgid "select privacy"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:79
#, elixir-autogen, elixir-format
msgid "set unlimited"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:3
#, elixir-autogen, elixir-format
msgid "settings"
msgstr ""
#: lib/memex_web/live/note_live/form_component.html.heex:30
#, elixir-autogen, elixir-format
msgid "tag1,tag2"
msgstr ""
#: lib/memex_web/components/notes_table_component.ex:50
#, elixir-autogen, elixir-format
msgid "tags"
msgstr ""
#: lib/memex_web/components/notes_table_component.ex:48
#: lib/memex_web/live/note_live/form_component.html.heex:14
#, elixir-autogen, elixir-format
msgid "title"
msgstr ""
#: lib/memex_web/components/invite_card.ex:21
#, elixir-autogen, elixir-format
msgid "unlimited"
msgstr ""
#: lib/memex_web/components/user_card.ex:25
#, elixir-autogen, elixir-format
msgid "user was confirmed at %{relative_datetime}"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:120
#, elixir-autogen, elixir-format
msgid "users"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:121
#, elixir-autogen, elixir-format
msgid "version:"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:148
#, elixir-autogen, elixir-format
msgid "view the source code"
msgstr ""
#: lib/memex_web/components/notes_table_component.ex:51
#, elixir-autogen, elixir-format
msgid "visibility"
msgstr ""
#: lib/memex_web/components/note_card.ex:18
#, elixir-autogen, elixir-format
msgid "visibility: %{visibility}"
msgstr "" msgstr ""

View File

@ -10,83 +10,83 @@
msgid "" msgid ""
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex/accounts/email.ex:30 #: lib/memex/accounts/email.ex:30
#, elixir-autogen, elixir-format
msgid "Confirm your Memex account" msgid "Confirm your Memex account"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/confirm_email.html.heex:3 #: lib/memex_web/templates/email/confirm_email.html.heex:3
#: lib/memex_web/templates/email/confirm_email.txt.eex:2 #: lib/memex_web/templates/email/confirm_email.txt.eex:2
#: lib/memex_web/templates/email/reset_password.html.heex:3 #: lib/memex_web/templates/email/reset_password.html.heex:3
#: lib/memex_web/templates/email/reset_password.txt.eex:2 #: lib/memex_web/templates/email/reset_password.txt.eex:2
#: lib/memex_web/templates/email/update_email.html.heex:3 #: lib/memex_web/templates/email/update_email.html.heex:3
#: lib/memex_web/templates/email/update_email.txt.eex:2 #: lib/memex_web/templates/email/update_email.txt.eex:2
#, elixir-autogen, elixir-format
msgid "Hi %{email}," msgid "Hi %{email},"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/confirm_email.txt.eex:10 #: lib/memex_web/templates/email/confirm_email.txt.eex:10
#, elixir-autogen, elixir-format
msgid "If you didn't create an account at %{url}, please ignore this." msgid "If you didn't create an account at %{url}, please ignore this."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/confirm_email.html.heex:22 #: lib/memex_web/templates/email/confirm_email.html.heex:22
#, elixir-autogen, elixir-format
msgid "If you didn't create an account at Memex, please ignore this." msgid "If you didn't create an account at Memex, please ignore this."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/reset_password.txt.eex:8 #: lib/memex_web/templates/email/reset_password.txt.eex:8
#: lib/memex_web/templates/email/update_email.txt.eex:8 #: lib/memex_web/templates/email/update_email.txt.eex:8
#, elixir-autogen, elixir-format
msgid "If you didn't request this change from %{url}, please ignore this." msgid "If you didn't request this change from %{url}, please ignore this."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/reset_password.html.heex:16 #: lib/memex_web/templates/email/reset_password.html.heex:16
#: lib/memex_web/templates/email/update_email.html.heex:16 #: lib/memex_web/templates/email/update_email.html.heex:16
#, elixir-autogen, elixir-format
msgid "If you didn't request this change from Memex, please ignore this." msgid "If you didn't request this change from Memex, please ignore this."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex/accounts/email.ex:37 #: lib/memex/accounts/email.ex:37
#, elixir-autogen, elixir-format
msgid "Reset your Memex password" msgid "Reset your Memex password"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/layout/email.txt.eex:9 #: lib/memex_web/templates/layout/email.txt.eex:9
#, elixir-autogen, elixir-format
msgid "This email was sent from Memex at %{url}, the self-hosted firearm tracker website." msgid "This email was sent from Memex at %{url}, the self-hosted firearm tracker website."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/layout/email.html.heex:13 #: lib/memex_web/templates/layout/email.html.heex:13
#, elixir-autogen, elixir-format
msgid "This email was sent from Memex, the self-hosted firearm tracker website." msgid "This email was sent from Memex, the self-hosted firearm tracker website."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex/accounts/email.ex:44 #: lib/memex/accounts/email.ex:44
#, elixir-autogen, elixir-format
msgid "Update your Memex email" msgid "Update your Memex email"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/confirm_email.html.heex:9 #: lib/memex_web/templates/email/confirm_email.html.heex:9
#: lib/memex_web/templates/email/confirm_email.txt.eex:4 #: lib/memex_web/templates/email/confirm_email.txt.eex:4
#, elixir-autogen, elixir-format
msgid "Welcome to Memex" msgid "Welcome to Memex"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/update_email.html.heex:8 #: lib/memex_web/templates/email/update_email.html.heex:8
#: lib/memex_web/templates/email/update_email.txt.eex:4 #: lib/memex_web/templates/email/update_email.txt.eex:4
#, elixir-autogen, elixir-format
msgid "You can change your email by visiting the URL below:" msgid "You can change your email by visiting the URL below:"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/confirm_email.html.heex:14 #: lib/memex_web/templates/email/confirm_email.html.heex:14
#: lib/memex_web/templates/email/confirm_email.txt.eex:6 #: lib/memex_web/templates/email/confirm_email.txt.eex:6
#, elixir-autogen, elixir-format
msgid "You can confirm your account by visiting the URL below:" msgid "You can confirm your account by visiting the URL below:"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/email/reset_password.html.heex:8 #: lib/memex_web/templates/email/reset_password.html.heex:8
#: lib/memex_web/templates/email/reset_password.txt.eex:4 #: lib/memex_web/templates/email/reset_password.txt.eex:4
#, elixir-autogen, elixir-format
msgid "You can reset your password by visiting the URL below:" msgid "You can reset your password by visiting the URL below:"
msgstr "" msgstr ""

View File

@ -10,109 +10,113 @@
msgid "" msgid ""
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_settings_controller.ex:84 #: lib/memex_web/controllers/user_settings_controller.ex:84
#, elixir-autogen, elixir-format
msgid "Email change link is invalid or it has expired." msgid "Email change link is invalid or it has expired."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/error/error.html.heex:8 #: lib/memex_web/templates/error/error.html.heex:8
#, elixir-autogen, elixir-format
msgid "Error" msgid "Error"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/error/error.html.heex:28 #: lib/memex_web/templates/error/error.html.heex:28
#, elixir-autogen, elixir-format
msgid "Go back home" msgid "Go back home"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/views/error_view.ex:11 #: lib/memex_web/views/error_view.ex:11
#, elixir-autogen, elixir-format
msgid "Internal Server Error" msgid "Internal Server Error"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_session_controller.ex:17 #: lib/memex_web/controllers/user_session_controller.ex:17
#, elixir-autogen, elixir-format
msgid "Invalid email or password" msgid "Invalid email or password"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/views/error_view.ex:9 #: lib/memex_web/views/error_view.ex:9
#, elixir-autogen, elixir-format
msgid "Not found" msgid "Not found"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_registration/new.html.heex:15 #: lib/memex_web/templates/user_registration/new.html.heex:15
#: lib/memex_web/templates/user_reset_password/edit.html.heex:15 #: lib/memex_web/templates/user_reset_password/edit.html.heex:15
#: lib/memex_web/templates/user_settings/edit.html.heex:21
#: lib/memex_web/templates/user_settings/edit.html.heex:64 #: lib/memex_web/templates/user_settings/edit.html.heex:64
#: lib/memex_web/templates/user_settings/edit.html.heex:119 #, elixir-autogen, elixir-format
msgid "Oops, something went wrong! Please check the errors below." msgid "Oops, something went wrong! Please check the errors below."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_reset_password_controller.ex:63 #: lib/memex_web/controllers/user_reset_password_controller.ex:63
#, elixir-autogen, elixir-format
msgid "Reset password link is invalid or it has expired." msgid "Reset password link is invalid or it has expired."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_registration_controller.ex:25 #: lib/memex_web/controllers/user_registration_controller.ex:25
#: lib/memex_web/controllers/user_registration_controller.ex:56 #: lib/memex_web/controllers/user_registration_controller.ex:56
#, elixir-autogen, elixir-format
msgid "Sorry, public registration is disabled" msgid "Sorry, public registration is disabled"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_registration_controller.ex:15 #: lib/memex_web/controllers/user_registration_controller.ex:15
#: lib/memex_web/controllers/user_registration_controller.ex:46 #: lib/memex_web/controllers/user_registration_controller.ex:46
#, elixir-autogen, elixir-format
msgid "Sorry, this invite was not found or expired" msgid "Sorry, this invite was not found or expired"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_settings_controller.ex:99 #: lib/memex_web/controllers/user_settings_controller.ex:99
#, elixir-autogen, elixir-format
msgid "Unable to delete user" msgid "Unable to delete user"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/views/error_view.ex:10 #: lib/memex_web/views/error_view.ex:10
#, elixir-autogen, elixir-format
msgid "Unauthorized" msgid "Unauthorized"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_confirmation_controller.ex:54 #: lib/memex_web/controllers/user_confirmation_controller.ex:54
#, elixir-autogen, elixir-format
msgid "User confirmation link is invalid or it has expired." msgid "User confirmation link is invalid or it has expired."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:18 #: lib/memex_web/live/invite_live/index.ex:18
#, elixir-autogen, elixir-format
msgid "You are not authorized to view this page" msgid "You are not authorized to view this page"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_auth.ex:177 #: lib/memex_web/controllers/user_auth.ex:177
#, elixir-autogen, elixir-format
msgid "You are not authorized to view this page." msgid "You are not authorized to view this page."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_auth.ex:39 #: lib/memex_web/controllers/user_auth.ex:39
#: lib/memex_web/controllers/user_auth.ex:161 #: lib/memex_web/controllers/user_auth.ex:161
#, elixir-autogen, elixir-format
msgid "You must confirm your account and log in to access this page." msgid "You must confirm your account and log in to access this page."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex/accounts/user.ex:130 #: lib/memex/accounts/user.ex:130
#, elixir-autogen, elixir-format
msgid "did not change" msgid "did not change"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex/accounts/user.ex:151 #: lib/memex/accounts/user.ex:151
#, elixir-autogen, elixir-format
msgid "does not match password" msgid "does not match password"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex/accounts/user.ex:188 #: lib/memex/accounts/user.ex:188
#, elixir-autogen, elixir-format
msgid "is not valid" msgid "is not valid"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex/accounts/user.ex:84 #: lib/memex/accounts/user.ex:84
#, elixir-autogen, elixir-format
msgid "must have the @ sign and no spaces" msgid "must have the @ sign and no spaces"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:21
#: lib/memex_web/templates/user_settings/edit.html.heex:119
#, elixir-autogen, elixir-format
msgid "oops, something went wrong! Please check the errors below"
msgstr ""

View File

@ -10,138 +10,145 @@
msgid "" msgid ""
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_confirmation_controller.ex:38 #: lib/memex_web/controllers/user_confirmation_controller.ex:38
#, elixir-autogen, elixir-format
msgid "%{email} confirmed successfully." msgid "%{email} confirmed successfully."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/form_component.ex:62 #: lib/memex_web/live/invite_live/form_component.ex:62
#, elixir-autogen, elixir-format
msgid "%{invite_name} created successfully" msgid "%{invite_name} created successfully"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:53 #: lib/memex_web/live/invite_live/index.ex:53
#, elixir-autogen, elixir-format
msgid "%{invite_name} deleted succesfully" msgid "%{invite_name} deleted succesfully"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:114 #: lib/memex_web/live/invite_live/index.ex:114
#, elixir-autogen, elixir-format
msgid "%{invite_name} disabled succesfully" msgid "%{invite_name} disabled succesfully"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:90 #: lib/memex_web/live/invite_live/index.ex:90
#, elixir-autogen, elixir-format
msgid "%{invite_name} enabled succesfully" msgid "%{invite_name} enabled succesfully"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:68 #: lib/memex_web/live/invite_live/index.ex:68
#, elixir-autogen, elixir-format
msgid "%{invite_name} updated succesfully" msgid "%{invite_name} updated succesfully"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/form_component.ex:42 #: lib/memex_web/live/invite_live/form_component.ex:42
#, elixir-autogen, elixir-format
msgid "%{invite_name} updated successfully" msgid "%{invite_name} updated successfully"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:139 #: lib/memex_web/live/invite_live/index.ex:139
#, elixir-autogen, elixir-format
msgid "%{user_email} deleted succesfully" msgid "%{user_email} deleted succesfully"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_settings_controller.ex:29 #: lib/memex_web/controllers/user_settings_controller.ex:29
#, elixir-autogen, elixir-format
msgid "A link to confirm your email change has been sent to the new address." msgid "A link to confirm your email change has been sent to the new address."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:133
msgid "Are you sure you want to change your language?"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:101
#: lib/memex_web/live/invite_live/index.html.heex:130
msgid "Are you sure you want to delete %{email}? This action is permanent!"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:48
msgid "Are you sure you want to delete the invite for %{invite_name}?"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/templates/user_settings/edit.html.heex:143
msgid "Are you sure you want to delete your account?"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/components/topbar.ex:95
msgid "Are you sure you want to log out?"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.html.heex:73
msgid "Are you sure you want to make %{invite_name} unlimited?"
msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/index.ex:127 #: lib/memex_web/live/invite_live/index.ex:127
#, elixir-autogen, elixir-format
msgid "Copied to clipboard" msgid "Copied to clipboard"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_settings_controller.ex:77 #: lib/memex_web/controllers/user_settings_controller.ex:77
#, elixir-autogen, elixir-format
msgid "Email changed successfully." msgid "Email changed successfully."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_confirmation_controller.ex:23 #: lib/memex_web/controllers/user_confirmation_controller.ex:23
#, elixir-autogen, elixir-format
msgid "If your email is in our system and it has not been confirmed yet, you will receive an email with instructions shortly." msgid "If your email is in our system and it has not been confirmed yet, you will receive an email with instructions shortly."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_reset_password_controller.ex:24 #: lib/memex_web/controllers/user_reset_password_controller.ex:24
#, elixir-autogen, elixir-format
msgid "If your email is in our system, you will receive instructions to reset your password shortly." msgid "If your email is in our system, you will receive instructions to reset your password shortly."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_settings_controller.ex:65 #: lib/memex_web/controllers/user_settings_controller.ex:65
#, elixir-autogen, elixir-format
msgid "Language updated successfully." msgid "Language updated successfully."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_session_controller.ex:23 #: lib/memex_web/controllers/user_session_controller.ex:23
#, elixir-autogen, elixir-format
msgid "Logged out successfully." msgid "Logged out successfully."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_reset_password_controller.ex:46 #: lib/memex_web/controllers/user_reset_password_controller.ex:46
#, elixir-autogen, elixir-format
msgid "Password reset successfully." msgid "Password reset successfully."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_settings_controller.ex:49 #: lib/memex_web/controllers/user_settings_controller.ex:49
#, elixir-autogen, elixir-format
msgid "Password updated successfully." msgid "Password updated successfully."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_registration_controller.ex:74 #: lib/memex_web/controllers/user_registration_controller.ex:74
#, elixir-autogen, elixir-format
msgid "Please check your email to verify your account" msgid "Please check your email to verify your account"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/live/invite_live/form_component.html.heex:30 #: lib/memex_web/live/invite_live/form_component.html.heex:30
#, elixir-autogen, elixir-format
msgid "Saving..." msgid "Saving..."
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/memex_web/controllers/user_settings_controller.ex:95 #: lib/memex_web/controllers/user_settings_controller.ex:95
#, elixir-autogen, elixir-format
msgid "Your account has been deleted" msgid "Your account has been deleted"
msgstr "" msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:133
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/memex_web/live/home_live.html.heex:91 msgid "are you sure you want to change your language?"
msgid "Register to setup %{name}" msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:102
#: lib/memex_web/live/invite_live/index.html.heex:132
#, elixir-autogen, elixir-format
msgid "are you sure you want to delete %{email}? This action is permanent!"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:48
#, elixir-autogen, elixir-format
msgid "are you sure you want to delete the invite for %{invite_name}?"
msgstr ""
#: lib/memex_web/templates/user_settings/edit.html.heex:143
#, elixir-autogen, elixir-format
msgid "are you sure you want to delete your account?"
msgstr ""
#: lib/memex_web/components/topbar.ex:92
#, elixir-autogen, elixir-format
msgid "are you sure you want to log out?"
msgstr ""
#: lib/memex_web/live/invite_live/index.html.heex:74
#, elixir-autogen, elixir-format
msgid "are you sure you want to make %{invite_name} unlimited?"
msgstr ""
#: lib/memex_web/live/context_live/index.html.heex:51
#: lib/memex_web/live/note_live/index.html.heex:29
#: lib/memex_web/live/pipeline_live/index.html.heex:49
#, elixir-autogen, elixir-format
msgid "are you sure?"
msgstr ""
#: lib/memex_web/live/home_live.html.heex:95
#, elixir-autogen, elixir-format
msgid "register to setup %{name}"
msgstr "" msgstr ""

View File

@ -6,9 +6,11 @@ defmodule Memex.Repo.Migrations.CreateNotes do
add :id, :binary_id, primary_key: true add :id, :binary_id, primary_key: true
add :title, :string add :title, :string
add :content, :text add :content, :text
add :tag, {:array, :string} add :tags, {:array, :string}
add :visibility, :string add :visibility, :string
add :user_id, references(:users, on_delete: :delete_all, type: :binary_id)
timestamps() timestamps()
end end
end end

View File

@ -1,71 +1,113 @@
defmodule Memex.NotesTest do defmodule Memex.NotesTest do
use Memex.DataCase use Memex.DataCase
import Memex.NotesFixtures
alias Memex.Notes alias Memex.{Notes, Notes.Note}
@moduletag :notes_test
@invalid_attrs %{content: nil, tag: nil, title: nil, visibility: nil}
describe "notes" do describe "notes" do
alias Memex.Notes.Note setup do
[user: user_fixture()]
import Memex.NotesFixtures
@invalid_attrs %{content: nil, tag: nil, title: nil, visibility: nil}
test "list_notes/0 returns all notes" do
note = note_fixture()
assert Notes.list_notes() == [note]
end end
test "get_note!/1 returns the note with given id" do test "list_notes/1 returns all notes for a user", %{user: user} do
note = note_fixture() note_a = note_fixture(%{title: "a", visibility: :public}, user)
assert Notes.get_note!(note.id) == note note_b = note_fixture(%{title: "b", visibility: :unlisted}, user)
note_c = note_fixture(%{title: "c", visibility: :private}, user)
assert Notes.list_notes(user) == [note_a, note_b, note_c]
end end
test "create_note/1 with valid data creates a note" do test "list_public_notes/0 returns public notes", %{user: user} do
valid_attrs = %{content: "some content", tag: [], title: "some title", visibility: :public} public_note = note_fixture(%{visibility: :public}, user)
note_fixture(%{visibility: :unlisted}, user)
note_fixture(%{visibility: :private}, user)
assert Notes.list_public_notes() == [public_note]
end
assert {:ok, %Note{} = note} = Notes.create_note(valid_attrs) test "get_note!/1 returns the note with given id", %{user: user} do
note = note_fixture(%{visibility: :public}, user)
assert Notes.get_note!(note.id, user) == note
note = note_fixture(%{visibility: :unlisted}, user)
assert Notes.get_note!(note.id, user) == note
note = note_fixture(%{visibility: :private}, user)
assert Notes.get_note!(note.id, user) == note
end
test "get_note!/1 only returns unlisted or public notes for other users", %{user: user} do
another_user = user_fixture()
note = note_fixture(%{visibility: :public}, another_user)
assert Notes.get_note!(note.id, user) == note
note = note_fixture(%{visibility: :unlisted}, another_user)
assert Notes.get_note!(note.id, user) == note
note = note_fixture(%{visibility: :private}, another_user)
assert_raise Ecto.NoResultsError, fn ->
Notes.get_note!(note.id, user)
end
end
test "create_note/1 with valid data creates a note", %{user: user} do
valid_attrs = %{
"content" => "some content",
"tags_string" => "tag1,tag2",
"title" => "some title",
"visibility" => :public
}
assert {:ok, %Note{} = note} = Notes.create_note(valid_attrs, user)
assert note.content == "some content" assert note.content == "some content"
assert note.tag == [] assert note.tags == ["tag1", "tag2"]
assert note.title == "some title" assert note.title == "some title"
assert note.visibility == :public assert note.visibility == :public
end end
test "create_note/1 with invalid data returns error changeset" do test "create_note/1 with invalid data returns error changeset", %{user: user} do
assert {:error, %Ecto.Changeset{}} = Notes.create_note(@invalid_attrs) assert {:error, %Ecto.Changeset{}} = Notes.create_note(@invalid_attrs, user)
end end
test "update_note/2 with valid data updates the note" do test "update_note/2 with valid data updates the note", %{user: user} do
note = note_fixture() note = note_fixture(user)
update_attrs = %{ update_attrs = %{
content: "some updated content", "content" => "some updated content",
tag: [], "tags_string" => "tag1,tag2",
title: "some updated title", "title" => "some updated title",
visibility: :private "visibility" => :private
} }
assert {:ok, %Note{} = note} = Notes.update_note(note, update_attrs) assert {:ok, %Note{} = note} = Notes.update_note(note, update_attrs, user)
assert note.content == "some updated content" assert note.content == "some updated content"
assert note.tag == [] assert note.tags == ["tag1", "tag2"]
assert note.title == "some updated title" assert note.title == "some updated title"
assert note.visibility == :private assert note.visibility == :private
end end
test "update_note/2 with invalid data returns error changeset" do test "update_note/2 with invalid data returns error changeset", %{user: user} do
note = note_fixture() note = note_fixture(user)
assert {:error, %Ecto.Changeset{}} = Notes.update_note(note, @invalid_attrs) assert {:error, %Ecto.Changeset{}} = Notes.update_note(note, @invalid_attrs, user)
assert note == Notes.get_note!(note.id) assert note == Notes.get_note!(note.id, user)
end end
test "delete_note/1 deletes the note" do test "delete_note/1 deletes the note", %{user: user} do
note = note_fixture() note = note_fixture(user)
assert {:ok, %Note{}} = Notes.delete_note(note) assert {:ok, %Note{}} = Notes.delete_note(note, user)
assert_raise Ecto.NoResultsError, fn -> Notes.get_note!(note.id) end assert_raise Ecto.NoResultsError, fn -> Notes.get_note!(note.id, user) end
end end
test "change_note/1 returns a note changeset" do test "delete_note/1 deletes the note for an admin user", %{user: user} do
note = note_fixture() admin_user = admin_fixture()
assert %Ecto.Changeset{} = Notes.change_note(note) note = note_fixture(user)
assert {:ok, %Note{}} = Notes.delete_note(note, admin_user)
assert_raise Ecto.NoResultsError, fn -> Notes.get_note!(note.id, user) end
end
test "change_note/1 returns a note changeset", %{user: user} do
note = note_fixture(user)
assert %Ecto.Changeset{} = Notes.change_note(note, user)
end end
end end
end end

View File

@ -4,14 +4,24 @@ defmodule MemexWeb.ContextLiveTest do
import Phoenix.LiveViewTest import Phoenix.LiveViewTest
import Memex.ContextsFixtures import Memex.ContextsFixtures
@create_attrs %{content: "some content", tag: [], title: "some title", visibility: :public} @create_attrs %{
@update_attrs %{ "content" => "some content",
content: "some updated content", "tags_string" => "tag1",
tag: [], "title" => "some title",
title: "some updated title", "visibility" => :public
visibility: :private }
@update_attrs %{
"content" => "some updated content",
"tags_string" => "tag1,tag2",
"title" => "some updated title",
"visibility" => :private
}
@invalid_attrs %{
"content" => nil,
"tags_string" => "",
"title" => nil,
"visibility" => nil
} }
@invalid_attrs %{content: nil, tag: [], title: nil, visibility: nil}
defp create_context(_) do defp create_context(_) do
context = context_fixture() context = context_fixture()

View File

@ -4,22 +4,31 @@ defmodule MemexWeb.NoteLiveTest do
import Phoenix.LiveViewTest import Phoenix.LiveViewTest
import Memex.NotesFixtures import Memex.NotesFixtures
@create_attrs %{content: "some content", tag: [], title: "some title", visibility: :public} @create_attrs %{
@update_attrs %{ "content" => "some content",
content: "some updated content", "tags_string" => "tag1",
tag: [], "title" => "some title",
title: "some updated title", "visibility" => :public
visibility: :private }
@update_attrs %{
"content" => "some updated content",
"tags_string" => "tag1,tag2",
"title" => "some updated title",
"visibility" => :private
}
@invalid_attrs %{
"content" => nil,
"tags_string" => "",
"title" => nil,
"visibility" => nil
} }
@invalid_attrs %{content: nil, tag: [], title: nil, visibility: nil}
defp create_note(_) do defp create_note(%{user: user}) do
note = note_fixture() [note: note_fixture(user)]
%{note: note}
end end
describe "Index" do describe "Index" do
setup [:create_note] setup [:register_and_log_in_user, :create_note]
test "lists all notes", %{conn: conn, note: note} do test "lists all notes", %{conn: conn, note: note} do
{:ok, _index_live, html} = live(conn, Routes.note_index_path(conn, :index)) {:ok, _index_live, html} = live(conn, Routes.note_index_path(conn, :index))
@ -53,7 +62,7 @@ defmodule MemexWeb.NoteLiveTest do
test "updates note in listing", %{conn: conn, note: note} do test "updates note in listing", %{conn: conn, note: note} do
{:ok, index_live, _html} = live(conn, Routes.note_index_path(conn, :index)) {:ok, index_live, _html} = live(conn, Routes.note_index_path(conn, :index))
assert index_live |> element("#note-#{note.id} a", "Edit") |> render_click() =~ assert index_live |> element("[data-qa=\"note-edit-#{note.id}\"]") |> render_click() =~
"edit" "edit"
assert_patch(index_live, Routes.note_index_path(conn, :edit, note)) assert_patch(index_live, Routes.note_index_path(conn, :edit, note))
@ -75,7 +84,7 @@ defmodule MemexWeb.NoteLiveTest do
test "deletes note in listing", %{conn: conn, note: note} do test "deletes note in listing", %{conn: conn, note: note} do
{:ok, index_live, _html} = live(conn, Routes.note_index_path(conn, :index)) {:ok, index_live, _html} = live(conn, Routes.note_index_path(conn, :index))
assert index_live |> element("#note-#{note.id} a", "Delete") |> render_click() assert index_live |> element("[data-qa=\"delete-note-#{note.id}\"]") |> render_click()
refute has_element?(index_live, "#note-#{note.id}") refute has_element?(index_live, "#note-#{note.id}")
end end
end end

View File

@ -3,20 +3,23 @@ defmodule Memex.NotesFixtures do
This module defines test helpers for creating This module defines test helpers for creating
entities via the `Memex.Notes` context. entities via the `Memex.Notes` context.
""" """
alias Memex.{Accounts.User, Notes, Notes.Note}
@doc """ @doc """
Generate a note. Generate a note.
""" """
def note_fixture(attrs \\ %{}) do @spec note_fixture(User.t()) :: Note.t()
@spec note_fixture(attrs :: map(), User.t()) :: Note.t()
def note_fixture(attrs \\ %{}, user) do
{:ok, note} = {:ok, note} =
attrs attrs
|> Enum.into(%{ |> Enum.into(%{
content: "some content", content: "some content",
tag: [], tag: [],
title: "some title", title: "some title",
visibility: :public visibility: :private
}) })
|> Memex.Notes.create_note() |> Notes.create_note(user)
note note
end end