src/views/middleware/newui-dispatcher.lisp

DOWNLOAD
(defpackage murja.newui.dispatcher
  (:use :cl :murja.views.components.root :murja.views.components.tab :cl-hash-util)
  (:import-from :murja.newui :c)
  (:import-from :murja.middleware.auth :@ssr-authenticated :*user*)
  (:export :@dispatcher :deftab))

(in-package :murja.newui.dispatcher)

;; (defun @view-dispatcher (next)
;;   "Returns newui data structures based on whatever parameters next returns.

(defclass tab ()
  ((route :initarg :route :initform (error "Route needed") :accessor tab-route)
   (component :initarg :component :initform (error "Component needed") :accessor tab-component)
   (title :initarg :title :initform (error "Title needed") :accessor title)
   (require-login :initarg :require-login :initform nil :accessor require-login)
   (needed-abilities :initarg :abilities :initform nil :accessor abilities)))

(defmethod print-object ((current-tab tab) output)
  (with-slots (route title needed-abilities) current-tab
    (format output "#<TAB: ~{~{~a: ~s~}~^,~%~t ~}>" (list
						     (list :route route)
						     (list :title title)
						     (list :needed-abilities needed-abilities)))))

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defvar *tabs* (make-hash-table :test 'equal)
    "A list of tabs, keyed by symbol and valued by instances of tab class"))

(defmacro deftab (sym (&key
			 route
			 title
			 require-login
			 needed-abilities)
		  &body rst)
  `(setf (gethash (quote ,sym) *tabs*)
	 (make-instance 'tab :route ,route
			     :abilities ,needed-abilities
			     :require-login ,require-login
			     :title ,title
			     :component (lambda ()
					  (c :div ()
					     ,@rst)))))
(defun @dispatcher (next)
  (let* ((sym (funcall next))
	 (tab (gethash sym *tabs*))
	 (usr-abilities (when *user*
			  (coerce (murja.models.user:abilities *user*) 'list))))
    (assert tab)

    (when (or (not (abilities tab))
	      (intersection usr-abilities (abilities tab))
	      (or (not (require-login tab))
		  *user*))
	      
      (let ((tab-spec (hash)))
	(maphash (lambda (k v)
		   (declare (ignore k))
		   (format t "req login? ~a~%" (require-login v))
		   (when (or (not (require-login v))
			     *user*)
		     (setf (gethash (title v) tab-spec)
			   (funcall (tab-component v)))))
		 *tabs*)
      (root-component
       (tabs (title tab)
	     tab-spec))))))