Compare commits
17 commits
renovate/p
...
devel
Author | SHA1 | Date | |
---|---|---|---|
8bf1887d85 | |||
bf15790153 | |||
01a3c4f0da | |||
0fac4df834 | |||
fd580b112e | |||
cdf15f5bf8 | |||
4135d72214 | |||
d2db822685 | |||
bb086946a8 | |||
cf3fa19044 | |||
94976b3414 | |||
644cabd24f | |||
2bb625af23 | |||
1b68c68644 | |||
c05259118f | |||
3127937528 | |||
8079245269 |
7 changed files with 180 additions and 21 deletions
|
@ -40,6 +40,19 @@
|
||||||
:root[data-mode=dark] .prose {
|
:root[data-mode=dark] .prose {
|
||||||
@apply prose-invert;
|
@apply prose-invert;
|
||||||
}
|
}
|
||||||
|
/* https://stackoverflow.com/questions/5379752/css-style-external-links */
|
||||||
|
a[href]:not(:where(
|
||||||
|
/* exclude hash only links */
|
||||||
|
[href^="#"],
|
||||||
|
/* exclude relative but not double slash only links */
|
||||||
|
[href^="/"]:not([href^="//"]),
|
||||||
|
/* domains to exclude */
|
||||||
|
[href*="//inhji.de"],
|
||||||
|
/* subdomains to exclude */
|
||||||
|
[href*="//cloud.inhji.de"],
|
||||||
|
)):after {
|
||||||
|
content: '↬';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -72,7 +72,7 @@ defmodule Chiya.Notes.Note do
|
||||||
end
|
end
|
||||||
|
|
||||||
def note_path_admin(note) do
|
def note_path_admin(note) do
|
||||||
~p"/admin/notes/#{note.slug}"
|
~p"/admin/notes/#{note.id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def note_url(note) do
|
def note_url(note) do
|
||||||
|
|
|
@ -586,7 +586,9 @@ defmodule ChiyaWeb.CoreComponents do
|
||||||
<dt class="w-1/4 flex-none text-[0.8125rem] leading-6 text-gray-500 dark:text-gray-300">
|
<dt class="w-1/4 flex-none text-[0.8125rem] leading-6 text-gray-500 dark:text-gray-300">
|
||||||
<%= item.title %>
|
<%= item.title %>
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="text-sm leading-6 text-gray-700 dark:text-gray-400"><%= render_slot(item) %></dd>
|
<dd class="text-sm leading-6 text-gray-700 dark:text-gray-400 overflow-auto">
|
||||||
|
<%= render_slot(item) %>
|
||||||
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -43,14 +43,14 @@
|
||||||
|
|
||||||
<aside class="prose max-w-none">
|
<aside class="prose max-w-none">
|
||||||
<%= if has_outline?(@note) do %>
|
<%= if has_outline?(@note) do %>
|
||||||
<h3>Outline</h3>
|
<h3><.icon name="hero-rectangle-stack" /> Outline</h3>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<%= raw(render_outline(@note)) %>
|
<%= raw(render_outline(@note)) %>
|
||||||
</section>
|
</section>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<h3>Properties</h3>
|
<h3><.icon name="hero-rectangle-group" /> Properties</h3>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= if not Enum.empty?(@note.links_to) do %>
|
<%= if not Enum.empty?(@note.links_to) do %>
|
||||||
<h3>Notes linking here</h3>
|
<h3><.icon name="hero-arrow-down-on-square" /> Notes linking here</h3>
|
||||||
<section>
|
<section>
|
||||||
<ul>
|
<ul>
|
||||||
<%= for link <- @note.links_to do %>
|
<%= for link <- @note.links_to do %>
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
</section>
|
</section>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<h3>Admin</h3>
|
<h3><.icon name="hero-wrench-screwdriver" /> Admin</h3>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
132
lib/chiya_web/live/note_edit_live.ex
Normal file
132
lib/chiya_web/live/note_edit_live.ex
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
defmodule ChiyaWeb.NoteEditLive do
|
||||||
|
use ChiyaWeb, :live_view
|
||||||
|
|
||||||
|
def render(assigns) do
|
||||||
|
~H"""
|
||||||
|
<.header>
|
||||||
|
<:actions>
|
||||||
|
<.link href={~p"/admin/notes/#{@note.id}"}>
|
||||||
|
<.button><.icon name="hero-arrow-left" /> Back to Note</.button>
|
||||||
|
</.link>
|
||||||
|
</:actions>
|
||||||
|
</.header>
|
||||||
|
|
||||||
|
<.simple_form for={@note_form} id="note_form" phx-change="validate_note" phx-submit="update_note">
|
||||||
|
<header>
|
||||||
|
<.input
|
||||||
|
field={@note_form[:name]}
|
||||||
|
type="text"
|
||||||
|
class="border-none dark:border-none text-2xl dark:text-2xl"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<.input field={@note_form[:slug]} type="text" class="bg-gray-200 dark:bg-gray-900 font-mono" />
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section class="grid grid-cols-5 gap-6">
|
||||||
|
<section class="col-span-5 md:col-span-3">
|
||||||
|
<.input
|
||||||
|
field={@note_form[:content]}
|
||||||
|
type="textarea"
|
||||||
|
label="Content"
|
||||||
|
rows="20"
|
||||||
|
class="font-mono"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="col-span-5 md:col-span-2 flex flex-col gap-6">
|
||||||
|
<.input field={@note_form[:published_at]} type="datetime-local" label="Published at" />
|
||||||
|
<.input
|
||||||
|
field={@note_form[:kind]}
|
||||||
|
type="select"
|
||||||
|
label="Kind"
|
||||||
|
prompt="Choose a value"
|
||||||
|
options={Ecto.Enum.values(Chiya.Notes.Note, :kind)}
|
||||||
|
/>
|
||||||
|
<.input field={@note_form[:url]} type="text" label="Url" />
|
||||||
|
<.input
|
||||||
|
field={@note_form[:tags_string]}
|
||||||
|
type="text"
|
||||||
|
label="Tags"
|
||||||
|
value={tags_to_string(@note.tags)}
|
||||||
|
/>
|
||||||
|
<.input
|
||||||
|
field={@note_form[:channels]}
|
||||||
|
type="select"
|
||||||
|
label="Channel"
|
||||||
|
multiple={true}
|
||||||
|
options={@channels}
|
||||||
|
value={@selected_channels}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<:actions>
|
||||||
|
<.button>Save Note</.button>
|
||||||
|
</:actions>
|
||||||
|
</.simple_form>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
def mount(%{"id" => id}, _session, socket) do
|
||||||
|
note = Chiya.Notes.get_note_preloaded!(id)
|
||||||
|
changeset = Chiya.Notes.change_note(note)
|
||||||
|
selected_channels = Enum.map(note.channels, fn c -> c.id end)
|
||||||
|
|
||||||
|
{:ok,
|
||||||
|
socket
|
||||||
|
|> assign(%{
|
||||||
|
note_form: to_form(changeset),
|
||||||
|
note: note,
|
||||||
|
action: ~p"/admin/notes/#{note}",
|
||||||
|
channels: to_channel_options(),
|
||||||
|
selected_channels: selected_channels
|
||||||
|
})}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("validate_note", params, socket) do
|
||||||
|
%{"note" => note_params} = params
|
||||||
|
|
||||||
|
note_form =
|
||||||
|
socket.assigns.note
|
||||||
|
|> Chiya.Notes.change_note(note_params)
|
||||||
|
|> Map.put(:action, :validate)
|
||||||
|
|> to_form()
|
||||||
|
|
||||||
|
{:noreply, socket |> assign(:note_form, note_form)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("update_note", params, socket) do
|
||||||
|
%{"note" => note_params} = params
|
||||||
|
note_params = from_channel_ids(note_params)
|
||||||
|
note = socket.assigns.note
|
||||||
|
|
||||||
|
case Chiya.Notes.update_note(note, note_params) do
|
||||||
|
{:ok, note} ->
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> put_flash(:info, "Note updated successfully.")
|
||||||
|
|> redirect(to: ~p"/admin/notes/#{note}")}
|
||||||
|
|
||||||
|
{:error, %Ecto.Changeset{} = changeset} ->
|
||||||
|
{:noreply, assign(socket, :note_form, to_form(Map.put(changeset, :action, :update)))}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def tags_to_string(tags), do: Enum.map_join(tags, ", ", fn t -> t.name end)
|
||||||
|
|
||||||
|
defp from_channel_ids(note_params) do
|
||||||
|
selected_ids = Enum.map(note_params["channels"] || [], &String.to_integer/1)
|
||||||
|
|
||||||
|
selected_channels =
|
||||||
|
Chiya.Channels.list_channels()
|
||||||
|
|> Enum.filter(fn c -> Enum.member?(selected_ids, c.id) end)
|
||||||
|
|
||||||
|
Map.put(note_params, "channels", selected_channels)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp to_channel_options(items \\ nil),
|
||||||
|
do:
|
||||||
|
Enum.map(items || Chiya.Channels.list_channels(), fn c ->
|
||||||
|
{Chiya.Channels.Channel.icon(c) <> " " <> c.name, c.id}
|
||||||
|
end)
|
||||||
|
end
|
|
@ -37,20 +37,31 @@ defmodule ChiyaWeb.NoteShowLive do
|
||||||
</:actions>
|
</:actions>
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
|
<section class="mt-4">
|
||||||
|
<div class="select-all font-mono bg-white p-1 rounded">[[<%= @note.slug %>]]</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="grid grid-cols-2">
|
||||||
|
<section class="col-span-1">
|
||||||
<.list>
|
<.list>
|
||||||
<:item title="Published at">
|
<:item title="Published at">
|
||||||
<%= pretty_date(@note.published_at) %> <span>(<%= from_now(@note.published_at) %>)</span>
|
<%= pretty_date(@note.published_at) %> <span>(<%= from_now(@note.published_at) %>)</span>
|
||||||
</:item>
|
</:item>
|
||||||
<:item title="Channels"><%= note_channels(@note.channels) %></:item>
|
<:item title="Channels"><%= note_channels(@note.channels) %></:item>
|
||||||
<:item title="Kind"><%= @note.kind %></:item>
|
<:item title="Kind"><%= @note.kind %></:item>
|
||||||
<:item title="Url"><%= @note.url %></:item>
|
<:item title="Url"><a href={@note.url} target="_blank"><%= @note.url %></a></:item>
|
||||||
<:item title="Tags"><%= note_tags(@note.tags) %></:item>
|
<:item title="Tags"><%= note_tags(@note.tags) %></:item>
|
||||||
<:item title="Links outgoing"><%= note_links(@note.links_from) %></:item>
|
<:item title="Links outgoing"><%= note_links(@note.links_from) %></:item>
|
||||||
<:item title="Links incoming"><%= note_links(@note.links_to) %></:item>
|
<:item title="Links incoming"><%= note_links(@note.links_to) %></:item>
|
||||||
<:item title="Embed">
|
|
||||||
<pre class="p-1 bg-gray-100 text-black rounded select-all">[[<%= @note.slug %>]]</pre>
|
|
||||||
</:item>
|
|
||||||
</.list>
|
</.list>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="col-span-1 p-6">
|
||||||
|
<section class="prose">
|
||||||
|
<%= raw(Markdown.render(@note.content)) %>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
<.line />
|
<.line />
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ defmodule ChiyaWeb.Router do
|
||||||
live "/", AdminHomeLive, :index
|
live "/", AdminHomeLive, :index
|
||||||
|
|
||||||
resources "/channels", ChannelController
|
resources "/channels", ChannelController
|
||||||
resources "/notes", NoteController, except: [:show, :index]
|
resources "/notes", NoteController, except: [:show, :index, :edit]
|
||||||
resources "/settings", SettingController, singleton: true
|
resources "/settings", SettingController, singleton: true
|
||||||
resources "/identities", IdentityController
|
resources "/identities", IdentityController
|
||||||
resources "/comments", CommentController, only: [:index, :show]
|
resources "/comments", CommentController, only: [:index, :show]
|
||||||
|
@ -85,6 +85,7 @@ defmodule ChiyaWeb.Router do
|
||||||
|
|
||||||
live "/notes", NoteListLive, :index
|
live "/notes", NoteListLive, :index
|
||||||
live "/notes/:id", NoteShowLive, :show
|
live "/notes/:id", NoteShowLive, :show
|
||||||
|
live "/notes/:id/edit", NoteEditLive, :edit
|
||||||
|
|
||||||
get "/notes/:id/raw", NoteController, :raw
|
get "/notes/:id/raw", NoteController, :raw
|
||||||
get "/notes/:id/publish", NoteController, :publish
|
get "/notes/:id/publish", NoteController, :publish
|
||||||
|
|
Loading…
Reference in a new issue