Skip to main content

HeaderAction

Trait HeaderAction 

Source
pub trait HeaderAction: 'static {
    type Input: FormInput;

    const NAME: &'static str;
    const CONFIRM: bool = false;

    // Required method
    fn run(
        cx: &Cx,
        input: Self::Input,
        ex: &mut dyn Executor,
    ) -> impl Future<Output = Result<Outcome, WriteError>> + Send;

    // Provided methods
    fn label(cx: &Cx) -> String { ... }
    fn can_run(_cx: &Cx) -> bool { ... }
    fn validate_input(_cx: &Cx, _input: &Self::Input) -> FieldErrors { ... }
    fn success(cx: &Cx) -> String { ... }
}
Expand description

A mutation that acts on no record, run from a button in a page’s header: “import posts”, “clear the cache”, “recompute the totals”.

A resource declares one with ResourceDef::header_action, and its list page renders the button; a Page declares one with PageDef::header_action, and renders the buttons with header_action_buttons:

struct RecountTags;

impl HeaderAction for RecountTags {
    type Input = ();
    const NAME: &'static str = "recount-tags";

    async fn run(
        _cx: &Cx,
        _: (),
        _ex: &mut dyn Executor,
    ) -> Result<tablo_core::Outcome, tablo_core::WriteError> {
        // Recount through `ex`, the framework's transaction.
        Ok(tablo_core::Outcome::done())
    }
}

The framework owns everything around run, as it does for a record’s Action:

  • the route, {url}/-/actions/{NAME} under the list or page URL, and its CSRF check;
  • who may run it: on a resource, the policy’s Ability::ViewAny and Ability::RunHeader with the action’s NAME; on a page, PageDef::access; on either, then can_run. A refusal answers 403 and renders no button;
  • the transaction: run writes through its executor, and an error rolls everything back;
  • on a resource, the hooks, with Change::HeaderAction: Resource::before_commit in the transaction after run, then Resource::after_commit once it commits;
  • the success notification, and the redirect back to the list as it was left, its search, sort and filters kept, or to the page.

No record is loaded, so nothing scopes run to the request’s tenant: an action over a tenant’s records reads them through scoped_query.

An action that asks for an Input asks for it as a record’s action does, in a dialog or a page titled with its label, and runs on its submit.

Required Associated Constants§

Source

const NAME: &'static str

The action’s URL segment, distinct among the actions of its resource or page.

A name that is not a single path segment does not compile, as for Action::NAME.

Provided Associated Constants§

Source

const CONFIRM: bool = false

Whether the action asks first through a confirmation dialog with destructive wording. Defaults to false.

An action with input confirms in its input dialog, or on its input page, instead. An unconfirmed POST that would write answers 400.

Required Associated Types§

Source

type Input: FormInput

What the action asks for before it runs: () for nothing, or an FormInput struct.

Required Methods§

Source

fn run( cx: &Cx, input: Self::Input, ex: &mut dyn Executor, ) -> impl Future<Output = Result<Outcome, WriteError>> + Send

Perform the action with the parsed input, through the framework’s transaction ex, and say what the response does once it commits: Outcome::done for the success notification, landing back on the list or page.

Refuses the input with WriteError::Refused, as Action::run does.

Provided Methods§

Source

fn label(cx: &Cx) -> String

The button text. Defaults to the message action-{NAME} of the panel’s catalogs, else NAME in sentence case: "recount-tags" reads “Recount tags”.

Source

fn can_run(_cx: &Cx) -> bool

Whether the request may run the action, beyond the policy or the page’s access: a feature flag, a role the policy does not model. Defaults to true.

Source

fn validate_input(_cx: &Cx, _input: &Self::Input) -> FieldErrors

Refuse an input run should not receive. Each error names an input field’s key and renders under its control. Defaults to none. A key no control renders is a declaration error: the page would show no message.

Source

fn success(cx: &Cx) -> String

The success notification after a commit. Defaults to the label: "Recount tags: done".

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§