pub trait HeaderAction: 'static {
type Input: FormInput;
const NAME: &'static str;
const CONFIRM: bool = false;
const ICON: Option<IconData> = None;
const COLOR: Color = Color::Gray;
// Required method
fn run(
cx: &Cx,
input: Self::Input,
ex: &mut dyn Executor,
) -> impl Future<Output = Result<Outcome, WriteError<<Self::Input as FormInput>::Field>>> + Send;
// Provided methods
fn confirmation() -> Text { ... }
fn label() -> Text { ... }
fn can_run(_cx: &Cx) -> bool { ... }
fn validate_input(
_cx: &Cx,
_input: &Self::Input,
) -> FieldErrors<<Self::Input as FormInput>::Field> { ... }
fn success() -> Text { ... }
}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<std::convert::Infallible>> {
// 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::ViewAnyandAbility::RunHeaderwith the action’sNAME; on a page,PageDef::access; on either, thencan_run. A refusal answers 403 and renders no button; - the transaction:
runwrites through its executor, and an error rolls everything back; - on a resource, the hooks, with
Change::HeaderAction:Resource::before_commitin the transaction afterrun, thenResource::after_commitonce 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§
Sourceconst NAME: &'static str
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§
Sourceconst CONFIRM: bool = false
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.
Sourceconst COLOR: Color = Color::Gray
const COLOR: Color = Color::Gray
The colour the button is tinted in, as Delete’s is in Color::Danger. Defaults to
Color::Gray, the untinted button.
It changes how the button looks, not what it asks: CONFIRM asks first.
Required Associated Types§
Required Methods§
Sourcefn run(
cx: &Cx,
input: Self::Input,
ex: &mut dyn Executor,
) -> impl Future<Output = Result<Outcome, WriteError<<Self::Input as FormInput>::Field>>> + Send
fn run( cx: &Cx, input: Self::Input, ex: &mut dyn Executor, ) -> impl Future<Output = Result<Outcome, WriteError<<Self::Input as FormInput>::Field>>> + 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, or declines
with WriteError::declined, as
Action::run does.
Provided Methods§
Sourcefn confirmation() -> Text
fn confirmation() -> Text
The question the confirmation dialog asks when CONFIRM is set. Defaults
to the message tablo-confirm-run, “Run this action?”. An action with input confirms in
its input dialog instead, which its label titles.
Sourcefn label() -> Text
fn label() -> Text
The button text. Defaults to the message action-{NAME} of the panel’s catalogs, else
NAME in sentence case: "recount-tags" reads “Recount tags”.
Sourcefn can_run(_cx: &Cx) -> bool
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.
Sourcefn validate_input(
_cx: &Cx,
_input: &Self::Input,
) -> FieldErrors<<Self::Input as FormInput>::Field>
fn validate_input( _cx: &Cx, _input: &Self::Input, ) -> FieldErrors<<Self::Input as FormInput>::Field>
Refuse an input run should not receive. Each error names a field of the
input’s Field enum and renders under its control, as
Action::validate_input does. Defaults to none.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".