adamc@915: con colMeta' = fn (row :: Type) (t :: Type) => adamc@915: {Header : string, adamc@915: Project : row -> transaction t, adamc@915: Update : row -> t -> transaction row, adamc@915: Display : t -> xbody, adamc@915: Edit : t -> xbody, adamc@915: Validate : t -> signal bool} adamc@915: adamc@915: con colMeta = fn (row :: Type) (global_t :: (Type * Type)) => adamc@915: {Initialize : transaction global_t.1, adamc@915: Handlers : global_t.1 -> colMeta' row global_t.2} adamc@915: adamc@935: con aggregateMeta = fn (row :: Type) (acc :: Type) => adamc@935: {Initial : acc, adamc@935: Step : row -> acc -> acc, adamc@935: Display : acc -> xbody} adamc@935: adamc@915: functor Make(M : sig adamc@915: type row adamc@936: type key adamc@936: val keyOf : row -> key adamc@936: adamc@915: val list : transaction (list row) adamc@915: val new : transaction row adamc@936: val save : key -> row -> transaction unit adamc@936: val delete : key -> transaction unit adamc@915: adamc@915: con cols :: {(Type * Type)} adamc@915: val cols : $(map (colMeta row) cols) adamc@915: adamc@915: val folder : folder cols adamc@935: adamc@935: con aggregates :: {Type} adamc@935: val aggregates : $(map (aggregateMeta row) aggregates) adamc@937: val aggFolder : folder aggregates adamc@915: end) : sig adamc@915: type grid adamc@915: adamc@915: val grid : transaction grid adamc@915: val sync : grid -> transaction unit adamc@915: val render : grid -> xbody adamc@915: adamc@915: style tabl adamc@915: style tr adamc@915: style th adamc@915: style td adamc@915: end