Getting one automation to fire took two modals and two names: create the
automation, then create a separate trigger with a title the user has no use
for. The automation form now carries a "Runs on" selection and reconciles the
global triggers on save, so a working automation is one form away.
The triggers card stays for the cases it is actually good at, naming triggers
and pointing several at one automation, and says so.
Saving now spans two requests. A create that succeeds followed by a failed
trigger sync keeps the automation id, so retrying edits the automation rather
than creating a second one, and the form stays open with the partial state
reported rather than closing on a half-applied save.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpbLJVVT26tzWkduck1M9H
The list showed counts rather than meaning, and one column was mislabelled
"Trigger rule" while rendering the filter rule. The form buried the test and
delete actions inside four fixed grids, and the Test buttons discarded their
result entirely, so a failing output looked identical to a working one.
- list rows now say when an automation runs, what it sends, and flag the two
silent misconfigurations: an automation with no triggers and one with no outputs
- outputs and filters render as cards with a shared header, replacing the fixed
grids and the spacer hack used to fake a label-height cell
- test results are reported inline, keyed by field array id so removing an
output cannot leave feedback on the wrong row
- filters gain a plain language summary, and the filter rule only shows when
there is more than one filter to combine
- lifecycle labels are shared with the rundown event editor, which was showing
raw enum values, and it now shows what the linked automation sends
- triggers pointing at a deleted automation say so instead of rendering an
empty tag; the duplicates warning describes what actually happens
not_contains stays out of the operator list: the type and the runtime support
it but the server validation list omits it, so it cannot be saved.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpbLJVVT26tzWkduck1M9H
Surface {{groupNow.*}} template variables (title, note, colour, times,
custom fields) in the automation template autocomplete so events inside a
group can reference their group. The runtime store already carries
groupNow, so substitution and filters worked already; this makes it
discoverable.
Extend the message-secondary action with an optional text field so an
automation can set the secondary message content, not just its source.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LZYPZVdZLWowU7DyzGkWyy
* feat: create the first event from the cuesheet
* chore: cleanup css
* test: cuesheet beckground edit from empty state
* feat: only show +event button when user is in edit mode and have full write perms
* refactor: allow secondary rundowns
* ui: move dropdown
* feat: follow loaded
* ui: background edit warning
ui: fix disable radio button
* feat(ui): add loaded sufix in the rundown list
* feat(ui): add direct link to background edit from rundown manager
* fix: better fallback
* fix: default to is isCurrentRundown for nav bar colour
* chore: rename navigate to cuesheet
---------
Co-authored-by: alex-arc <ac@omnivox.dk>
* fix: prevent add filter from submitting form
* refactor: event clarifies whether automations exist but are disabled
* refactor: improve readability of automation form
* refactor: add affordance for field warnings
* refactor: improve visibility of automation off state
* refactor: apply warning styles to other feature toggles
* Adding playback actions to automations (#2024)
* adding intial automation actions
* cleaning up
* fixing formatting
* ran oxfmt
* switching action names to playback- to match the dropdown strings
* fixing flicker that was caused by scroll arrows gettting unmounted
---------
Co-authored-by: Cameron Slipp <cdslipp@gmail.com>
* chore: migrate eslint to oxlint
* chore: migrate prettier to oxfmt
* chore: migrate typescript
* chore: toThrow should have a expected value
* chore: cast test value as Day
* chore: small title fix
* chore: mocks should be hoisted
* chore: incorrect async useage
* chore: test should be inside description
* chore: test sohuld include an expeced
* chore: oxfmt
---------
Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
* feat: get server port from app satate or env
optional startup port from env will always override
function for parsing port from env
populate default port in app state
add test for migration
* bump version