Catalogue — the Jobs page
The Jobs page is Nomaflow's home. It opens by default when you click Nomaflow in the top navigation and lists every declared job — scheduled or manual-only, enabled or paused.
This page covers what each piece does, what the actions trigger, and how the Run-with-parameters modal lets operators override a fire without editing the job definition.
Page layout
The page is one card per job. The catalogue is sorted alphabetically by id; there's no manual ordering — let the id and tags do that work.
The toolbar
| Action | What it does |
|---|---|
| + New Job | Opens the Job editor on a blank job (/nomaflow/jobs/new). |
| 📅 Schedule view | Opens the Schedules page — a calendar of upcoming fires across every job. |
| ↻ Reload | Re-fetches the catalogue. Use after editing TOML on disk if your install allows that path. |
What's on a job card
Every card carries the same nine pieces:
| Piece | Where on the card | Meaning |
|---|---|---|
| Id | Top-left, monospace. | The job's identifier. Click anywhere in the row title to view its details. |
| Last-run badge | After the id. | Coloured pill (SUCCEEDED, FAILED, RUNNING, CANCELED). Click it → opens the Run detail for that run. |
| Tags | After the badge. | Free labels from the job definition — etl, nightly, legal. |
| Enabled toggle | Top-right. | Green when on. Clicking flips the job's enabled flag and reloads the scheduler. Shows a spinner while saving — it's a real save, not optimistic. |
| Description | Below the title row. | Free text from the job definition. |
| Schedule chip | Meta row, with a ⏱ icon. | Cron expression in monospace, or manual-only if no schedule. |
| Next-run hint | Meta row, with a 📅 icon. | Relative time until the next fire (in 14 m). Hover for the absolute timestamp. |
| Last-run hint | Meta row. | Relative time since the last finish. |
| Step count | Meta row. | How many steps the job carries. |
The Actions row below carries ▶ Run now, ✕ Cancel (only when a run is in flight) and ✎ Edit.
Enable / disable
The enabled toggle in the top-right of each card controls whether the scheduler honours the job's cron. The behaviours:
| State | Cron fires? | Manual ▶ Run still works? |
|---|---|---|
| Enabled | Yes — every cron match creates a run. | Yes. |
| Disabled | No — the scheduler skips this job. | Yes — operators can still trigger manually. |
The toggle is not an optimistic flip: clicking it writes back the saved job configuration with the new value and triggers a scheduler reload. The button shows a spinner while that round-trip finishes — typically under a second, but the spinner is honest about what's happening.
A common pattern: freeze a job during a maintenance window by disabling it, then re-enable when the system is back. The job's history is preserved; only the auto-fires stop.
▶ Run now
Clicking Run now triggers a fire of the job, on top of any schedule. What happens next depends on what the job carries:
| Situation | What happens |
|---|---|
| Single-step job with no params and no op_kwargs. | The job fires immediately. The card transitions to RUNNING. |
| Job has shared params or any Python step has op_kwargs or more than one step. | The Run-with-parameters modal opens. |
| A run is already in flight for this job. | The button is disabled — one run at a time per job. |
The trigger source on the resulting run is user:<your-account> — visible on the Run detail page and used for the audit trail.
Cancel a run
When a job's last_run state is RUNNING, a ✕ Cancel button appears in the actions row. Clicking it sends a cancellation signal to the runner:
- The current step receives a cancellation request — what happens next depends on the step type:
- SQL steps: the underlying connection is closed; the database transaction rolls back.
- Python steps: the asyncio task is cancelled; in-flight
awaitcalls raiseCancelledError. - HTTP / LDAP steps: the network call is aborted.
- The remaining steps do not run.
- The run state moves to
CANCELED.
Cancellation is best-effort — a Python step that's blocked on a non-async call (a thread sleep, a blocking DB driver) only stops at its next checkpoint. Design long Python steps to check for cancellation periodically; the Custom Python guide covers the pattern.
Live updates
The catalogue polls every 2 seconds while any job is in flight, so:
- A job that's
RUNNINGwill transition to its terminal state without a manual reload. - A new run that fires from a cron will land on the card with its
RUNNINGbadge within ~2 seconds. - When nothing is in flight, polling stops to keep the page quiet.
If the page seems stale, hit ↻ Reload in the toolbar — it forces an immediate refresh.
Run with parameters
When you click ▶ Run now on a job that carries params, Python step op_kwargs or more than one step, the Run-with-parameters modal opens.
What's in the modal
| Section | What it shows |
|---|---|
| Log level | Dropdown: INFO or DEBUG. Seeded from the job's saved value. |
| Shared params | One row per key in the job's params block. Type-aware inputs (number / boolean / text / connector picker). Hidden when the job has no params. |
| Per-step section | One per step in the job. Each carries: the step name, an enabled checkbox, and (for Python steps) one row per op_kwarg. |
How it diffs
The modal only sends the diff — values you actually changed. Untouched fields fall back to the job's saved value. So clicking ▶ Run without changing anything fires the job exactly as if you'd done a quick ▶ Run now.
Connector pickers
Any kwarg whose key is connector or ends in _connector (e.g. source_connector, target_connector) renders as a search-select populated with the framework's connectors. Saves typos versus free-text — and lets you spot connector names you didn't know existed.
Per-step enable toggle
Every step has a checkbox. Unchecking it tells the runner to skip that step for this fire only:
- The step appears in the run history with a
CANCELEDstate and the reasonskipped: disabled. - The remaining steps still run.
This is the operator's escape hatch for chained jobs — re-run a job after fixing step 6's data without re-doing steps 1–5.
Use cases
| Pattern | How the modal helps |
|---|---|
| Test against a sandbox | Override target_connector to nomasx1-sandbox for one fire. |
| Back-fill a specific tenant | Override apps_id from the production default to the target tenant. |
| Re-run only the failing phase | Disable steps 1–5 (already done), keep step 6 enabled. |
| Debug a flaky step | Switch log_level to DEBUG for one fire to see the full SQL. |
Search and filter
The catalogue surfaces the job's id, description and tags in the card; the browser's Ctrl/Cmd+F finds anything quickly. There's no in-app search bar today — most installs have under 50 jobs and grep-via-browser is enough.
For installs with hundreds of jobs, consider:
- Naming jobs with a prefix convention (
nomajde-…,nomasx1-…,reporting-…). - Tagging by frequency (
hourly,daily,monthly) and by owner (team-data,team-security).
What's next
- Create a job — the full Job editor.
- Schedules — the cron syntax, the schedule view, calendar preview.
- Runs → History — clicking a last-run badge takes you here.
- Notifications — Slack / email / webhook on success or failure.