Repository navigation
2.2.0
Fixed: the header actions were glued together
ButtonGroup is a segmented control in Statamic — one border around everything, dividers instead
of gaps. Right for the list/grid switch, wrong for a header's actions: "All events" had no button
of its own and the primary button sat flush against the "…" menu. The actions are siblings in the
header slot now, the way Events/Index.vue and core's own headers do it.
Fixed: two tests asserted an order the query never promised
The status breakdown is sorted by count, descending, and says nothing about rows that tie. SQLite
and MySQL break a tie differently, so the suite was green locally and red on CI. The tests now
check what is actually guaranteed — the figures, and that they never rise — which is more than
they checked before. A deterministic tie-break belongs in TableMetric::splitByColumn of
statamic-insights, which thirteen addons carry byte for byte; that is its own ticket.
Pint also tripped over tests/Fakes/insights-contracts.php. All three pinned copies are excluded
now, not just one.
Changed: an event's dates are a Statamic table now
The dates on an event's screen were a stack of blocks with the actions written out as text links
underneath each one. Five dates filled the panel, nothing could be sorted, nothing could be picked,
and it did not look like any other screen in the Control Panel. They are core's <Listing> now, in
its client-side mode: the dates arrive complete as an Inertia prop, so there is no new route and
nothing to page through.
Four columns — the window, the timezone, the location and the status — with sortable headers, a
checkbox column and a … menu per row. Nothing that was on screen before has gone: the all-day
badge sits beside the window, the timezone and the location are columns of their own, and a
cancelled date says so in the status column instead of a red pill in the corner.
The window no longer repeats the date on the end of a same-day event. Tue, 15 Sep 2026 19:00 – 21:30, not the same date twice, which in a column costs exactly the width the location needs.
Changed: cancelling and deleting a date are registered actions
They were two buttons per row, each with a hand-built confirmation modal, and they only ever worked
on one date. They are Statamic\Actions\Action classes now, which is what earns the listing its
checkbox column: the same action runs from a single row's … menu and from the bulk bar over a
whole selection, through POST cp/events/occurrences/actions, with core's confirmation, core's
toast and core's authorization.
Neither action declares a redirect(), and that is deliberate. A redirect looks like the obvious way
to get a client-side listing to show the new state, and it silently costs the success message: core's
ActionController::run() returns from the redirect branch before it reads what the action returned,
so the front end falls back to toasting its own "Action completed". The screen refreshes through the
listing's refreshing event instead, which is what Events/Index.vue already does.
Removed with them: POST cp/events/occurrences/{occurrence}/cancel and
DELETE cp/events/occurrences/{occurrence}, along with OccurrenceController::cancel() and
::destroy(). They existed to serve the buttons and had no caller left. Control Panel routes are
not part of this package's public API (see the note at the top); the Antlers tags, the config keys
and the facade are untouched.
An id a selection carries that the brand scope does not reach is now a 404 rather than a shrunken
selection. Core decides which actions apply by comparing counts, so an empty collection satisfies
every action registered in the Control Panel — verified in the playground, where one foreign-brand
id came back with core's asset actions and a 500.
Fixed: the event screen no longer borrows another addon's stylesheet
The two panels sat side by side through a pair of responsive grid classes that Statamic core does
not emit. They came from statamic-marketing and statamic-clientrooms, so the layout only ever
appeared on an installation that happened to carry one of them; on its own this addon fell back to a
stacked page.
They stack on purpose now, and the reason is the table rather than the missing classes — side by
side is buildable with classes core does emit. Measured: the table needs 988px, two thirds of a
detail screen gives it 739, and the … column then sits 242px outside the visible area, reachable
only by scrolling the table sideways. Stacked it gets 1128.
The location column keeps one line per row, the way core's listings do. Letting an address wrap put
every row at 125px on a 390px screen where core's collections listing sits at 49-65 — and the table
scrolled sideways anyway. Rows are 47px now at both widths.