CRUD / foldkit-crud
A first list
A list is one query and one Selection: the query decides which rows, the Selection what to show of each.
ts
const Authors = Crud.list('Authors', {
query: AuthorsQuery, // Query.make('Authors', { Input: { search }, Result: Query.connection(Blog.Author) })
selection: Entity.select(Blog.Author, { id: true, name: true }),
pageSize: 25,
// How a row reads as a choice, for a list that feeds relation pickers.
choice: { value: row => row.id, label: row => row.name },
})
const AuthorList = Authors.at({
data: Data,
// The query's input as the Model has it; none while the list is not shown.
input: model => Option.map(Option.fromNullOr(model.search), search => ({ search })),
})
const subscriptions = Data.subscriptions({ authors: AuthorList.active })What each call does:
Crud.listis a declaration: no request, no state.Authors.columnsis the selected members in the Selection's order, each with itskey,member, alabelfound the way a form finds one (the schema'stitle, elseForm.labelmetadata, else the key), and adisplay.Authors.atbinds it to your Remote domain and your Model. It still does no I/O.AuthorList.activeis the requirement: whileinputgives a value, the page and its rows are fetched and retained. Another input is another connection, fetched on its own.AuthorList.page(model)reads Remote's store: aRemoteDataof the page, withitemstyped by the Selection,hasNextandhasPrevious.AuthorList.more(model)is "load more": the Model with the list showing one page more, anOption, none when it already shows every row. Return it fromupdate(Option.getOrElse(AuthorList.more(model), () => model)); the read entry fetches the rows it lacks.AuthorList.refresh(model)is the Model with the list asked for again. A failed read is not retried on its own, so this is what a retry button's Message returns.
AuthorList.row(id) is a Projection of one row through the list's Selection,
whether or not the query finds it now, and AuthorList.choiceOf(model, id) is
that row as a choice once it is read. Relation pickers use both.
Wiring a page
Every placed piece has an active. Crud.actives gathers them from the pieces
themselves, so a page cannot forget one:
ts
Data.wiring(Crud.actives({ posts: Posts, authors: Authors, editor: PostEditor, pickers }))It takes a placed editor, list or detail, and the pickers from Crud.options,
and gives { posts: Posts.active, ... }, for Data.wiring in a
foldkit-bundle assembly, or for Data.subscriptions.