0 | module Web.MVC.Controller.List
5 | import Text.HTML.Class
6 | import Text.HTML.DomID
7 | import Web.MVC.Controller
15 | zipWithIndex : List t -> List (Nat,t)
16 | zipWithIndex vs = fst (foldl (\(x,n),v => (x:<(n,v),S n)) ([<],Z) vs) <>> []
18 | del : Nat -> List (Nat,t) -> List (Nat,t)
19 | del n = filter ((n /=) . fst)
21 | nextID : List (Nat,t) -> Nat
23 | nextID (x :: xs) = S $
foldl (\x => max x . fst) (fst x) xs
31 | data ListEv : Type -> Type where
33 | Del : (ix : Nat) -> ListEv e
34 | Change : (ix : Nat) -> (ev : e) -> ListEv e
38 | 0 ListEditor : (i,s,e,t : Type) -> Type
39 | ListEditor i s e t = Editor i (List (Nat,s)) (ListEv e) (List t)
43 | 0 List1Editor : (i,s,e,t : Type) -> Type
44 | List1Editor i s e t = Editor i (List (Nat,s)) (ListEv e) (List1 t)
48 | data ListMode = Append | Prepend
50 | insert : ListMode -> Nat -> s -> List (Nat,s) -> List (Nat,s)
51 | insert Append n v vs = vs ++ [(n,v)]
52 | insert Prepend n v vs = (n,v) :: vs
54 | insertCmd : Cast i DomID => ListMode -> i -> Node e -> Cmd e
55 | insertCmd Append = elemAppend
56 | insertCmd Prepend = elemPrepend
60 | record ListEnv (i : Type) where
64 | rowID : i -> Nat -> i
73 | delIcon : {0 e : _} -> e -> Node e
76 | addIcon : {0 e : _} -> e -> Node e
85 | parameters {0 i,s,e,t : Type}
86 | {auto cst : Cast i DomID}
91 | listRow : (i -> s -> Node e) -> i -> (Nat,s) -> Node (ListEv e)
93 | let lid := li.rowID u n
94 | in div [cls (Row :< "list-edit") li.cls, ref lid]
95 | [Change n <$> f lid x, li.delIcon (Del n)]
100 | values : (i -> s -> Node e) -> i -> List (Nat,s) -> Node (ListEv e)
102 | div [cls (Cell :< "list-edit") li.cls ]
103 | [ div [cls (Row :< "list-add") li.cls] [li.addIcon Add]
104 | , div [cls (Lst :< "list-edit") li.cls, ref $
li.listID u]
105 | (listRow f u <$> ps)
111 | list : Editor i s e t -> ListEditor i s e t
115 | (\u => batch . map (\(n,v) => init u n v))
116 | (traverse (ed.stToNew . snd))
117 | (maybe [] (zipWithIndex . map (ed.toState . Just)))
120 | row : i -> Nat -> s -> Node (ListEv e)
121 | row u n v = listRow ed.view u (n,v)
123 | ctrl : i -> Nat -> Prog e s (Cmd $
ListEv e)
124 | ctrl u n v = Change n <$$> ed.ctrl (li.rowID u n) v
126 | init : i -> Nat -> s -> Cmd (ListEv e)
127 | init u n v = Change n <$> ed.init (li.rowID u n) v
129 | adj : i -> Controller (ListEv e) (List (Nat,s))
131 | n <- map nextID get
132 | let s := ed.toState Nothing
133 | modify (insert li.mode n s)
134 | pure $
insertCmd li.mode (li.listID u) (row u n s) <+> init u n s
135 | adj u (Del n) = modify (del n) $> (removeElem $
li.rowID u n)
136 | adj u (Change n v) = stO (eqFirst n fst .> snd) (ctrl u n v)
139 | list1 : (empty : String) -> Editor i s e t -> List1Editor i s e t
142 | in E led.ctrl led.view led.init toN (toS led)
145 | toS : ListEditor i s e t -> Maybe (List1 t) -> List (Nat,s)
146 | toS _ Nothing = [(0,ed.toState Nothing)]
147 | toS led (Just vs) = led.toState (Just $
forget vs)
149 | toN : List (Nat,s) -> Either String (List1 t)
151 | case traverse (ed.stToNew . snd) ps of
152 | Left err => Left err
153 | Right (h::t) => Right (h:::t)
154 | Right [] => Left empty