Pinia's `$patch()` function will merge the given state with the current
state, instead of doing a replacement. As a result, going from an active
job with metadata fields `A` and `B`, to a job with metadata fields `B`
and `C` would actually have fields `A`, `B`, and `C` in the Pinia store.
This is resolved by replacing the `$patch(object)` with `$patch(function)`
and having that function replace the entire job.
The selection mechanism of Tabulator was getting in the way of having nice
navigation, as it would deselect (i.e. nav to "/") before selecting the
next job (i.e. nav to "/jobs/{job-id}").
The active job is now determined by the URL and thus handled by Vue Router.
Clicking on a job simply navigates to its URL, which causes the reactive
system to load & display it.
It is still intended to get job selection for "mass actions", but that's
only possible after normal navigation is working well.
A wrapper for the generated `ApiClient` class tracks the number of running
queries. This makes it much simpler to show the "API calls pending" UI
element, regardless of which part of the webapp performs the queries.
For task scheduling this doesn't matter, but for human workflow it can be
useful to differentiate between "failed" (and should be retried) and
"cancelled" (no longer relevant).
Add a bar for "job actions", i.e. buttons that do something with the
selected job(s).
Just has one button, and it doesn't do much either, but at least the
framework for these things is here.