Add a drawer, routes, handlers to update an article.
This commit is contained in:
@@ -104,6 +104,43 @@
|
||||
(res/status 500)
|
||||
(res/send (ex-message err))))))))
|
||||
|
||||
(defn htmx-get-article-edit-content-handler-factory
|
||||
[client]
|
||||
(fn [req res]
|
||||
(let [channel (chan)
|
||||
id (.-id (.-params req))]
|
||||
(go
|
||||
(try
|
||||
(let [article (<! (db/get-article client id channel))]
|
||||
(if (empty? article)
|
||||
(do
|
||||
(res/status 404)
|
||||
(res/send (ex-message "404")))
|
||||
(do
|
||||
(res/status 200)
|
||||
(.render res "admin_article_edit_content"
|
||||
(-> {:article article :layout false }
|
||||
(cljs.core/clj->js))))))
|
||||
(catch js/Error err
|
||||
(res/status 500)
|
||||
(res/send (ex-message err))))))))
|
||||
|
||||
(defn htmx-update-article-handler-factory
|
||||
[client]
|
||||
(fn [req res]
|
||||
(let [channel (chan)
|
||||
article {:id (.-id (.-params req))
|
||||
:title (.-title (.-body req))
|
||||
:content (.-content (.-body req))}]
|
||||
(go
|
||||
(try
|
||||
(let [id (<! (db/update-article client article channel))]
|
||||
(res/status 200)
|
||||
(.redirect res 303 (str "/htmx/admin/rows/article/" id)))
|
||||
(catch js/Error err
|
||||
(res/status 500)
|
||||
(res/send (ex-message err))))))))
|
||||
|
||||
(defn htmx-delete-article-row-handler-factory
|
||||
[client]
|
||||
(fn [req res]
|
||||
|
||||
@@ -85,11 +85,17 @@
|
||||
(. app get "/htmx/admin/rows/article/:id/"
|
||||
(handlers/htmx-get-article-row-handler-factory client))
|
||||
|
||||
(. app get "/htmx/admin/modals/article/content/:id/"
|
||||
(handlers/htmx-get-article-preview-content-handler-factory client))
|
||||
(. app patch "/htmx/admin/rows/article/:id/"
|
||||
(handlers/htmx-update-article-handler-factory client))
|
||||
|
||||
(. app delete "/htmx/admin/rows/article/:id/"
|
||||
(handlers/htmx-delete-article-row-handler-factory client))
|
||||
|
||||
(. app get "/htmx/admin/modals/article/content/:id/"
|
||||
(handlers/htmx-get-article-preview-content-handler-factory client))
|
||||
|
||||
(. app get "/htmx/admin/modals/article/edit-content/:id/"
|
||||
(handlers/htmx-get-article-edit-content-handler-factory client))
|
||||
)
|
||||
|
||||
(defn start
|
||||
|
||||
+54
-1
@@ -103,7 +103,7 @@
|
||||
</button>
|
||||
</div>
|
||||
<!-- Modal body -->
|
||||
<form action="#">
|
||||
<form>
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1">
|
||||
<div>
|
||||
<label for="title" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Title</label>
|
||||
@@ -128,6 +128,59 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Update modal -->
|
||||
<form id="drawer-update-article"
|
||||
x-data="{ id: null, title: '', created: '' }"
|
||||
@update_article.window="id = $event.detail.id; title = $event.detail.title; created = $event.detail.created;"
|
||||
x-init="$watch('id', () => htmx.process(htmx.find('#confirmUpdateButton')))"
|
||||
tabindex="-1"
|
||||
aria-labelledby="drawer-update-article-label"
|
||||
aria-hidden="true"
|
||||
class="fixed top-0 left-0 z-40 w-full h-screen max-w-3xl p-4 overflow-y-auto transition-transform -translate-x-full bg-white dark:bg-gray-800">
|
||||
<h5 id="drawer-label" class="inline-flex items-center mb-6 text-sm font-semibold text-gray-500 uppercase dark:text-gray-400">Update Article</h5>
|
||||
<button type="button" data-drawer-dismiss="drawer-update-article" aria-controls="drawer-update-article" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 absolute top-2.5 right-2.5 inline-flex items-center dark:hover:bg-gray-600 dark:hover:text-white">
|
||||
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewbox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
<span class="sr-only">Close menu</span>
|
||||
</button>
|
||||
<div class="grid gap-4 sm:grid-cols-1 sm:gap-6 ">
|
||||
<div class="space-y-4 sm:col-span-1 sm:space-y-6">
|
||||
<div>
|
||||
<label for="title" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Title</label>
|
||||
<input type="text"
|
||||
name="title"
|
||||
x-model="title"
|
||||
id="update-title"
|
||||
placeholder="Type article title"
|
||||
required=""
|
||||
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500">
|
||||
</div>
|
||||
<div>
|
||||
<label for="content" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Content</label>
|
||||
<textarea id="update-drawer-content" name="content" rows="4" class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-primary-500 focus:border-primary-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="Write article here"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4 mt-6 sm:w-1/2">
|
||||
<button id="confirmUpdateButton"
|
||||
data-drawer-toggle="drawer-update-article"
|
||||
aria-controls="drawer-update-article"
|
||||
type="submit"
|
||||
hx-swap="outerHTML"
|
||||
x-bind:hx-patch="`/htmx/admin/rows/article/${id}`"
|
||||
x-bind:hx-target="`#row-${id}`"
|
||||
class="text-white bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Update</button>
|
||||
<button type="button"
|
||||
data-drawer-dismiss="drawer-update-article"
|
||||
aria-controls="drawer-update-article"
|
||||
class="text-sm font-medium text-center text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-primary-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Preview Drawer -->
|
||||
<div id="drawer-read-article-advanced"
|
||||
x-data="{ title: '', created: '' }"
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.3.0/flowbite.min.css" rel="stylesheet" />
|
||||
<script>
|
||||
htmx.onLoad(function(content) {
|
||||
if(!content.outerHTML.startsWith('<p'))
|
||||
if(!content.outerHTML.startsWith('<p')
|
||||
&& !content.outerHTML.startsWith('<textarea'))
|
||||
initFlowbite();
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<tr id="row-{{ article.id }}"
|
||||
x-data='{ title: "{{ article.title }}", created: "{{ full-timestamp article.created }}" }'
|
||||
x-data='{ id: "{{ article.id }}", title: "{{ article.title }}", created: "{{ full-timestamp article.created }}" }'
|
||||
class="border-b dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700">
|
||||
<th scope="row" class="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
<div class="flex items-center mr-3" x-text="title">
|
||||
@@ -11,7 +11,14 @@
|
||||
<td class="px-4 py-3" x-text="created"></td>
|
||||
<td class="px-4 py-3 font-medium text-gray-900 whitespace-nowrap dark:text-white">
|
||||
<div class="flex items-center space-x-4">
|
||||
<button type="button" data-drawer-target="drawer-update-product" data-drawer-show="drawer-update-product" aria-controls="drawer-update-product" class="py-2 px-3 flex items-center text-sm font-medium text-center text-white bg-primary-700 rounded-lg hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
|
||||
<button type="button"
|
||||
@click="$dispatch('update_article', { id: id, title: title, created: created })"
|
||||
hx-get="/htmx/admin/modals/article/edit-content/{{ article.id }}/"
|
||||
hx-swap="outerHTML"
|
||||
hx-target="#update-drawer-content"
|
||||
data-drawer-target="drawer-update-article"
|
||||
data-drawer-show="drawer-update-article"
|
||||
class="py-2 px-3 flex items-center text-sm font-medium text-center text-white bg-primary-700 rounded-lg hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2 -ml-0.5" viewbox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z" />
|
||||
<path fill-rule="evenodd" d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" clip-rule="evenodd" />
|
||||
@@ -33,7 +40,7 @@
|
||||
Preview
|
||||
</button>
|
||||
<button type="button"
|
||||
@click="$dispatch('show_delete_modal', { id: '{{ article.id }}'});"
|
||||
@click="$dispatch('show_delete_modal', { id: id });"
|
||||
data-modal-target="delete-modal"
|
||||
data-modal-toggle="delete-modal"
|
||||
class="flex items-center text-red-700 hover:text-white border border-red-700 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-3 py-2 text-center dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600 dark:focus:ring-red-900">
|
||||
|
||||
Reference in New Issue
Block a user