/ src / admin / crud.lisp
crud.lisp
 1  (in-package :ami.admin)
 2  
 3  (defun format-route (control-string &rest args)
 4    (let ((extended-ctrl-string (format nil "~~@[/~~a~~]~a" control-string)))
 5      (apply #'format 
 6             (append 
 7              (list nil extended-ctrl-string (when (get-config :is-development)
 8                                               "cheapcharminghouses.com"))
 9              args))))
10  
11  (defmethod create-route ((mdef ami.modeling:model-definition))
12    (format-route "/admin/~(~a~)/new" (ami.modeling:model-name mdef)))
13  
14  (defmethod update-route ((m ami.modeling:model))
15    (let ((mdef (ami.modeling:model-definition m)))
16      (format-route "/admin/~(~a~)/~a"
17                    (ami.modeling:model-name mdef)
18                    (ami.modeling:model-id m))))
19  
20  (defmethod edit-route ((m ami.modeling:model))
21    (let ((mdef (ami.modeling:model-definition m)))
22      (format-route "/admin/~(~a~)/~a/edit"
23                    (ami.modeling:model-name mdef)
24                    (ami.modeling:model-id m))))
25  
26  (defmethod list-route ((mdef ami.modeling:model-definition))
27    (let ((mname (ami.modeling:model-name mdef)))
28      (format nil "~@[/~a~]/~(~a~)s" (if T "cheapcharminghouses.com") mname)))
29  
30  (defun render-form-field (field mdef &optional obj)
31    (let ((accessor (alexandria:format-symbol 
32                     (ami.modeling:model-package mdef) "~a-~a" (ami.modeling:model-name mdef) field))
33  	(fdef (gethash field (ami.modeling:model-fields mdef))))
34      (ami.modeling:render-form fdef
35                   (when obj (funcall accessor obj)))))
36  
37  (defun render-view-field (field mdef obj)
38    (let* ((fdef (if (symbolp field)
39                     (gethash field (ami.modeling:model-fields mdef))
40                   field))
41  	 (accessor (ami.modeling:get-accessor mdef fdef)))
42      (html
43       (:div
44        :id (ami.modeling:field-domid fdef obj) 
45        (ami.modeling:render-view
46         fdef
47         (funcall accessor obj))))))
48  
49  (defmethod new ((mdef ami.modeling:model-definition))
50    (html
51     (:form
52      :id (format nil "~a-new" (ami.modeling:name-as-string mdef))
53      (dolist (field (alexandria:hash-table-keys (ami.modeling:model-fields mdef)))
54        (render-form-field field mdef))
55      (:input :hx-swap "outerHTML"
56  	    :hx-post (create-route mdef)
57  	    :hx-push-url (list-route mdef)
58  	    :hx-target "#content"
59  	    :hx-select "#content"
60  	    :type "submit"
61  	    :value "Create"))))
62  
63  (defmethod edit ((obj ami.modeling:model))
64     (let* ((mdef (ami.modeling:model-definition obj)))
65       (html
66        (:form
67         :id (ami.modeling:domid obj)
68         :class "flex flex-col p-1.5"
69         (dolist (field (alexandria:hash-table-keys (ami.modeling:model-fields mdef)))
70   	(render-form-field field mdef obj))
71         (:input :hx-swap "outerHTML"
72          :hx-target (ami.modeling:domid obj :for-selector t) 
73          :hx-select (ami.modeling:domid obj :for-selector t) 
74          :hx-patch (update-route obj)
75          :class "flex w-full justify-center rounded bg-primary p-3 font-medium text-gray-100 hover:bg-opacity-90"
76          :type "submit"
77          :value "Save")))))
78  
79  (defmethod view ((obj ami.modeling:model))
80     (let* ((mdef (ami.modeling:model-definition obj)))
81       (html
82        (:div
83         :class "w-[75%] rounded-sm border border-stroke bg-white shadow-default dark:border-strokedark dark:bg-boxdark"
84         (:div
85          :id (ami.modeling:domid obj) 
86          :class "flex flex-col p-1.5"
87          (dolist (field (alexandria:hash-table-keys (ami.modeling:model-fields mdef)))
88            (render-view-field field mdef obj))
89          (:button :hx-swap "outerHTML"
90           :hx-target (ami.modeling:domid obj :for-selector t) 
91           :hx-select (ami.modeling:domid obj :for-selector t)
92           :data-hx-get (edit-route obj)
93           "Edit"))))))