Skip to content

Show progress/status on evaluation tasks#7553

Merged
lucanovera merged 29 commits intomainfrom
ENG-2837-UI-Show-in-progress-evaluation-tasks-that-update-in-real-time
Mar 5, 2026
Merged

Show progress/status on evaluation tasks#7553
lucanovera merged 29 commits intomainfrom
ENG-2837-UI-Show-in-progress-evaluation-tasks-that-update-in-real-time

Conversation

@lucanovera
Copy link
Contributor

@lucanovera lucanovera commented Mar 3, 2026

Ticket ENG-2837

Description Of Changes

Add a progress and status indicator for evaluation tasks. It shows a progress percentage that updates when an evaluation task is in progress and a Notification when the task is done. If no task is in progress it will show when was the last time than an evaluation ran.

Code Changes

Steps to Confirm

  1. Enable alpha flag "Alpha data protection assessments"
  2. Go to assessments screen and click evaluate assessments
  3. Pick an assessment template, 2 or 3 systems and click Run evaluation
  4. You should be redirected to the assessment list screen and see a success message
  5. Next to the "Evaluate assessments" button there should be an indicator "Evaluation in progress · X%" that goes up as the evaluation runs.

Note: Nightly currently doesn't have this fix deployed so the progress percentage might not be reporting correctly, but you can still open the network tab to see the indicator polling the task statuses every 30s.

  1. If you reload the page you should still see the evaluation in progress indicator
  2. If you hover the indicator it should show a Popover with details like: the assessment count, status, types, systems (it will show system keys until the BE provides system names) and when the task started
  3. When the task is finish a Notification should appear that says "New assessment results are available" with an action button to reload results
  4. The indicator should now display "Last assessment X minutes ago"

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label to the entry if your change includes a high-risk change (i.e. potential for performance impact or unexpected regression) that should be flagged
    • Updates unreleased work already in Changelog, no new entry necessary
  • UX feedback:
    • All UX related changes have been reviewed by a designer
    • No UX review needed
  • Followup issues:
    • Followup issues created
    • No followup issues
  • Database migrations:
    • Ensure that your downrev is up to date with the latest revision on main
    • Ensure that your downgrade() migration is correct and works
      • If a downgrade migration is not possible for this change, please call this out in the PR description!
    • No migrations
  • Documentation:
    • Documentation complete, PR opened in fidesdocs
    • Documentation issue created in fidesdocs
    • If there are any new client scopes created as part of the pull request, remember to update public-facing documentation that references our scope registry
    • No documentation updates required

Summary by CodeRabbit

  • New Features

    • Real-time status indicator for privacy assessment evaluations with live progress, spinner, and estimated completion
    • Hoverable popover showing detailed task info (types, systems, timestamps)
    • Displays last completed or failed assessment with relative time and status tag
    • Completion notification with a Reload action to refresh results and an error notification when evaluations fail
    • Automatic polling while evaluations are in progress; indicator shown in the assessments page header
  • Changelog

    • Added changelog entry documenting the assessment task status feature

@vercel
Copy link
Contributor

vercel bot commented Mar 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fides-plus-nightly Ready Ready Preview, Comment Mar 5, 2026 3:43pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
fides-privacy-center Ignored Ignored Mar 5, 2026 3:43pm

Request Review

…in-progress-evaluation-tasks-that-update-in-real-time
@lucanovera lucanovera marked this pull request as ready for review March 4, 2026 13:34
@coderabbitai
Copy link

coderabbitai bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

Adds real-time privacy assessment task status: new API endpoints, types, utilities, two UI components that poll tasks, display inline status with a popover, and emit notifications (with optional reload) when tasks finish.

Changes

Cohort / File(s) Summary
Changelog
changelog/7553-assessment-task-status.yaml
New changelog entry describing the added real-time status indicator for privacy assessment evaluations.
API Core
clients/admin-ui/src/features/common/api.slice.ts
Added "Privacy Assessment Tasks" to RTK Query tagTypes.
Privacy Assessments API
clients/admin-ui/src/features/privacy-assessments/privacy-assessments.slice.ts
Added getAssessmentTasks and getAssessmentTask queries; createPrivacyAssessment invalidates "Privacy Assessment Tasks"; exported hooks useGetAssessmentTasksQuery, useGetAssessmentTaskQuery.
Types
clients/admin-ui/src/features/privacy-assessments/types.ts
Added TaskStatus enum, TaskSystem, AssessmentTaskResponse, and AssessmentTaskPage interfaces.
Utilities
clients/admin-ui/src/features/privacy-assessments/utils.ts
Added formatSystems and formatTypes helpers; updated imports to include AssessmentTaskResponse.
UI Components
clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx, clients/admin-ui/src/features/privacy-assessments/AssessmentTaskPopoverContent.tsx
New AssessmentTaskStatusIndicator (polls tasks, derives active/last task, maps templates, emits notifications, optional reload action) and AssessmentTaskPopoverContent (detailed popover for active/last tasks). Both exported.
Module Exports
clients/admin-ui/src/features/privacy-assessments/index.ts
Re-exported the two new components from the privacy-assessments index.
Page Integration
clients/admin-ui/src/pages/privacy-assessments/index.tsx
Integrated AssessmentTaskStatusIndicator into the page header and wired onTaskFinish to a refetch callback for assessments.

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as AssessmentTaskStatusIndicator
    participant API as PrivacyAssessmentsAPI
    participant Backend as BackendService

    User->>UI: mount
    UI->>API: getAssessmentTasks()
    API->>Backend: GET /assessment-tasks
    Backend-->>API: tasks list
    API-->>UI: tasks

    alt active task exists
        UI->>UI: start polling loop
        loop while active
            UI->>API: getAssessmentTasks() (poll)
            API->>Backend: GET /assessment-tasks
            Backend-->>API: updated status
            API-->>UI: updated tasks
            UI->>User: render spinner / progress
        end
        UI->>API: getAssessmentTemplates()
        API->>Backend: GET /assessment-templates
        Backend-->>API: templates
        API-->>UI: template names
        UI->>User: notify completion (optional Reload)
    else no active task
        alt last completed exists
            UI->>User: show last completion timestamp
        else
            UI->>User: show "No evaluation history"
        end
    end

    User->>UI: hover -> open popover
    UI->>API: fetch task details (if needed)
    API-->>UI: task details
    UI->>User: show AssessmentTaskPopoverContent
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • jpople

Poem

🐰 I hopped to check a task today,
Polling softly along the way,
Spinners spin and popovers sing,
A gentle ping when results take wing,
Reload, refresh — the updates stay. 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title clearly and concisely summarizes the main change: adding progress and status indicators for evaluation tasks.
Description check ✅ Passed The pull request description follows the template structure, includes ticket reference, clear description of changes, code changes list, comprehensive verification steps, and completed pre-merge checklist.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ENG-2837-UI-Show-in-progress-evaluation-tasks-that-update-in-real-time

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@clients/admin-ui/src/features/privacy-assessments/AssessmentTaskPopoverContent.tsx`:
- Around line 44-47: The Progress percent prop is fed directly from
activeTask.progress and should be defensively clamped and validated before
render; update the usage in AssessmentTaskPopoverContent (where <Progress
percent={Math.round(activeTask.progress)} ... /> is set) to first coerce to a
finite number and clamp into [0,100] (e.g., use Number.isFinite check and
Math.max(0, Math.min(100, value)) or a small clamp helper) and then Math.round
the clamped value so the UI never receives NaN/Infinity or out-of-range values.

In
`@clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx`:
- Around line 96-114: Currently the code always shows a success notification
when hadActiveTaskRef transitions from true to no activeTask; update the branch
inside the effect that checks hadActiveTaskRef.current && !activeTask to inspect
the last terminal status (e.g., use the previous activeTask status or check
activeTask?.status or store lastTaskStatus) and emit notificationApi.success
when the task ended successfully and notificationApi.error (with a message like
"Assessment failed" and optional details) when the terminal status is
TaskStatus.ERROR; keep the existing Reload results button behavior tied to
onTaskFinish for successful completion and avoid showing the success message on
error by branching on TaskStatus (reference hadActiveTaskRef, activeTask,
notificationApi, onTaskFinish, and TaskStatus).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9d09f737-d4f6-4faa-ba63-6d8db1d2b4a4

📥 Commits

Reviewing files that changed from the base of the PR and between 11d78c9 and 49fd30e.

📒 Files selected for processing (9)
  • changelog/7553-assessment-task-status.yaml
  • clients/admin-ui/src/features/common/api.slice.ts
  • clients/admin-ui/src/features/privacy-assessments/AssessmentTaskPopoverContent.tsx
  • clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx
  • clients/admin-ui/src/features/privacy-assessments/index.ts
  • clients/admin-ui/src/features/privacy-assessments/privacy-assessments.slice.ts
  • clients/admin-ui/src/features/privacy-assessments/types.ts
  • clients/admin-ui/src/features/privacy-assessments/utils.ts
  • clients/admin-ui/src/pages/privacy-assessments/index.tsx

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx (1)

172-187: Make evaluation details reachable without hover-only interaction.

The details popover is currently hover-triggered on a non-focusable container, which is easy to miss for keyboard/touch users. Please expose a focus/click path.

Proposed refactor
       <Popover
         content={
           <AssessmentTaskPopoverContent
             activeTask={activeTask}
             lastCompletedTask={lastCompletedTask}
             templateNamesMap={templateNamesMap}
           />
         }
         title="Evaluation details"
-        trigger="hover"
+        trigger={["hover", "focus", "click"]}
         placement="bottom"
       >
-        <div className={classNames("cursor-pointer", className)}>
+        <div
+          className={classNames("cursor-pointer", className)}
+          tabIndex={0}
+          aria-label="View evaluation details"
+        >
           {inlineContent}
         </div>
       </Popover>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx`
around lines 172 - 187, The popover in AssessmentTaskStatusIndicator.tsx is only
triggered on hover and wrapped around a non-focusable div, making it
inaccessible to keyboard and touch users; update the Popover props to allow
focus/click (e.g., trigger includes "click" and/or "focus") and make the wrapper
element keyboard-accessible by replacing or augmenting the div with a focusable
control (add tabIndex=0 and appropriate role like "button" or convert to a
<button>) and wire keyboard activation (onKeyDown handling Enter/Space) so
AssessmentTaskPopoverContent becomes reachable via keyboard and touch while
preserving inlineContent styling via className.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx`:
- Around line 172-187: The popover in AssessmentTaskStatusIndicator.tsx is only
triggered on hover and wrapped around a non-focusable div, making it
inaccessible to keyboard and touch users; update the Popover props to allow
focus/click (e.g., trigger includes "click" and/or "focus") and make the wrapper
element keyboard-accessible by replacing or augmenting the div with a focusable
control (add tabIndex=0 and appropriate role like "button" or convert to a
<button>) and wire keyboard activation (onKeyDown handling Enter/Space) so
AssessmentTaskPopoverContent becomes reachable via keyboard and touch while
preserving inlineContent styling via className.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: adf201a8-6110-4da9-bfea-bb7db5ab500a

📥 Commits

Reviewing files that changed from the base of the PR and between 49fd30e and 12e6131.

📒 Files selected for processing (2)
  • clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx
  • clients/admin-ui/src/features/privacy-assessments/utils.ts

Copy link
Contributor

@kruulik kruulik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple non-blocking code nits.
One thing I think we should change though is the copy.
Last assessment 2 minutes ago and
Last assessment a minute ago is kind of awkward.

I'd suggest changing the copy to something like Last assessment evaluated a minute ago

@lucanovera
Copy link
Contributor Author

Couple non-blocking code nits. One thing I think we should change though is the copy. Last assessment 2 minutes ago and Last assessment a minute ago is kind of awkward.

I'd suggest changing the copy to something like Last assessment evaluated a minute ago

Great suggestion on the copy! I'll implement it.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
clients/admin-ui/src/features/privacy-assessments/privacy-assessments.slice.ts (1)

88-95: Dead code — remove the unused getAssessmentTask endpoint.

The getAssessmentTask endpoint is defined but never exported or used. Only useGetAssessmentTasksQuery (plural) is exported and actively used in the codebase. Remove this endpoint to reduce maintenance burden.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clients/admin-ui/src/features/privacy-assessments/privacy-assessments.slice.ts`
around lines 88 - 95, Remove the unused RTK Query endpoint getAssessmentTask
from the privacy-assessments slice: delete the getAssessmentTask entry in the
endpoints object (the build.query definition returning url
`plus/privacy-assessments/tasks/${taskId}` and providesTags for "Privacy
Assessment Tasks") so only the used getAssessmentTasks endpoint remains; ensure
there are no lingering references to getAssessmentTask (e.g., exported hooks or
types) and run a quick project-wide search to confirm it isn't referenced
elsewhere before committing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@clients/admin-ui/src/features/privacy-assessments/privacy-assessments.slice.ts`:
- Around line 88-95: Remove the unused RTK Query endpoint getAssessmentTask from
the privacy-assessments slice: delete the getAssessmentTask entry in the
endpoints object (the build.query definition returning url
`plus/privacy-assessments/tasks/${taskId}` and providesTags for "Privacy
Assessment Tasks") so only the used getAssessmentTasks endpoint remains; ensure
there are no lingering references to getAssessmentTask (e.g., exported hooks or
types) and run a quick project-wide search to confirm it isn't referenced
elsewhere before committing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9a658f2c-7256-45b0-abd8-56b7001ec29f

📥 Commits

Reviewing files that changed from the base of the PR and between 12e6131 and a8df964.

📒 Files selected for processing (1)
  • clients/admin-ui/src/features/privacy-assessments/privacy-assessments.slice.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx (1)

35-54: Polling won't detect externally-started tasks.

The polling is gated on activeTask being truthy. If the component mounts with no active task and a task is later started by another user/session (or via API), this component won't detect it until the page is refreshed.

Consider whether a slower background poll (e.g., every 60–120s) when idle would improve the experience, or document this as expected behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx`
around lines 35 - 54, The current logic gates polling on activeTask so the
component never notices tasks started externally after mount; change the polling
strategy in useGetAssessmentTasksQuery so it always polls but with a conditional
interval (e.g., ACTIVE_POLL_INTERVAL when activeTask is truthy and a longer
IDLE_POLL_INTERVAL when falsy) instead of using skip: !activeTask, or add a
second call that polls at a slow IDLE_POLL_INTERVAL when there is no activeTask;
update references to useGetAssessmentTasksQuery, activeTask,
ACTIVE_POLL_INTERVAL (and introduce IDLE_POLL_INTERVAL) so the component can
detect externally-started tasks without requiring a full refresh.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx`:
- Around line 35-54: The current logic gates polling on activeTask so the
component never notices tasks started externally after mount; change the polling
strategy in useGetAssessmentTasksQuery so it always polls but with a conditional
interval (e.g., ACTIVE_POLL_INTERVAL when activeTask is truthy and a longer
IDLE_POLL_INTERVAL when falsy) instead of using skip: !activeTask, or add a
second call that polls at a slow IDLE_POLL_INTERVAL when there is no activeTask;
update references to useGetAssessmentTasksQuery, activeTask,
ACTIVE_POLL_INTERVAL (and introduce IDLE_POLL_INTERVAL) so the component can
detect externally-started tasks without requiring a full refresh.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b70b0fb1-faaf-4176-a8c6-18b15f80dea0

📥 Commits

Reviewing files that changed from the base of the PR and between a8df964 and 857235d.

📒 Files selected for processing (1)
  • clients/admin-ui/src/features/privacy-assessments/AssessmentTaskStatusIndicator.tsx

@lucanovera lucanovera added this pull request to the merge queue Mar 5, 2026
Merged via the queue into main with commit 93b0caf Mar 5, 2026
47 checks passed
@lucanovera lucanovera deleted the ENG-2837-UI-Show-in-progress-evaluation-tasks-that-update-in-real-time branch March 5, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants