Skip to main content

DataGrid

Struct DataGrid 

Source
pub struct DataGrid<E: Model> { /* private fields */ }
Expand description

Data grid. Its data source is an action that takes a DataQuery and returns Page<E>.

Example:

ⓘ
DataGrid::of(search_products).column(Product::code).width(120).filter()

Implementations§

Source§

impl<E: Model> DataGrid<E>

Source

pub fn of<A>(_source: A) -> Self
where A: Action<Input = DataQuery, Output = Result<Page<E>>>,

DataGrid that loads its rows from the given action.

Source

pub fn group_by<T: FieldType>(self, field: Field<E, T>) -> Self

Groups rows by field on the server; call again to group inside each group. The grid shows a header row per group with its value, row count and the column totals over the group, and loads a group’s rows (or subgroups) when the user opens it, a page at a time. The top level pages over groups. The grid’s action answers DataQuery::group with Page::groups; DataQuery::apply does it for in memory data. Virtual grids do not group. Masked fields never group a grid, because a group shows its value: such a call is ignored and logged.

Source

pub fn tree<K: FieldType>(self, parent: Field<E, Option<K>>) -> Self
where Option<K>: FieldType,

Shows rows as a tree by their parent key: rows whose parent is empty at the top, and the children of a row loaded when the user opens it, a page at a time, to any depth (at most [MAX_TREE_DEPTH]). The parent field must be optional; empty means a top row. Filters and sorting apply at every level, totals cover every matching row. Tree grids do not group and show no row details; virtual grids show no tree.

Source

pub fn detail<S: ScreenDef>( self, detail: impl Fn(&E) -> (S, S::Params) + Send + Sync + 'static, ) -> Self

Lets every row expand into a screen built from the row, loaded only when the user opens it: .detail(|o: &Order| (order_lines, OrderParams { id: o.id })). Params of the wrong type do not compile. The detail can hold anything a screen holds, such as another grid with its own detail, to any depth. The expander shows only for users who may open the screen, and the server checks the screen’s permission again when it loads, as for any screen. The params travel through the browser like a window’s, so the detail screen checks that the user may see the record they name.

Virtual grids (Paging::Virtual) keep every row at one fixed height and show no expander; use pages or infinite paging for grids with details.

Source

pub fn sort_by<T: FieldType>(self, field: Field<E, T>, desc: bool) -> Self

The order rows come in before the user sorts: .sort_by(Order::id, true) for newest first. The header shows it, and clicking that column only switches between ascending and descending; other columns go back to this order on their third click. Call it again to add further keys. The action still receives it in DataQuery::sort.

Source

pub fn scope<T: FieldType>(self, field: Field<E, T>, value: T) -> Self

Keeps only the rows whose field equals value, on every request, whatever the client sends: .scope(OrderLine::order_id, params.id) for the lines of one order. The filter goes first in DataQuery::filters, so a data layer that reads the filters keeps it. Text compares ignoring case.

Source

pub fn exportable(self) -> Self

Lets users export every row that matches their filters as CSV, in their column layout and language. The server pages through the grid’s action and streams the file, up to DEFAULT_EXPORT_LIMIT rows. Exporting needs the grid’s read access. The toolbar’s Export::Csv button uses this export when the grid has it.

Source

pub fn export_permission(self, permission: &'static str) -> Self

Like exportable, but exporting also needs permission.

Source

pub fn export_limit(self, rows: usize) -> Self

Most rows one export may hold; bigger results are cut there. At most 1,000,000.

Source

pub fn edit_with<A>(self, _save: A) -> Self
where A: FormAction<E> + Action<Input = Valid<E>>, A::Output: Outcome,

Lets users edit cells of the columns marked editable() in place, saved with save, an action that takes Valid<E> like a form’s. The server loads the row again by key, applies only the editable columns and the row version (#[version]) the client sends, validates and runs the action; a changed row comes back as a conflict. F2 or a double click on an editable cell starts editing, Enter saves, Escape cancels, Ctrl+Z undoes the last save.

Source

pub fn row_menu( self, menu: impl Fn(&E) -> ContextMenu + Send + Sync + 'static, ) -> Self

Context menu of each row, built on the server from the row. Right click, Shift+F10 or the context menu key opens it. See crate::ContextMenu.

Source

pub fn auto<A>(source: A) -> Self
where A: Action<Input = DataQuery, Output = Result<Page<E>>>,

DataGrid with a column for every field of the model except the row version, in declaration order, and filter boxes on text and choice columns. The quickest list for a simple model.

Source

pub fn mode(self, mode: DataMode) -> Self

Source

pub fn paging(self, paging: Paging) -> Self

Paging style. Numbered pages of 50 rows unless set.

Source

pub fn column<T: FieldType + 'static>( self, field: Field<E, T>, ) -> DataGridColumn<E, T>

Adds a column. The following settings (width, filter…) apply to it.

Source

pub fn row_style( self, style: impl Fn(&E) -> Option<RowStyle> + Send + Sync + 'static, ) -> Self

Picks a highlight per row.

Source

pub fn on_open( self, open: impl Fn(&E) -> Effect + Send + Sync + 'static, ) -> Self

What happens when a row is opened (double click or Enter).

Source

pub fn row_action<A>( self, label: impl Into<Text>, _action: A, input: impl Fn(&E) -> A::Input + Send + Sync + 'static, ) -> Self
where A: Action, A::Output: Outcome,

Adds a button to every row that runs action with input built from the row: .row_action(t!("stock.archive"), archive_product, |p| p.id). The button only shows for users with the action’s permission. When pressed, the server loads the row again by its key through the grid’s action, builds the input from it, checks the permission again and runs the action; the client never sends the input.

Source

pub fn selectable(self) -> Self

Adds a checkbox to every row and a selection bar above the grid. Shift selects a range, the header box selects the page, and the bar offers every row that matches the filters.

Source

pub fn bulk_action<A, K>( self, label: impl Into<Text>, _action: A, _key: Field<E, K>, ) -> Self
where A: BulkAction<K> + Action<Input = Vec<K>>, A::Output: Outcome, K: DeserializeOwned + Send + 'static,

Adds a button to the selection bar that runs action with the keys of the selected rows: .bulk_action(t!("stock.archive"), archive_products, Product::id) where archive_products takes Vec<ProductId>. Makes the grid selectable. The button shows only for users with the action’s permission, which the server checks again. When the user picks every matching row, the server collects the keys itself (at most MAX_BULK). Keys picked one by one come from the client, so the action must check that the user may change each record, as an API action would.

Source

pub fn icon(self, icon: Icon) -> Self

Icon of the last added row action.

Source

pub fn open_effect(&self, row: &E) -> Option<Effect>

Effect produced when the row is opened.

Source

pub fn rows_html(&self, rows: &[E]) -> String

Renders rows as HTML in English. For tests and tools; the server uses the user’s language.

Trait Implementations§

Source§

impl<E: Model> Component for DataGrid<E>

Source§

fn render(&self, out: &mut String, r: &Render<'_>)

Source§

fn schema(&self) -> Value

Schema used by MCP tools and test generation. Include a "type" key.
Source§

fn grid(&self) -> Option<&dyn GridSource>

Source§

fn form(&self) -> Option<&dyn FormSource>

Source§

fn reveal(&self, _field: &str) -> Option<Revealed>

The raw value of a masked field this component shows, for an audited reveal. The server checks the unmask permission before sending it.
Source§

fn import(&self) -> Option<&dyn ImportSource>

CSV import, for components that import rows (see crate::Import).
Source§

fn children(&self) -> &[Node]

Nodes held by a container. Child i of the node at path p has the path p.i.
Source§

fn eager_children(&self) -> &[Node]

Children rendered with the page. Others, such as closed lazy tabs, load when first shown.
Source§

fn source(&self, _key: &str) -> Option<&dyn DataSource>

Data the component fetches through an action, by key (a field name for lookups).
Source§

fn shortcuts(&self) -> Vec<&str>

Keyboard shortcuts of the component’s own links, as declared, for the clash checks of App::check and App::check_page.
Source§

impl<E: Model> From<DataGrid<E>> for Node

Source§

fn from(g: DataGrid<E>) -> Self

Converts to this type from the input type.
Source§

impl<E: Model, T> From<DataGridColumn<E, T>> for DataGrid<E>

Source§

fn from(c: DataGridColumn<E, T>) -> Self

Converts to this type from the input type.
Source§

impl<E: Model> GridSource for DataGrid<E>

Source§

fn reveal( &self, ctx: Ctx, key: String, field: String, ) -> BoxFuture<Result<Option<Revealed>>>

Reveals a masked column of one row. The row is loaded like a row action’s, through the grid’s scope, so only rows the grid shows can be revealed.

Source§

fn action(&self) -> ActionMeta

Source§

fn first_query(&self, view: Option<&DataGridView>) -> DataQuery

Query for the first page, as the grid’s paging asks for it, with the sort and filters of a saved view.
Source§

fn clean_view(&self, view: DataGridView) -> DataGridView

Cleans a view sent by a client so only the grid’s own columns, sort keys and filters remain.
Source§

fn head_html(&self, r: &Render<'_>, view: Option<&DataGridView>) -> String

Header row for a view.
Source§

fn find_row(&self, ctx: Ctx, key: String) -> BoxFuture<Result<LoadedPage>>

Loads the row with this key through the grid’s own action. The result holds at most the rows the action returned for a key filter; GridSource::row_call picks the matching one.
Source§

fn bulk_call(&self, index: usize, keys: Vec<Value>) -> Option<RowCall>

Call of bulk action index with these keys; None when there is no such action or a key does not read as the key type.
Source§

fn bulk_meta(&self, index: usize) -> Option<ActionMeta>

Access rule of bulk action index.
Source§

fn key_json(&self, key: &str) -> Option<Value>

A row key from the client as JSON of the key’s type; None when it cannot be read.
Source§

fn page_keys(&self, page: &LoadedPage) -> Vec<Value>

Keys of the rows of a loaded page, in order.
Source§

fn export_access(&self) -> Option<Access>

Who may export the whole filtered result; None when the grid offers no export.
Source§

fn export_limit(&self) -> usize

Most rows one export may hold.
Source§

fn csv_head(&self, r: &Render<'_>, view: Option<&DataGridView>) -> String

Header line of a CSV export in a view, with the user’s labels.
Source§

fn csv_rows(&self, page: &LoadedPage, r: &Render<'_>) -> String

CSV lines of a loaded page in its view: values as the user reads them, in the user’s language, with spreadsheet formulas defused.
Source§

fn export_columns( &self, r: &Render<'_>, view: Option<&DataGridView>, ) -> Vec<ExportColumn>

Columns of a typed export (XLSX) in a view: labels in the user’s language and widths.
Source§

fn export_text(&self, page: &LoadedPage, r: &Render<'_>) -> Vec<Vec<String>>

Cells of a loaded page in its view as the user reads them, for printed exports (PDF).
Source§

fn export_values(&self, page: &LoadedPage, r: &Render<'_>) -> Vec<Vec<Value>>

Typed values of a loaded page in its view, one row per item: choices as the user’s labels and exact moments as wall clock time in the user’s time zone. Everything else keeps its type.
Source§

fn edit_call( &self, page: &LoadedPage, key: &str, values: &Map<String, Value>, locale: &str, tz: TimeZone, ) -> Result<RowCall>

Builds the save of an inline edit of the row with this key from the loaded page: only editable columns and the row version may be in values, otherwise Forbidden; values are read and validated as a form would (Validation errors name the fields).
Source§

fn row_html( &self, page: &LoadedPage, key: &str, r: &Render<'_>, ) -> Option<String>

The row with this key from a loaded page as HTML, in the page’s view.
Source§

fn row_call(&self, page: &LoadedPage, key: &str, item: &str) -> Option<RowCall>

Builds the call of a row item (a0 for the first row action) from the loaded row with this key. None when the row is not there or the item does not exist for it.
Source§

fn fetch(&self, ctx: Ctx, query: DataQuery) -> BoxFuture<Result<LoadedPage>>

Source§

fn fetch_at( &self, ctx: Ctx, query: DataQuery, path: Vec<Option<String>>, ) -> BoxFuture<Result<LoadedPage>>

Loads rows as the user sees them: in a grouped or tree grid, the groups or rows under path (group values or ancestor keys from the client, checked here). Flat grids ignore path. Exports and bulk actions use GridSource::fetch, which never groups.
Source§

fn rows_html(&self, page: &LoadedPage, r: &Render<'_>) -> String

Rows of a loaded page as HTML.
Source§

fn render_loaded(&self, out: &mut String, r: &Render<'_>, page: &LoadedPage)

Renders the grid with its first page already in place.
Source§

fn foot_html(&self, page: &LoadedPage, r: &Render<'_>) -> Option<String>

Footer row with the totals of a loaded page, or None when the grid has no totals or the page carries none (the client keeps the footer it has).
Source§

fn fields(&self) -> &'static [FieldMeta]

Fields of the row model. Used to keep searches off masked fields.
Source§

fn sensitive_model(&self) -> Option<&'static str>

Name of the row model when it is #[sensitive], so exports are audited.
Source§

fn tool_schema(&self) -> Value

JSON Schema of the query, for agent tools.

Auto Trait Implementations§

§

impl<E> !RefUnwindSafe for DataGrid<E>

§

impl<E> !UnwindSafe for DataGrid<E>

§

impl<E> Freeze for DataGrid<E>
where fn(Ctx, DataQuery) -> Pin<Box<dyn Future<Output = Result<Page<E>, Error>> + Send>>: Freeze, Vec<Column<E>>: Freeze, Option<Box<dyn Fn(&E) -> Option<RowStyle> + Sync + Send>>: Freeze, Option<Box<dyn Fn(&E) -> Effect + Sync + Send>>: Freeze, Vec<RowAction<E>>: Freeze, Option<Box<dyn Fn(&E) -> ContextMenu + Sync + Send>>: Freeze, Option<SaveDef<E>>: Freeze, Option<DetailDef<E>>: Freeze,

§

impl<E> Send for DataGrid<E>
where fn(Ctx, DataQuery) -> Pin<Box<dyn Future<Output = Result<Page<E>, Error>> + Send>>: Send, Vec<Column<E>>: Send, Option<Box<dyn Fn(&E) -> Option<RowStyle> + Sync + Send>>: Send, Option<Box<dyn Fn(&E) -> Effect + Sync + Send>>: Send, Vec<RowAction<E>>: Send, Option<Box<dyn Fn(&E) -> ContextMenu + Sync + Send>>: Send, Option<SaveDef<E>>: Send, Option<DetailDef<E>>: Send,

§

impl<E> Sync for DataGrid<E>
where fn(Ctx, DataQuery) -> Pin<Box<dyn Future<Output = Result<Page<E>, Error>> + Send>>: Sync, Vec<Column<E>>: Sync, Option<Box<dyn Fn(&E) -> Option<RowStyle> + Sync + Send>>: Sync, Option<Box<dyn Fn(&E) -> Effect + Sync + Send>>: Sync, Vec<RowAction<E>>: Sync, Option<Box<dyn Fn(&E) -> ContextMenu + Sync + Send>>: Sync, Option<SaveDef<E>>: Sync, Option<DetailDef<E>>: Sync,

§

impl<E> Unpin for DataGrid<E>
where fn(Ctx, DataQuery) -> Pin<Box<dyn Future<Output = Result<Page<E>, Error>> + Send>>: Unpin, Vec<Column<E>>: Unpin, Option<Box<dyn Fn(&E) -> Option<RowStyle> + Sync + Send>>: Unpin, Option<Box<dyn Fn(&E) -> Effect + Sync + Send>>: Unpin, Vec<RowAction<E>>: Unpin, Option<Box<dyn Fn(&E) -> ContextMenu + Sync + Send>>: Unpin, Option<SaveDef<E>>: Unpin, Option<DetailDef<E>>: Unpin,

§

impl<E> UnsafeUnpin for DataGrid<E>
where fn(Ctx, DataQuery) -> Pin<Box<dyn Future<Output = Result<Page<E>, Error>> + Send>>: UnsafeUnpin, Vec<Column<E>>: UnsafeUnpin, Option<Box<dyn Fn(&E) -> Option<RowStyle> + Sync + Send>>: UnsafeUnpin, Option<Box<dyn Fn(&E) -> Effect + Sync + Send>>: UnsafeUnpin, Vec<RowAction<E>>: UnsafeUnpin, Option<Box<dyn Fn(&E) -> ContextMenu + Sync + Send>>: UnsafeUnpin, Option<SaveDef<E>>: UnsafeUnpin, Option<DetailDef<E>>: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more