CRUD / foldkit-mixins-crud
Sorting, more, and special cells
ts
PostTable(
{
page: Posts.page(model),
onOpen: row => Message.OpenedPost({ id: row.id }),
onMore: Message.RequestedMorePosts(), // shown while the page has a next one
sort: {
title: {
direction: model.postSort === 'title' ? 'asc' : undefined,
message: Message.SortedPosts({ sort: 'title' }),
},
},
cells: {
published: (row, h) => h.span([h.Class(row.published ? 'live' : 'draft')], ['●']),
},
words: { yes: 'Live', no: 'Draft', empty: 'No posts yet.', more: 'Load more', retry: 'Reload' },
},
h,
)sort: PostSort.inputs(model.postSort, (_, column) => Message.SortedPosts({ column }))is the wholesortinput when the state is afoldkit-crudSort.- Sorting is state the application holds, as the query's input (see
foldkit-crud).sortnames the columns that sort, how each is sorted now, and the Message a click sends. The header becomes a button and the column carriesaria-sort. cellsdraws one column specially, and gets the whole row, so a link can use the id.renderersdraws every column of a Display kind, a shipped one or your own, in any list or detail:renderers: { Badge: ({ value, h, badge }) => h.span(badge.attrs(), [String(value)]) }.badgeis the list's (or detail's)badgeSlot, so what a renderer draws is styled like any other part. A column'scellsentry wins over its kind's renderer, and a kind with neither saysDisplay.show.wordsis text, with{message}a blank infailed; it shares no key with a form's words, so one object serves both.wordssupplies every word the view says itself, and the wordsDisplay.showuses (yes,no,nothing,separator), for wording and for translation.
A detail
ts
import { DetailView } from 'foldkit-mixins-crud'
const PostLines = DetailView.forMessages<Message>().define(PostDetail)
PostLines({ value: Shown.value(model) }, h) // Shown = PostDetail.at({ data, id })A dl with a dt per shown field and its value in a dd. It takes cells and
words as a list does.