src/view/admin/components/previouslies-script.lisp

DOWNLOAD
(in-package :murja.view.admin.components.previouslies-script)

(eval-when (:compile-toplevel :load-toplevel :execute)

  (named-readtables:in-readtable :murja.ps))

(defun previouslies-component-frontend ()
  (ps
    (defun remove-previously (id)
      (lambda (e)
	(chain e (prevent-default))
	(let* ((previouslies-input (chain document
					  (query-selector "#previouslies")))
	       (previouslies (chain JSON (parse (@ previouslies-input value)))))
	  (setf (@ previouslies-input value)
		(chain JSON
		       (stringify 
			(chain previouslies
			       (filter 
				(lambda (el)
				  (not (= (@ el id) id))))))))

	  (regenerate-previously-component nil))))
    
    (defun regenerate-previously-component (e)
      
      (let* ((previouslies-container (chain document
					    (query-selector "#previouslies-container")))
	     (previouslies-input (chain document
					(query-selector "#previouslies")))
	     (previouslies (chain JSON (parse (@ previouslies-input value))))

	     (ul-root (chain document
			     (create-element "ul"))))

	;; drop the old previously DOM completely, holding on to the state-holding <input type="hidden"/> 
	(setf (@ previouslies-container innerHTML) "")

	;; generate list of links ->posts and buttons to remove them 
	(dolist (el previouslies)
	  (let ((li (chain document (create-element "li")))
		(a (chain document (create-element "a")))
		
		(remove-btn (chain document (create-element "button"))))
	    (setf (@ remove-btn inner-text) "X")
	    (setf (@ a href) (+ "/blog/post/" (@ el id)))
	    (setf (@ a inner-text) (@ el title))
	    (chain remove-btn
		   (add-event-listener "click" (remove-previously (@ el id))))

	    (chain li
		   (append-child a))
	    (chain li
		   (append-child remove-btn))

	    (setf (@ li class-name) "editor-previously-li")
	    
	    (chain ul-root
		   (append-child li))))

	;; add the state-holding <input type="hidden" /> back to DOM 
	(chain previouslies-container
	       (append-child previouslies-input))

	;; add the previously generated <ul> tree into DOM 
	(chain previouslies-container
	       (append-child ul-root))
	
	nil))

    (defun-async previously-searched (e)
      (let ((result (await (fetch (murja.genurl:route->url-ps 'murja.routes.post-routes:search-prev)
				  (create
				   method "POST"
				   body (@ e target value)
				   headers (create
					    "Content-Type" "application/json"))))))

	(when (equal 200 (@ result status))
	  (let* ((previouslies-input (chain document
					    (query-selector "#previouslies")))
		 (current-previouslies (chain JSON (parse (@ previouslies-input value))))
		 (root-select (chain document
				     (query-selector "#previouslyPostResult")))
		 (result (await (chain result (json))))
		 (result-data (chain result
				     (filter (lambda (el)
					       (not (chain current-previouslies
							   (includes el))))))))

	    (setf (@ root-select innerHTML) "")
				    
	    (dolist (result result-data)
	      (let ((option (chain document
				   (create-element "option"))))
		(setf (@ option innerText) (@ result title))
		(setf (@ option value) (@ result id))
		(chain option
		       (add-event-listener "click" (lambda (e)
						     (chain e (prevent-default))
						     (let* ((id (@ e target value))
							    (title (@ e target innerText))
							    (previouslies-input (chain document
										       (query-selector "#previouslies")))
							    (current-previouslies (chain JSON (parse (@ previouslies-input value)))))
						       (chain current-previouslies
							      (push (create id id
									    title title)))
						       (setf (@ previouslies-input value) (chain JSON (stringify current-previouslies)))

						       (setf (@ root-select innerHTML) "")
						       (setf (@ (chain document
								       (query-selector "#previouslySearcher"))
								innerHTML) "")

						       (regenerate-previously-component)))))
						       
		(chain root-select (append-child option))))))))

    (defun link-add-previously-button (e)
      (chain document
	     (query-selector "#add-previously")
	     (add-event-listener "click"
				 (lambda (ee)
				   (chain ee (prevent-default))
				   (chain document
					  (query-selector "#previouslyModal")
					  (show-modal)))))

      (chain document
	     (query-selector "#closeModal")
	     (add-event-listener "click"
				 (lambda (ee)
				   (chain ee (prevent-default))
				   (chain document
					  (query-selector "#previouslyModal")
					  (close)))))

      (chain document
	     (query-selector "#previouslySearcher")
	     (add-event-listener "input" #'previously-searched)))
      
    
    (chain document
	   (add-event-listener "DOMContentLoaded"
			       #'regenerate-previously-component))

    (chain document
	   (add-event-listener "DOMContentLoaded"
			       #'link-add-previously-button))))