Merge pull request 'devel' (#322) from devel into main
Reviewed-on: #322
This commit is contained in:
commit
4543c3b289
13 changed files with 358 additions and 84 deletions
|
@ -2,9 +2,9 @@
|
||||||
@import "tailwindcss/components";
|
@import "tailwindcss/components";
|
||||||
@import "tailwindcss/utilities";
|
@import "tailwindcss/utilities";
|
||||||
|
|
||||||
|
@import "./hljs.css";
|
||||||
@import "./lightbox.css";
|
@import "./lightbox.css";
|
||||||
@import "./tablesort.css";
|
@import "./tablesort.css";
|
||||||
@import "./tokyo-night-dark.css";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The base layer is for things like reset rules or default styles applied to plain HTML elements.
|
The base layer is for things like reset rules or default styles applied to plain HTML elements.
|
||||||
|
@ -33,6 +33,10 @@
|
||||||
margin-block-start: var(--flow-space, 1em);
|
margin-block-start: var(--flow-space, 1em);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:root .prose {
|
||||||
|
@apply prose-inhji;
|
||||||
|
}
|
||||||
|
|
||||||
:root[data-mode=dark] .prose {
|
:root[data-mode=dark] .prose {
|
||||||
@apply prose-invert;
|
@apply prose-invert;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +189,29 @@
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* === CARD LIST (ADMIN) === */
|
||||||
|
|
||||||
|
.card-list {
|
||||||
|
@apply flex flex-col gap-3 mt-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === CARD (ADMIN) === */
|
||||||
|
.card {
|
||||||
|
@apply bg-neutral-100 dark:bg-neutral-800 text-neutral-900 dark:text-neutral-100 p-3 rounded;
|
||||||
|
|
||||||
|
& header {
|
||||||
|
& h2 {
|
||||||
|
@apply text-xl leading-normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& footer {
|
||||||
|
@apply flex gap-3 text-sm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
201
assets/css/hljs.css
Normal file
201
assets/css/hljs.css
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
:root {
|
||||||
|
/*!
|
||||||
|
Theme: a11y-light
|
||||||
|
Author: @ericwbailey
|
||||||
|
Maintainer: @ericwbailey
|
||||||
|
|
||||||
|
Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css
|
||||||
|
*/
|
||||||
|
|
||||||
|
& .hljs {
|
||||||
|
background: #fefefe;
|
||||||
|
color: #545454;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment */
|
||||||
|
& .hljs-comment,
|
||||||
|
& .hljs-quote {
|
||||||
|
color: #696969;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Red */
|
||||||
|
& .hljs-variable,
|
||||||
|
& .hljs-template-variable,
|
||||||
|
& .hljs-tag,
|
||||||
|
& .hljs-name,
|
||||||
|
& .hljs-selector-id,
|
||||||
|
& .hljs-selector-class,
|
||||||
|
& .hljs-regexp,
|
||||||
|
& .hljs-deletion {
|
||||||
|
color: #d91e18;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Orange */
|
||||||
|
& .hljs-number,
|
||||||
|
& .hljs-built_in,
|
||||||
|
& .hljs-literal,
|
||||||
|
& .hljs-type,
|
||||||
|
& .hljs-params,
|
||||||
|
& .hljs-meta,
|
||||||
|
& .hljs-link {
|
||||||
|
color: #aa5d00;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Yellow */
|
||||||
|
& .hljs-attribute {
|
||||||
|
color: #aa5d00;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Green */
|
||||||
|
& .hljs-string,
|
||||||
|
& .hljs-symbol,
|
||||||
|
& .hljs-bullet,
|
||||||
|
& .hljs-addition {
|
||||||
|
color: #008000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blue */
|
||||||
|
& .hljs-title,
|
||||||
|
& .hljs-section {
|
||||||
|
color: #007faa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Purple */
|
||||||
|
& .hljs-keyword,
|
||||||
|
& .hljs-selector-tag {
|
||||||
|
color: #7928a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .hljs-emphasis {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .hljs-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (-ms-high-contrast: active) {
|
||||||
|
& .hljs-addition,
|
||||||
|
& .hljs-attribute,
|
||||||
|
& .hljs-built_in,
|
||||||
|
& .hljs-bullet,
|
||||||
|
& .hljs-comment,
|
||||||
|
& .hljs-link,
|
||||||
|
& .hljs-literal,
|
||||||
|
& .hljs-meta,
|
||||||
|
& .hljs-number,
|
||||||
|
& .hljs-params,
|
||||||
|
& .hljs-string,
|
||||||
|
& .hljs-symbol,
|
||||||
|
& .hljs-type,
|
||||||
|
& .hljs-quote {
|
||||||
|
color: highlight;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .hljs-keyword,
|
||||||
|
& .hljs-selector-tag {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[data-mode=dark] {
|
||||||
|
/*!
|
||||||
|
Theme: a11y-dark
|
||||||
|
Author: @ericwbailey
|
||||||
|
Maintainer: @ericwbailey
|
||||||
|
|
||||||
|
Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css
|
||||||
|
*/
|
||||||
|
|
||||||
|
& .hljs {
|
||||||
|
background: #2b2b2b;
|
||||||
|
color: #f8f8f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment */
|
||||||
|
& .hljs-comment,
|
||||||
|
& .hljs-quote {
|
||||||
|
color: #d4d0ab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Red */
|
||||||
|
& .hljs-variable,
|
||||||
|
& .hljs-template-variable,
|
||||||
|
& .hljs-tag,
|
||||||
|
& .hljs-name,
|
||||||
|
& .hljs-selector-id,
|
||||||
|
& .hljs-selector-class,
|
||||||
|
& .hljs-regexp,
|
||||||
|
& .hljs-deletion {
|
||||||
|
color: #ffa07a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Orange */
|
||||||
|
& .hljs-number,
|
||||||
|
& .hljs-built_in,
|
||||||
|
& .hljs-literal,
|
||||||
|
& .hljs-type,
|
||||||
|
& .hljs-params,
|
||||||
|
& .hljs-meta,
|
||||||
|
& .hljs-link {
|
||||||
|
color: #f5ab35;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Yellow */
|
||||||
|
& .hljs-attribute {
|
||||||
|
color: #ffd700;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Green */
|
||||||
|
& .hljs-string,
|
||||||
|
& .hljs-symbol,
|
||||||
|
& .hljs-bullet,
|
||||||
|
& .hljs-addition {
|
||||||
|
color: #abe338;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blue */
|
||||||
|
& .hljs-title,
|
||||||
|
& .hljs-section {
|
||||||
|
color: #00e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Purple */
|
||||||
|
& .hljs-keyword,
|
||||||
|
& .hljs-selector-tag {
|
||||||
|
color: #dcc6e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .hljs-emphasis {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .hljs-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (-ms-high-contrast: active) {
|
||||||
|
& .hljs-addition,
|
||||||
|
& .hljs-attribute,
|
||||||
|
& .hljs-built_in,
|
||||||
|
& .hljs-bullet,
|
||||||
|
& .hljs-comment,
|
||||||
|
& .hljs-link,
|
||||||
|
& .hljs-literal,
|
||||||
|
& .hljs-meta,
|
||||||
|
& .hljs-number,
|
||||||
|
& .hljs-params,
|
||||||
|
& .hljs-string,
|
||||||
|
& .hljs-symbol,
|
||||||
|
& .hljs-type,
|
||||||
|
& .hljs-quote {
|
||||||
|
color: highlight;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .hljs-keyword,
|
||||||
|
& .hljs-selector-tag {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,34 +23,34 @@ module.exports = {
|
||||||
background: 'rgb(var(--color-background) / <alpha-value>)'
|
background: 'rgb(var(--color-background) / <alpha-value>)'
|
||||||
},
|
},
|
||||||
typography: ({ theme }) => ({
|
typography: ({ theme }) => ({
|
||||||
colorful: {
|
inhji: {
|
||||||
css: {
|
css: {
|
||||||
'--tw-prose-lead': theme('colors.rose[700]'),
|
'--tw-prose-lead': theme('colors.neutral[700]'),
|
||||||
'--tw-prose-links': theme('colors.rose[900]'),
|
'--tw-prose-links': theme('colors.neutral[900]'),
|
||||||
'--tw-prose-counters': theme('colors.rose[600]'),
|
'--tw-prose-counters': theme('colors.neutral[600]'),
|
||||||
'--tw-prose-bullets': theme('colors.rose[400]'),
|
'--tw-prose-bullets': theme('colors.neutral[400]'),
|
||||||
'--tw-prose-hr': theme('colors.rose[300]'),
|
'--tw-prose-hr': theme('colors.neutral[300]'),
|
||||||
'--tw-prose-quotes': theme('colors.rose[900]'),
|
'--tw-prose-quotes': theme('colors.neutral[900]'),
|
||||||
'--tw-prose-quote-borders': theme('colors.rose[300]'),
|
'--tw-prose-quote-borders': theme('colors.neutral[300]'),
|
||||||
'--tw-prose-captions': theme('colors.rose[700]'),
|
'--tw-prose-captions': theme('colors.neutral[700]'),
|
||||||
'--tw-prose-code': theme('colors.rose[900]'),
|
'--tw-prose-code': theme('colors.neutral[900]'),
|
||||||
'--tw-prose-pre-code': theme('colors.rose[100]'),
|
'--tw-prose-pre-code': theme('colors.neutral[100]'),
|
||||||
'--tw-prose-pre-bg': theme('colors.rose[900]'),
|
'--tw-prose-pre-bg': theme('colors.neutral[200]'),
|
||||||
'--tw-prose-th-borders': theme('colors.rose[300]'),
|
'--tw-prose-th-borders': theme('colors.neutral[300]'),
|
||||||
'--tw-prose-td-borders': theme('colors.rose[200]'),
|
'--tw-prose-td-borders': theme('colors.neutral[200]'),
|
||||||
'--tw-prose-invert-lead': theme('colors.rose[300]'),
|
'--tw-prose-invert-lead': theme('colors.neutral[300]'),
|
||||||
'--tw-prose-invert-links': theme('colors.white'),
|
'--tw-prose-invert-links': theme('colors.white'),
|
||||||
'--tw-prose-invert-counters': theme('colors.rose[400]'),
|
'--tw-prose-invert-counters': theme('colors.neutral[400]'),
|
||||||
'--tw-prose-invert-bullets': theme('colors.rose[600]'),
|
'--tw-prose-invert-bullets': theme('colors.neutral[600]'),
|
||||||
'--tw-prose-invert-hr': theme('colors.rose[700]'),
|
'--tw-prose-invert-hr': theme('colors.neutral[700]'),
|
||||||
'--tw-prose-invert-quotes': theme('colors.rose[100]'),
|
'--tw-prose-invert-quotes': theme('colors.neutral[100]'),
|
||||||
'--tw-prose-invert-quote-borders': theme('colors.rose[700]'),
|
'--tw-prose-invert-quote-borders': theme('colors.neutral[700]'),
|
||||||
'--tw-prose-invert-captions': theme('colors.rose[400]'),
|
'--tw-prose-invert-captions': theme('colors.neutral[400]'),
|
||||||
'--tw-prose-invert-code': theme('colors.white'),
|
'--tw-prose-invert-code': theme('colors.white'),
|
||||||
'--tw-prose-invert-pre-code': theme('colors.rose[300]'),
|
'--tw-prose-invert-pre-code': theme('colors.neutral[300]'),
|
||||||
'--tw-prose-invert-pre-bg': 'rgb(0 0 0 / 50%)',
|
'--tw-prose-invert-pre-bg': 'rgb(0 0 0 / 50%)',
|
||||||
'--tw-prose-invert-th-borders': theme('colors.rose[600]'),
|
'--tw-prose-invert-th-borders': theme('colors.neutral[600]'),
|
||||||
'--tw-prose-invert-td-borders': theme('colors.rose[700]'),
|
'--tw-prose-invert-td-borders': theme('colors.neutral[700]'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -58,9 +58,11 @@ defmodule Chiya.Notes do
|
||||||
Chiya.Flop.validate_and_run(q, params, for: Chiya.Notes.Note)
|
Chiya.Flop.validate_and_run(q, params, for: Chiya.Notes.Note)
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_apply_notes(regex) do
|
def list_apply_notes(%Chiya.Tags.Tag{} = tag) do
|
||||||
Note
|
Note
|
||||||
|> where([n], fragment("? ~ ?", n.name, ^regex))
|
|> where([n], fragment("? ~ ?", n.name, ^tag.regex))
|
||||||
|
|> or_where([n], fragment("? ~ ?", n.url, ^tag.regex))
|
||||||
|
|> or_where([n], fragment("? ~ ?", n.content, ^tag.regex))
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -15,5 +15,6 @@ defmodule Chiya.Notes.NoteTag do
|
||||||
note_tag
|
note_tag
|
||||||
|> cast(attrs, [:note_id, :tag_id])
|
|> cast(attrs, [:note_id, :tag_id])
|
||||||
|> validate_required([:note_id, :tag_id])
|
|> validate_required([:note_id, :tag_id])
|
||||||
|
|> unique_constraint([:note_id, :tag_id])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,9 +38,10 @@ defmodule Chiya.Tags do
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_admin_tags(params) do
|
def list_admin_tags() do
|
||||||
q =
|
q =
|
||||||
Tag
|
Tag
|
||||||
|
|> order_by(:name)
|
||||||
|> with_preloads()
|
|> with_preloads()
|
||||||
|
|
||||||
Repo.all(q)
|
Repo.all(q)
|
||||||
|
|
|
@ -8,6 +8,13 @@ defmodule Chiya.Tags.TagUpdater do
|
||||||
alias Chiya.{Notes, Tags}
|
alias Chiya.{Notes, Tags}
|
||||||
alias Chiya.Notes.Note
|
alias Chiya.Notes.Note
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Updates a tag for the given note.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> update_tags({:ok, note}, "foo,bar")
|
||||||
|
"""
|
||||||
def update_tags({:ok, %Note{} = note}, attrs) do
|
def update_tags({:ok, %Note{} = note}, attrs) do
|
||||||
note
|
note
|
||||||
|> Notes.preload_note()
|
|> Notes.preload_note()
|
||||||
|
@ -20,27 +27,19 @@ defmodule Chiya.Tags.TagUpdater do
|
||||||
{:error, changeset}
|
{:error, changeset}
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
def update_tags(%Note{} = note, %{tags_string: new_tags} = attrs) when is_map(attrs) do
|
||||||
Updates the tags for the given note
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> update_tags(note, "foo,bar")
|
|
||||||
|
|
||||||
"""
|
|
||||||
def update_tags(note, %{tags_string: new_tags} = attrs) when is_map(attrs) do
|
|
||||||
update_tags(note, new_tags)
|
update_tags(note, new_tags)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_tags(note, %{"tags_string" => new_tags} = attrs) when is_map(attrs) do
|
def update_tags(%Note{} = note, %{"tags_string" => new_tags} = attrs) when is_map(attrs) do
|
||||||
update_tags(note, new_tags)
|
update_tags(note, new_tags)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_tags(note, attrs) when is_map(attrs) do
|
def update_tags(%Note{} = note, attrs) when is_map(attrs) do
|
||||||
note
|
note
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_tags(note, new_tags) when is_binary(new_tags) do
|
def update_tags(%Note{} = note, new_tags) when is_binary(new_tags) do
|
||||||
update_tags(note, split_tags(new_tags))
|
update_tags(note, split_tags(new_tags))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,14 +61,7 @@ defmodule Chiya.Tags.TagUpdater do
|
||||||
|> remove_tags(old_tags -- new_tags)
|
|> remove_tags(old_tags -- new_tags)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp split_tags(tags_string) when is_binary(tags_string) do
|
def add_tags(note, tags) do
|
||||||
tags_string
|
|
||||||
|> String.split(",")
|
|
||||||
|> Enum.map(&String.trim/1)
|
|
||||||
|> Enum.filter(&(String.length(&1) > 0))
|
|
||||||
end
|
|
||||||
|
|
||||||
defp add_tags(note, tags) do
|
|
||||||
tags
|
tags
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
|> Enum.each(&add_tag(note, &1))
|
|> Enum.each(&add_tag(note, &1))
|
||||||
|
@ -77,6 +69,13 @@ defmodule Chiya.Tags.TagUpdater do
|
||||||
note
|
note
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp split_tags(tags_string) when is_binary(tags_string) do
|
||||||
|
tags_string
|
||||||
|
|> String.split(",")
|
||||||
|
|> Enum.map(&String.trim/1)
|
||||||
|
|> Enum.filter(&(String.length(&1) > 0))
|
||||||
|
end
|
||||||
|
|
||||||
defp add_tag(%{id: note_id} = note, tag) when is_binary(tag) do
|
defp add_tag(%{id: note_id} = note, tag) when is_binary(tag) do
|
||||||
slug = Slugger.slugify_downcase(tag)
|
slug = Slugger.slugify_downcase(tag)
|
||||||
|
|
||||||
|
@ -100,7 +99,13 @@ defmodule Chiya.Tags.TagUpdater do
|
||||||
tag_id: tag.id
|
tag_id: tag.id
|
||||||
}
|
}
|
||||||
|
|
||||||
{:ok, _note_tag} = Notes.create_note_tag(attrs)
|
case Notes.create_note_tag(attrs) do
|
||||||
|
{:ok, _note_tag} ->
|
||||||
|
true
|
||||||
|
|
||||||
|
{:error, changeset} ->
|
||||||
|
Logger.warn(inspect(changeset))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,21 +8,15 @@ defmodule ChiyaWeb.PageController do
|
||||||
defp put_assigns(conn, opts) do
|
defp put_assigns(conn, opts) do
|
||||||
conn
|
conn
|
||||||
|> assign(:page_header, true)
|
|> assign(:page_header, true)
|
||||||
|
|> assign(:page_title, "no title")
|
||||||
end
|
end
|
||||||
|
|
||||||
def home(conn, params) do
|
def home(conn, params) do
|
||||||
settings = conn.assigns.settings
|
settings = conn.assigns.settings
|
||||||
|
|
||||||
{channel, notes, meta} =
|
if settings.home_channel_id do
|
||||||
case settings.home_channel_id do
|
channel = Channels.get_channel!(settings.home_channel_id)
|
||||||
nil ->
|
|
||||||
nil
|
|
||||||
|
|
||||||
id ->
|
|
||||||
channel = Channels.get_channel!(id)
|
|
||||||
{:ok, {notes, meta}} = Chiya.Notes.list_home_notes(channel, params)
|
{:ok, {notes, meta}} = Chiya.Notes.list_home_notes(channel, params)
|
||||||
{channel, notes, meta}
|
|
||||||
end
|
|
||||||
|
|
||||||
render(conn, :home,
|
render(conn, :home,
|
||||||
channel: channel,
|
channel: channel,
|
||||||
|
@ -31,6 +25,9 @@ defmodule ChiyaWeb.PageController do
|
||||||
page_title: "Home",
|
page_title: "Home",
|
||||||
page_header: false
|
page_header: false
|
||||||
)
|
)
|
||||||
|
else
|
||||||
|
render_error(conn, :not_found)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def channel(conn, %{"slug" => channel_slug}) do
|
def channel(conn, %{"slug" => channel_slug}) do
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
defmodule ChiyaWeb.PageHTML do
|
defmodule ChiyaWeb.PageHTML do
|
||||||
use ChiyaWeb, :html_public
|
use ChiyaWeb, :html_public
|
||||||
import ChiyaWeb.Format, only: [pretty_datetime: 1, pretty_date: 1, datetime: 1]
|
import ChiyaWeb.Format, only: [pretty_datetime: 1, pretty_date: 1]
|
||||||
|
|
||||||
embed_templates "page_html/*"
|
embed_templates "page_html/*"
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ defmodule ChiyaWeb.TagController do
|
||||||
use ChiyaWeb, :controller
|
use ChiyaWeb, :controller
|
||||||
alias Chiya.Tags
|
alias Chiya.Tags
|
||||||
|
|
||||||
def index(conn, params) do
|
def index(conn, _params) do
|
||||||
tags = Chiya.Tags.list_admin_tags(params)
|
tags = Chiya.Tags.list_admin_tags()
|
||||||
|
|
||||||
render(conn, :index, tags: tags)
|
render(conn, :index, tags: tags)
|
||||||
end
|
end
|
||||||
|
@ -13,13 +13,26 @@ defmodule ChiyaWeb.TagController do
|
||||||
render(conn, :show, tag: tag)
|
render(conn, :show, tag: tag)
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply(conn, %{"id" => id}) do
|
def apply_prepare(conn, %{"id" => id}) do
|
||||||
tag = Tags.get_tag!(id)
|
tag = Tags.get_tag!(id)
|
||||||
notes = Chiya.Notes.list_apply_notes(tag.regex)
|
notes = Chiya.Notes.list_apply_notes(tag)
|
||||||
|
|
||||||
render(conn, :apply_prepare, tag: tag, notes: notes)
|
render(conn, :apply_prepare, tag: tag, notes: notes)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def apply_run(conn, %{"id" => id}) do
|
||||||
|
tag = Tags.get_tag!(id)
|
||||||
|
notes = Chiya.Notes.list_apply_notes(tag)
|
||||||
|
|
||||||
|
Enum.each(notes, fn note ->
|
||||||
|
IO.inspect("Updating note: #{note.name}")
|
||||||
|
Chiya.Tags.TagUpdater.add_tags(note, [tag.slug])
|
||||||
|
end)
|
||||||
|
|
||||||
|
notes = Chiya.Notes.list_apply_notes(tag)
|
||||||
|
render(conn, :apply_prepare, tag: tag, notes: notes)
|
||||||
|
end
|
||||||
|
|
||||||
def edit(conn, %{"id" => id}) do
|
def edit(conn, %{"id" => id}) do
|
||||||
IO.inspect(id)
|
IO.inspect(id)
|
||||||
tag = Tags.get_tag!(id)
|
tag = Tags.get_tag!(id)
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
<.header>
|
<.header>
|
||||||
Apply Tag <%= @tag.name %>
|
Apply Tag <%= @tag.name %>
|
||||||
<:subtitle>These notes will get the tag.</:subtitle>
|
<:subtitle><%= Enum.count(@notes) %> notes will get the tag.</:subtitle>
|
||||||
<:actions>
|
<:actions>
|
||||||
<.link href={~p"/admin/tags/#{@tag}/apply"}>
|
<.link href={~p"/admin/tags/#{@tag}/apply/run"}>
|
||||||
<.button>Apply tag</.button>
|
<.button>Apply tag</.button>
|
||||||
</.link>
|
</.link>
|
||||||
</:actions>
|
</:actions>
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
<section>
|
<section class="card-list">
|
||||||
<%= for note <- @notes do %>
|
<%= for note <- @notes do %>
|
||||||
<article class="bg-slate-100 dark:bg-slate-800 text-slate-900 dark:text-slate-100 p-3 rounded">
|
<article class="card">
|
||||||
<header>
|
<header>
|
||||||
<h2 class="text-xl leading-normal">
|
<h2>
|
||||||
<a href={"/admin/notes/#{note.id}"}><%= note.name %></a>
|
<a href={"/admin/notes/#{note.id}"}><%= note.name %></a>
|
||||||
</h2>
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
<footer class="flex gap-3 text-sm ">
|
<footer>
|
||||||
<span>Updated <%= from_now(note.updated_at) %></span>
|
<span>Updated <%= from_now(note.updated_at) %></span>
|
||||||
<span>Published <%= from_now(note.published_at) %></span>
|
<span>Published <%= from_now(note.published_at) %></span>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -3,17 +3,43 @@
|
||||||
<:subtitle>Tags are tags.</:subtitle>
|
<:subtitle>Tags are tags.</:subtitle>
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
<section class="flex flex-col gap-3 mt-6">
|
<section class="card-list mt-8">
|
||||||
<%= for tag <- @tags do %>
|
<h3 class="leading-normal text-xl">With Regex</h3>
|
||||||
<article class="bg-neutral-100 dark:bg-neutral-800 text-neutral-900 dark:text-neutral-100 p-3 rounded">
|
|
||||||
|
<%= for tag <- Enum.filter(@tags, fn t -> !!t.regex end) do %>
|
||||||
|
<article class="card">
|
||||||
<header>
|
<header>
|
||||||
<h2 class="text-xl leading-normal">
|
<h2>
|
||||||
<a href={"/admin/tags/#{tag.id}"}><%= tag.name %></a>
|
<a href={"/admin/tags/#{tag.id}"}><%= tag.name %></a>
|
||||||
</h2>
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
<footer class="flex gap-3 text-sm ">
|
<footer>
|
||||||
<span><%= Enum.count(tag.notes) %> notes</span>
|
<span><%= Enum.count(tag.notes) %> notes</span>
|
||||||
<span>Updated <%= from_now(tag.updated_at) %></span>
|
<span>Updated <%= from_now(tag.updated_at) %></span>
|
||||||
|
<%= if String.length(tag.regex || "") > 0 do %>
|
||||||
|
<span>Regex: <%= tag.regex %></span>
|
||||||
|
<% end %>
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
<% end %>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="card-list mt-8">
|
||||||
|
<h3 class="leading-normal text-xl">Without Regex</h3>
|
||||||
|
|
||||||
|
<%= for tag <- Enum.filter(@tags, fn t -> !t.regex end) do %>
|
||||||
|
<article class="card">
|
||||||
|
<header>
|
||||||
|
<h2>
|
||||||
|
<a href={"/admin/tags/#{tag.id}"}><%= tag.name %></a>
|
||||||
|
</h2>
|
||||||
|
</header>
|
||||||
|
<footer>
|
||||||
|
<span><%= Enum.count(tag.notes) %> notes</span>
|
||||||
|
<span>Updated <%= from_now(tag.updated_at) %></span>
|
||||||
|
<%= if String.length(tag.regex || "") > 0 do %>
|
||||||
|
<span>Regex: <%= tag.regex %></span>
|
||||||
|
<% end %>
|
||||||
</footer>
|
</footer>
|
||||||
</article>
|
</article>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -77,7 +77,8 @@ defmodule ChiyaWeb.Router do
|
||||||
resources "/tokens", TokenController, only: [:index, :show, :new, :create, :delete]
|
resources "/tokens", TokenController, only: [:index, :show, :new, :create, :delete]
|
||||||
resources "/tags", TagController, only: [:index, :edit, :update, :show]
|
resources "/tags", TagController, only: [:index, :edit, :update, :show]
|
||||||
|
|
||||||
get "/tags/:id/apply", TagController, :apply
|
get "/tags/:id/apply", TagController, :apply_prepare
|
||||||
|
get "/tags/:id/apply/run", TagController, :apply_run
|
||||||
|
|
||||||
get "/notes/import", NoteController, :import_prepare
|
get "/notes/import", NoteController, :import_prepare
|
||||||
post "/notes/import", NoteController, :import_run
|
post "/notes/import", NoteController, :import_run
|
||||||
|
|
Loading…
Reference in a new issue