Skip to content

Background import job: rounds show their import status (frontend) - #631

Open
lgelauff wants to merge 6 commits into
feat/import-workerfrom
feat/import-status-ui
Open

lgelauff wants to merge 6 commits into
feat/import-workerfrom
feat/import-status-ui

Conversation

@lgelauff

@lgelauff lgelauff commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator

Fixes #622 and, together with the worker PR #630, #621: the browser no longer waits for an import, and rounds show their import status. Based on #630, which must be merged and deployed first. Replaces the frontend half of #624.

What changes

  • Round creation (RoundNew.vue). In worker mode the dialog closes straight away with "Import started". For small imports it polls every 3 s for up to 60 s and then shows the usual result (warnings, disqualified files) or the failure reason; after that it says to refresh later. In sync mode the old flow is unchanged.
  • Round view (RoundInfo.vue, RoundImportStatus.vue). When the page loads it shows the import state: queued, running, finished (with counts and warnings) or failed (with the reason). It refetches when the state changes; there is no background polling.
  • Activate is disabled while the import is not finished, with a translated reason on its own line above the buttons.
  • Failed imports have Retry and Dismiss buttons.
  • Badges: the round header and the campaign cards show an import badge, only when activation is blocked.
  • Strings and dates:
    • All new strings are in en.json and qqq.json; no other locale files are touched.
    • Dates use the i18n locale.
    • A CSV warning that is a bare string is now shown whole, not just its last character.

Checks

  • npx prettier --check src/, npx eslint src/ --ext .vue,.js,.jsx,.cjs,.mjs and npm run build pass.
  • Checked by hand on montage-dev (the earlier combined branch): "Import started", the status panel, finished with counts, Activate disabled with its reason. The layout fix for that reason came from that test.
  • Deployed again on montage-dev on 2026-10-02 (integration branch, worker mode): imports, the import state in the round data, and Activate. Activate is also disabled while its own request runs (from Lock the round when activating it, so a double click can't create every task twice #626).
  • Not yet clicked through: Retry, Dismiss and the 60 s poll dialog.

Written with Claude (Claude Code) on behalf of @lgelauff.

🤖 Generated with Claude Code

lgelauff and others added 6 commits October 2, 2026 06:49
- RoundNew: after a queued import, close the form at once with
  "Import started; ... Refresh the page" (no waiting, no polling); the
  old result dialog stays for the sync rollback mode
- RoundImportStatus (new, in RoundInfo): queued since / running since /
  finished with counts and warnings / failed with the reason and the
  "cancel this round and create it again" hint; one details fetch on
  load, no polling
- RoundInfo: Activate disabled with the reason while the import blocks
  activation (state read from the campaign payload, so from first render)
- RoundView header and CoordinatorCampaignCard: "importing…" /
  "import failed" badge
- adminService.getImportJobs/getImportJob; utils.getImportBadgeKey,
  formatUtcDateTime (server dates are naive UTC)
- new strings in en.json + qqq.json only

Refs #622, #621

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RoundImportStatus fetched job details only on mount; a campaign reload
reuses the component, so a job that had just finished or failed showed
no warnings or reason until a full page reload. Watch job id + status
(immediate) instead.

Refs #622

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… blocked

The "cannot be activated yet" message sat in the same unwrapped flex row
as the action buttons, so they shrank and their labels were cut off
("Activat", "Finalize rou", ...). The message now takes its own line
above the buttons, the row can wrap, and the buttons don't shrink.

Seen on montage-dev with a queued import.

Refs #622

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Phase 2 of the background import job (#622, backend #621).

- Failed-import panel (RoundImportStatus): "Retry import" and "Dismiss"
  buttons while the round is paused (Dismiss hidden once dismissed), a
  "dismissed" note, and a new hint text replacing "cancel this round and
  create it again".
- Round creation (RoundNew): after the import is queued, poll the job
  every 3 s for at most 60 s (pollImportJob in utils.js; stopped on
  unmount or Cancel). A finished import shows the warnings/disqualified
  files dialog as before #621, a failed one its reason; otherwise the
  "import started, refresh later" message. The submit button stays
  disabled while polling. Dialog title/OK button are now translated.
- formatUtcDateTime uses the vue-i18n locale (falls back to the browser
  default for a code the browser rejects); string warnings are shown
  whole instead of their last character.
- CoordinatorCampaignCard: latest round and import badge are computed.
- en.json + qqq.json: new keys for the above.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the PR check of the import status UI:
- Cancel is disabled while the add-round/import request is in flight, and
  neither the poll nor the sync-mode result starts once the form has
  unmounted. Before, cancelling during the request started a poll nothing
  could stop, ending in a late toast or dialog on another page.
- Add round stays disabled until the import request has returned, so a
  second click can no longer create a second round.
- A failed import says "Import failed. Reason: ..." with a translated
  fallback instead of the raw error or hardcoded English.
- The "Importing files..." line is announced to screen readers.

Refs #622

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- R4-1: a failed import says "Import failed. Reason: {0}" with one
  translatable key instead of joining two translated strings; with no
  reason it shows the translated "Import failed".
- R4-3: the hint under a failed import promises activation only when
  the round has files. For an empty round it says the round cannot be
  activated and must be retried or recreated (the server refuses to
  activate an empty round, dismissed or not).
- R4-4: an "Importing files..." status line (role=status) is shown while
  the import request is in flight, in both modes. In sync mode the whole
  import runs inside that request; no poll is started there.
- Failed import request (sync error or timeout, refused enqueue,
  network): the round exists but is empty and has no job, so nothing
  offered to import into it. The form now stays open, says so, and
  Add round becomes "Retry import", which imports into the same round.
  Cancel closes the form and reloads the campaign. The file list is no
  longer split in place, so a retry sends it correctly.

Refs #622

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show "import in progress" instead of keeping the browser waiting, and show import status on rounds

1 participant