Skip to content

UI: Fix silent errors and layout shift in import error components#64267

Open
vamsi2246 wants to merge 2 commits intoapache:mainfrom
vamsi2246:fix-ui-dag-import-errors-layout-and-error-visibility
Open

UI: Fix silent errors and layout shift in import error components#64267
vamsi2246 wants to merge 2 commits intoapache:mainfrom
vamsi2246:fix-ui-dag-import-errors-layout-and-error-visibility

Conversation

@vamsi2246
Copy link
Copy Markdown

This PR improves the robustness and UX of the DAGImportErrors and PluginImportErrors components by addressing three issues:

  1. Error Visibility: Fixed a bug where API errors were swallowed because the component returned undefined early when the error count was 0 (the default on failure).
  2. Prevent Layout Shift: Adjusted the loading skeleton dimensions for iconOnly mode to match the final badge size, eliminating a noticeable flicker on the Dags List and Dashboard pages.
  3. UI Polish: Corrected the warning icon size from 8 (too small) to a standard 16 for better visibility.

Was generative AI tooling used to co-author this PR?
  • Yes — Antigravity (Google DeepMind Advanced Agentic Coding)

Generated-by: Antigravity following the guidelines

@boring-cyborg
Copy link
Copy Markdown

boring-cyborg bot commented Mar 26, 2026

Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our Contributors' Guide (https://github.com/apache/airflow/blob/main/contributing-docs/README.rst)
Here are some useful points:

  • Pay attention to the quality of your code (ruff, mypy and type annotations). Our prek-hooks will help you with that.
  • In case of a new feature add useful documentation (in docstrings or in docs/ directory). Adding a new operator? Check this short guide Consider adding an example DAG that shows how users should use it.
  • Consider using Breeze environment for testing locally, it's a heavy docker but it ships with a working Airflow and a lot of integrations.
  • Be patient and persistent. It might take some time to get a review or get the final approval from Committers.
  • Please follow ASF Code of Conduct for all communication including (but not limited to) comments on Pull Requests, Mailing list and Slack.
  • Be sure to read the Airflow Coding style.
  • Always keep your Pull Requests rebased, otherwise your build might fail due to changes not related to your commits.
    Apache Airflow is a community-driven project and together we are making it better 🚀.
    In case of doubts contact the developers at:
    Mailing List: dev@airflow.apache.org
    Slack: https://s.apache.org/airflow-slack

@boring-cyborg boring-cyborg bot added the area:UI Related to UI/UX. For Frontend Developers. label Mar 26, 2026
@bbovenzi
Copy link
Copy Markdown
Contributor

Thanks. Can you provide some screenshots or videos of before and after?

@vamsi2246 vamsi2246 force-pushed the fix-ui-dag-import-errors-layout-and-error-visibility branch from becc9a0 to c16879d Compare March 28, 2026 19:16
@vamsi2246
Copy link
Copy Markdown
Author

Thanks for the review! I'll add before/after screenshots shortly.

@bbovenzi
Copy link
Copy Markdown
Contributor

Still asking for videos of the before and after conditions.

Copy link
Copy Markdown
Member

@pierrejeambrun pierrejeambrun left a comment

Choose a reason for hiding this comment

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

LGTM, would love some screenshot to document the PR as mentioned by Brent.

@kaxil kaxil requested a review from Copilot April 2, 2026 00:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the Dashboard “import errors” UI by ensuring API failures are visible (instead of being silently hidden) and by reducing layout shift during loading, plus a small icon-size polish.

Changes:

  • Prevents silent-swallowing of API errors by only early-returning when the error count is 0 and there is no query error.
  • Updates loading skeleton dimensions (including iconOnly) to better match final rendered sizes and reduce flicker/layout shift.
  • Standardizes iconOnly warning icon size to 16 for better visibility.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/PluginImportErrors.tsx Fixes error visibility when the query fails; adjusts loading skeleton sizing; updates icon size; keeps 403 hidden.
airflow-core/src/airflow/ui/src/pages/Dashboard/Stats/DAGImportErrors.tsx Fixes error visibility when the query fails; adjusts loading skeleton sizing; updates icon size.

Comment on lines 39 to +47
if (isLoading) {
return <Skeleton height="9" width="225px" />;
// Skeleton dimensions match the rendered component sizes to prevent layout shift.
// iconOnly: 28px × 60px matches StateBadge (height={7} = 28px in Chakra spacing scale).
// full: 42px × 175px matches the rendered StatsCard dimensions.
return iconOnly ? (
<Skeleton height="28px" width="60px" />
) : (
<Skeleton height="42px" width="175px" />
);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The loading Skeleton sizes are hard-coded here (28×60 and 42×175). This can easily drift from the real rendered sizes if StateBadge / StatsCard styles change (reintroducing layout shift). Consider deriving these from the same source (e.g. reuse StatsCard’s built-in loading skeleton for the full variant, and for iconOnly either render a StateBadge container with a fixed/min width while loading, or share constants with the badge styles) to avoid duplicated magic numbers.

Copilot uses AI. Check for mistakes.
Comment on lines 40 to +48
if (isLoading) {
return <Skeleton height="9" width="225px" />;
// Skeleton dimensions match the rendered component sizes to prevent layout shift.
// iconOnly: 28px × 60px matches StateBadge (height={7} = 28px in Chakra spacing scale).
// full: 42px × 175px matches the rendered StatsCard dimensions.
return iconOnly ? (
<Skeleton height="28px" width="60px" />
) : (
<Skeleton height="42px" width="175px" />
);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The loading Skeleton sizes are duplicated and hard-coded (28×60 and 42×175). This risks getting out of sync with StateBadge / StatsCard styling changes and reintroducing layout shift. Consider reusing StatsCard’s loading skeleton for the full variant and centralizing the iconOnly placeholder dimensions (or rendering a fixed-size StateBadge-like wrapper) to avoid repeating magic numbers.

Copilot uses AI. Check for mistakes.
Comment on lines +50 to 52
if (importErrorsCount === 0 && !error) {
return undefined;
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This changes behavior so the component renders (via ErrorAlert) when the import-errors query fails (previously it returned early when total_entries defaulted to 0). Please add a regression test that simulates an API error (e.g. 500) and asserts the error alert is shown and the badge/card is not rendered when total_entries is 0.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +55 to 57
if (importErrorsCount === 0 && !error) {
return undefined;
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

This updates the early-return guard to allow the ErrorAlert to render when the query fails (since total_entries defaults to 0 on failure). Please add a regression test that mocks an API error and verifies the error alert shows even when importErrorsCount is 0, and that the badge/card only renders when importErrorsCount > 0.

Copilot generated this review using guidance from repository custom instructions.
);
}

if (Boolean(error) && (error as ExpandedApiError).status === 403) {
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The 403 handling does an unsafe cast (error as ExpandedApiError).status. Elsewhere in the UI (e.g. pages/Dashboard/PoolSummary/PoolSummary.tsx:50-52) code checks error?.status === 403 without a cast. Consider typing the query hook’s error (via generics) or using optional chaining ((error as ExpandedApiError | undefined)?.status) to avoid a potential runtime crash if error is not an ApiError shape.

Suggested change
if (Boolean(error) && (error as ExpandedApiError).status === 403) {
if ((error as ExpandedApiError | undefined)?.status === 403) {

Copilot uses AI. Check for mistakes.
@potiuk potiuk added the ready for maintainer review Set after triaging when all criteria pass. label Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:UI Related to UI/UX. For Frontend Developers. ready for maintainer review Set after triaging when all criteria pass.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants