Compare commits
1 Commits
066587f839
...
947dd5ff55
Author | SHA1 | Date | |
---|---|---|---|
947dd5ff55 |
@ -1,6 +1,5 @@
|
|||||||
# v0.1.10
|
# v0.1.10
|
||||||
- Improve accessibility
|
- Improve accessibility
|
||||||
- Code quality improvements
|
|
||||||
|
|
||||||
# v0.1.9
|
# v0.1.9
|
||||||
- Improve server log
|
- Improve server log
|
||||||
|
@ -27,7 +27,7 @@ defmodule Memex.Contexts.Context do
|
|||||||
field :tags_string, :string, virtual: true
|
field :tags_string, :string, virtual: true
|
||||||
field :visibility, Ecto.Enum, values: [:public, :private, :unlisted]
|
field :visibility, Ecto.Enum, values: [:public, :private, :unlisted]
|
||||||
|
|
||||||
field :user_id, :binary_id
|
belongs_to :user, User
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
@ -38,6 +38,7 @@ defmodule Memex.Contexts.Context do
|
|||||||
tags: [String.t()] | nil,
|
tags: [String.t()] | nil,
|
||||||
tags_string: String.t() | nil,
|
tags_string: String.t() | nil,
|
||||||
visibility: :public | :private | :unlisted,
|
visibility: :public | :private | :unlisted,
|
||||||
|
user: User.t() | Ecto.Association.NotLoaded.t(),
|
||||||
user_id: User.id(),
|
user_id: User.id(),
|
||||||
inserted_at: NaiveDateTime.t(),
|
inserted_at: NaiveDateTime.t(),
|
||||||
updated_at: NaiveDateTime.t()
|
updated_at: NaiveDateTime.t()
|
||||||
|
@ -26,7 +26,7 @@ defmodule Memex.Notes.Note do
|
|||||||
field :tags_string, :string, virtual: true
|
field :tags_string, :string, virtual: true
|
||||||
field :visibility, Ecto.Enum, values: [:public, :private, :unlisted]
|
field :visibility, Ecto.Enum, values: [:public, :private, :unlisted]
|
||||||
|
|
||||||
field :user_id, :binary_id
|
belongs_to :user, User
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
@ -37,6 +37,7 @@ defmodule Memex.Notes.Note do
|
|||||||
tags: [String.t()] | nil,
|
tags: [String.t()] | nil,
|
||||||
tags_string: String.t() | nil,
|
tags_string: String.t() | nil,
|
||||||
visibility: :public | :private | :unlisted,
|
visibility: :public | :private | :unlisted,
|
||||||
|
user: User.t() | Ecto.Association.NotLoaded.t(),
|
||||||
user_id: User.id(),
|
user_id: User.id(),
|
||||||
inserted_at: NaiveDateTime.t(),
|
inserted_at: NaiveDateTime.t(),
|
||||||
updated_at: NaiveDateTime.t()
|
updated_at: NaiveDateTime.t()
|
||||||
|
@ -27,7 +27,7 @@ defmodule Memex.Pipelines.Pipeline do
|
|||||||
field :tags_string, :string, virtual: true
|
field :tags_string, :string, virtual: true
|
||||||
field :visibility, Ecto.Enum, values: [:public, :private, :unlisted]
|
field :visibility, Ecto.Enum, values: [:public, :private, :unlisted]
|
||||||
|
|
||||||
field :user_id, :binary_id
|
belongs_to :user, User
|
||||||
|
|
||||||
has_many :steps, Step, preload_order: [asc: :position]
|
has_many :steps, Step, preload_order: [asc: :position]
|
||||||
|
|
||||||
@ -40,6 +40,7 @@ defmodule Memex.Pipelines.Pipeline do
|
|||||||
tags: [String.t()] | nil,
|
tags: [String.t()] | nil,
|
||||||
tags_string: String.t() | nil,
|
tags_string: String.t() | nil,
|
||||||
visibility: :public | :private | :unlisted,
|
visibility: :public | :private | :unlisted,
|
||||||
|
user: User.t() | Ecto.Association.NotLoaded.t(),
|
||||||
user_id: User.id(),
|
user_id: User.id(),
|
||||||
inserted_at: NaiveDateTime.t(),
|
inserted_at: NaiveDateTime.t(),
|
||||||
updated_at: NaiveDateTime.t()
|
updated_at: NaiveDateTime.t()
|
||||||
|
@ -23,7 +23,7 @@ defmodule Memex.Pipelines.Steps.Step do
|
|||||||
field :position, :integer
|
field :position, :integer
|
||||||
|
|
||||||
belongs_to :pipeline, Pipeline
|
belongs_to :pipeline, Pipeline
|
||||||
field :user_id, :binary_id
|
belongs_to :user, User
|
||||||
|
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
@ -34,6 +34,7 @@ defmodule Memex.Pipelines.Steps.Step do
|
|||||||
position: non_neg_integer(),
|
position: non_neg_integer(),
|
||||||
pipeline: Pipeline.t() | Ecto.Association.NotLoaded.t(),
|
pipeline: Pipeline.t() | Ecto.Association.NotLoaded.t(),
|
||||||
pipeline_id: Pipeline.id(),
|
pipeline_id: Pipeline.id(),
|
||||||
|
user: User.t() | Ecto.Association.NotLoaded.t(),
|
||||||
user_id: User.id(),
|
user_id: User.id(),
|
||||||
inserted_at: NaiveDateTime.t(),
|
inserted_at: NaiveDateTime.t(),
|
||||||
updated_at: NaiveDateTime.t()
|
updated_at: NaiveDateTime.t()
|
||||||
|
@ -18,14 +18,15 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
id="modal-content"
|
id="modal-content"
|
||||||
class="fade-in-scale max-w-3xl max-h-3xl relative w-full
|
class="fade-in-scale w-full max-w-3xl relative
|
||||||
pointer-events-auto overflow-hidden
|
pointer-events-auto overflow-hidden
|
||||||
px-8 py-4 sm:py-8 flex flex-col justify-start items-stretch
|
px-8 py-4 sm:py-8
|
||||||
bg-primary-800 text-primary-400 border-primary-900 border-2 rounded-lg"
|
flex flex-col justify-start items-center
|
||||||
|
bg-white border-2 rounded-lg"
|
||||||
>
|
>
|
||||||
<.link
|
<.link
|
||||||
patch={@return_to}
|
|
||||||
id="close"
|
id="close"
|
||||||
|
href={@return_to}
|
||||||
class="absolute top-8 right-10
|
class="absolute top-8 right-10
|
||||||
text-gray-500 hover:text-gray-800
|
text-gray-500 hover:text-gray-800
|
||||||
transition-all duration-500 ease-in-out"
|
transition-all duration-500 ease-in-out"
|
||||||
@ -34,7 +35,7 @@
|
|||||||
<i class="fa-fw fa-lg fas fa-times"></i>
|
<i class="fa-fw fa-lg fas fa-times"></i>
|
||||||
</.link>
|
</.link>
|
||||||
|
|
||||||
<div class="overflow-x-hidden overflow-y-auto w-full p-8 flex flex-col space-y-4 justify-start items-stretch">
|
<div class="overflow-x-hidden overflow-y-auto w-full p-8 flex flex-col space-y-4 justify-start items-center">
|
||||||
<%= render_slot(@inner_block) %>
|
<%= render_slot(@inner_block) %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
135
lib/memex_web/live/live_helpers.ex
Normal file
135
lib/memex_web/live/live_helpers.ex
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
defmodule MemexWeb.LiveHelpers do
|
||||||
|
@moduledoc """
|
||||||
|
Contains common helper functions for liveviews
|
||||||
|
"""
|
||||||
|
|
||||||
|
use Phoenix.Component
|
||||||
|
alias Phoenix.LiveView.JS
|
||||||
|
|
||||||
|
attr :return_to, :string, required: true
|
||||||
|
slot(:inner_block)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Renders a live component inside a modal.
|
||||||
|
|
||||||
|
The rendered modal receives a `:return_to` option to properly update
|
||||||
|
the URL when the modal is closed.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<.modal return_to={Routes.<%= schema.singular %>_index_path(Endpoint, :index)}>
|
||||||
|
<.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)}
|
||||||
|
<%= schema.singular %>: @<%= schema.singular %>
|
||||||
|
/>
|
||||||
|
</.modal>
|
||||||
|
"""
|
||||||
|
def modal(assigns) do
|
||||||
|
~H"""
|
||||||
|
<.link
|
||||||
|
id="modal-bg"
|
||||||
|
patch={@return_to}
|
||||||
|
class="fade-in fixed z-10 left-0 top-0
|
||||||
|
w-full h-full overflow-hidden
|
||||||
|
p-8 flex flex-col justify-center items-center cursor-auto"
|
||||||
|
style="background-color: rgba(0,0,0,0.4);"
|
||||||
|
phx-remove={hide_modal()}
|
||||||
|
>
|
||||||
|
<span class="hidden"></span>
|
||||||
|
</.link>
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="modal"
|
||||||
|
class="fixed z-10 left-0 top-0 pointer-events-none
|
||||||
|
w-full h-full overflow-hidden
|
||||||
|
p-4 sm:p-8 flex flex-col justify-center items-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="modal-content"
|
||||||
|
class="fade-in-scale max-w-3xl max-h-3xl relative w-full
|
||||||
|
pointer-events-auto overflow-hidden
|
||||||
|
px-8 py-4 sm:py-8 flex flex-col justify-start items-stretch
|
||||||
|
bg-primary-800 text-primary-400 border-primary-900 border-2 rounded-lg"
|
||||||
|
>
|
||||||
|
<.link
|
||||||
|
patch={@return_to}
|
||||||
|
id="close"
|
||||||
|
class="absolute top-8 right-10
|
||||||
|
text-gray-500 hover:text-gray-800
|
||||||
|
transition-all duration-500 ease-in-out"
|
||||||
|
phx-remove={hide_modal()}
|
||||||
|
>
|
||||||
|
<i class="fa-fw fa-lg fas fa-times"></i>
|
||||||
|
</.link>
|
||||||
|
|
||||||
|
<div class="overflow-x-hidden overflow-y-auto w-full p-8 flex flex-col space-y-4 justify-start items-stretch">
|
||||||
|
<%= render_slot(@inner_block) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp hide_modal(js \\ %JS{}) do
|
||||||
|
js
|
||||||
|
|> JS.hide(to: "#modal", transition: "fade-out")
|
||||||
|
|> JS.hide(to: "#modal-bg", transition: "fade-out")
|
||||||
|
|> JS.hide(to: "#modal-content", transition: "fade-out-scale")
|
||||||
|
end
|
||||||
|
|
||||||
|
attr :action, :string, required: true
|
||||||
|
attr :value, :boolean, required: true
|
||||||
|
attr :id, :string
|
||||||
|
slot(:inner_block)
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
A toggle button element that can be directed to a liveview or a
|
||||||
|
live_component's `handle_event/3`.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
<.toggle_button action="my_liveview_action" value={@some_value}>
|
||||||
|
<span>Toggle me!</span>
|
||||||
|
</.toggle_button>
|
||||||
|
<.toggle_button action="my_live_component_action" target={@myself} value={@some_value}>
|
||||||
|
<span>Whatever you want</span>
|
||||||
|
</.toggle_button>
|
||||||
|
"""
|
||||||
|
def toggle_button(assigns) do
|
||||||
|
assigns = assigns |> assign_new(:id, fn -> assigns.action end)
|
||||||
|
|
||||||
|
~H"""
|
||||||
|
<label for={@id} class="inline-flex relative items-center cursor-pointer">
|
||||||
|
<input
|
||||||
|
id={@id}
|
||||||
|
type="checkbox"
|
||||||
|
value={@value}
|
||||||
|
checked={@value}
|
||||||
|
class="sr-only peer"
|
||||||
|
aria-labelledby={"#{@id}-label"}
|
||||||
|
{
|
||||||
|
if assigns |> Map.has_key?(:target),
|
||||||
|
do: %{"phx-click": @action, "phx-value-value": @value, "phx-target": @target},
|
||||||
|
else: %{"phx-click": @action, "phx-value-value": @value}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<div class="w-11 h-6 bg-gray-300 rounded-full peer
|
||||||
|
peer-focus:ring-4 peer-focus:ring-teal-300 dark:peer-focus:ring-teal-800
|
||||||
|
peer-checked:bg-gray-600
|
||||||
|
peer-checked:after:translate-x-full peer-checked:after:border-white
|
||||||
|
after:content-[''] after:absolute after:top-1 after:left-[2px] after:bg-white after:border-gray-300
|
||||||
|
after:border after:rounded-full after:h-5 after:w-5
|
||||||
|
after:transition-all after:duration-250 after:ease-in-out
|
||||||
|
transition-colors duration-250 ease-in-out">
|
||||||
|
</div>
|
||||||
|
<span id={"#{@id}-label"} class="ml-3 text-sm font-medium text-gray-900 dark:text-gray-300">
|
||||||
|
<%= render_slot(@inner_block) %>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
end
|
@ -73,12 +73,12 @@ msgstr ""
|
|||||||
msgid "must have the @ sign and no spaces"
|
msgid "must have the @ sign and no spaces"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/memex/contexts/context.ex:57
|
#: lib/memex/contexts/context.ex:58
|
||||||
#: lib/memex/contexts/context.ex:70
|
#: lib/memex/contexts/context.ex:71
|
||||||
#: lib/memex/notes/note.ex:56
|
#: lib/memex/notes/note.ex:57
|
||||||
#: lib/memex/notes/note.ex:69
|
#: lib/memex/notes/note.ex:70
|
||||||
#: lib/memex/pipelines/pipeline.ex:59
|
#: lib/memex/pipelines/pipeline.ex:60
|
||||||
#: lib/memex/pipelines/pipeline.ex:72
|
#: lib/memex/pipelines/pipeline.ex:73
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "invalid format: only numbers, letters and hyphen are accepted"
|
msgid "invalid format: only numbers, letters and hyphen are accepted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -103,9 +103,9 @@ msgstr ""
|
|||||||
msgid "unauthorized"
|
msgid "unauthorized"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/memex/contexts/context.ex:83
|
#: lib/memex/contexts/context.ex:84
|
||||||
#: lib/memex/notes/note.ex:82
|
#: lib/memex/notes/note.ex:83
|
||||||
#: lib/memex/pipelines/pipeline.ex:85
|
#: lib/memex/pipelines/pipeline.ex:86
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited"
|
msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -74,12 +74,12 @@ msgstr ""
|
|||||||
msgid "must have the @ sign and no spaces"
|
msgid "must have the @ sign and no spaces"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/memex/contexts/context.ex:57
|
#: lib/memex/contexts/context.ex:58
|
||||||
#: lib/memex/contexts/context.ex:70
|
#: lib/memex/contexts/context.ex:71
|
||||||
#: lib/memex/notes/note.ex:56
|
#: lib/memex/notes/note.ex:57
|
||||||
#: lib/memex/notes/note.ex:69
|
#: lib/memex/notes/note.ex:70
|
||||||
#: lib/memex/pipelines/pipeline.ex:59
|
#: lib/memex/pipelines/pipeline.ex:60
|
||||||
#: lib/memex/pipelines/pipeline.ex:72
|
#: lib/memex/pipelines/pipeline.ex:73
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "invalid format: only numbers, letters and hyphen are accepted"
|
msgid "invalid format: only numbers, letters and hyphen are accepted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -104,9 +104,9 @@ msgstr ""
|
|||||||
msgid "unauthorized"
|
msgid "unauthorized"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/memex/contexts/context.ex:83
|
#: lib/memex/contexts/context.ex:84
|
||||||
#: lib/memex/notes/note.ex:82
|
#: lib/memex/notes/note.ex:83
|
||||||
#: lib/memex/pipelines/pipeline.ex:85
|
#: lib/memex/pipelines/pipeline.ex:86
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited"
|
msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -73,12 +73,12 @@ msgstr ""
|
|||||||
msgid "must have the @ sign and no spaces"
|
msgid "must have the @ sign and no spaces"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/memex/contexts/context.ex:57
|
#: lib/memex/contexts/context.ex:58
|
||||||
#: lib/memex/contexts/context.ex:70
|
#: lib/memex/contexts/context.ex:71
|
||||||
#: lib/memex/notes/note.ex:56
|
#: lib/memex/notes/note.ex:57
|
||||||
#: lib/memex/notes/note.ex:69
|
#: lib/memex/notes/note.ex:70
|
||||||
#: lib/memex/pipelines/pipeline.ex:59
|
#: lib/memex/pipelines/pipeline.ex:60
|
||||||
#: lib/memex/pipelines/pipeline.ex:72
|
#: lib/memex/pipelines/pipeline.ex:73
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "invalid format: only numbers, letters and hyphen are accepted"
|
msgid "invalid format: only numbers, letters and hyphen are accepted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -103,9 +103,9 @@ msgstr ""
|
|||||||
msgid "unauthorized"
|
msgid "unauthorized"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/memex/contexts/context.ex:83
|
#: lib/memex/contexts/context.ex:84
|
||||||
#: lib/memex/notes/note.ex:82
|
#: lib/memex/notes/note.ex:83
|
||||||
#: lib/memex/pipelines/pipeline.ex:85
|
#: lib/memex/pipelines/pipeline.ex:86
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited"
|
msgid "invalid format: only numbers, letters and hyphen are accepted. tags must be comma-delimited"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
Loading…
Reference in New Issue
Block a user