When the project page's task list shows its controls — the Active / Done / All lens and the sort dropdown.
Max, 2026-09-05: "by default we don't need to show them if there aren't multiple statuses, and with fewer than ten tasks there is no reason to show them either — but we should be able to control all of this via the settings." So:
:auto(default) — the controls appear only when they can change what is on screen: the project has tasks on BOTH sides of the lens (some active, some done) AND at leastthresholdtasks. Under the rule the list shows every task in manual order, which is also what lets drag-reordering work on a small project without a detour through the All lens.:always— the controls are always there.:never— never.
Site-wide PhoenixKit.Settings keys, configured on
/admin/settings/projects; validated on the way in so a malformed
value resolves to the default.
Summary
Functions
Allowed mode strings, for the settings form.
Persist the mode (one of modes/0); anything else is ignored.
Persist the task threshold, clamped to threshold_range/0; non-numbers are ignored.
The current settings (validated; defaults when unset or malformed).
Restore both settings to their defaults.
Whether the controls show for a list with counts (%{active, done, total}, the full project's numbers — never the visible slice).
Bounds for the task threshold, for the settings form.
Types
@type mode() :: :auto | :always | :never
@type settings() :: %{mode: mode(), threshold: pos_integer()}
Functions
@spec modes() :: [String.t()]
Allowed mode strings, for the settings form.
Persist the mode (one of modes/0); anything else is ignored.
Persist the task threshold, clamped to threshold_range/0; non-numbers are ignored.
@spec read() :: settings()
The current settings (validated; defaults when unset or malformed).
@spec reset() :: :ok
Restore both settings to their defaults.
@spec show?(settings(), %{ active: non_neg_integer(), done: non_neg_integer(), total: non_neg_integer() }) :: boolean()
Whether the controls show for a list with counts (%{active, done, total}, the full project's numbers — never the visible slice).
@spec threshold_range() :: {pos_integer(), pos_integer()}
Bounds for the task threshold, for the settings form.