Skip to content

feat(dashboard): add optional per-dashboard auto-refresh policy - #46037

Open
DamianPendrak wants to merge 6 commits into
apache:masterfrom
DamianPendrak:feat/dashboard-auto-refresh-policy
Open

DamianPendrak wants to merge 6 commits into
apache:masterfrom
DamianPendrak:feat/dashboard-auto-refresh-policy

Conversation

@DamianPendrak

@DamianPendrak DamianPendrak commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

SUMMARY

Adds an optional per-dashboard auto-refresh policy behind a new feature flag, AUTO_REFRESH_POLICY (default False). With the flag off, policy metadata is accepted and stored without validation (including null), but ignored by refresh behavior.

With the flag on, dashboard editors can turn on Use a refresh policy in Dashboard properties → Refresh settings and set:

  • Allow auto-refresh. When off, viewers get no auto-refresh menu item, status indicator or timer, embedded dashboards included. Manual refresh stays.
  • Optional Shortest and Longest intervals from DASHBOARD_AUTO_REFRESH_INTERVALS. Viewers can only pick intervals inside that range, and the default refresh frequency must be inside it too.

The policy is stored in json_metadata under auto_refresh_policy:

{
  "refresh_frequency": 60,
  "auto_refresh_policy": {
    "auto_refresh_allowed": true,
    "minimum_refresh_interval": {"value": 30, "unit": "seconds"},
    "maximum_refresh_interval": {"value": 1, "unit": "hours"}
  }
}

With the flag on, dashboard API writes, copy, imports, MCP tools and version restore validate refresh settings. REST dashboard endpoints and version restore return field errors as an errors list of {field, code, message}. Imports return ordinary validation messages; MCP returns an error string. REST PUT, Dashboard properties saves, MCP updates and version restore validate refresh rules only when the policy or refresh frequency changes; title-only, Published/Draft and layout saves preserve unchanged refresh settings even if an operator has removed their default interval from the list.

An update that omits auto_refresh_policy keeps the stored policy. With the flag on, null removes it and policy changes are recorded in the existing Log table as dashboard_refresh_policy_changed. No DB migration is required. With a policy, viewers cannot select Custom intervals and Custom defaults are rejected.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

01-properties-no-policy 02-properties-allowed-bounds 06-viewer-interval-modal

TESTING INSTRUCTIONS

  1. Set FEATURE_FLAGS = {"AUTO_REFRESH_POLICY": True} and restart.
  2. Open a dashboard → Edit properties → Refresh settings → turn on Use a refresh policy.
  3. Keep Allow auto-refresh on, pick Shortest 1 minute and Longest 1 hour, a default of 5 minutes, Apply and Save. As a viewer, open ⋯ → Update auto-refresh: only intervals between 1 minute and 1 hour are listed and the range is stated.
  4. Back in properties, lower Longest below the default: the default shows an inline error and Apply is disabled until it is fixed.
  5. Turn Allow auto-refresh off with a positive default: an error asks for "Don't refresh"; pick it, Save. Reload: the auto-refresh menu item, status indicator and timer are gone; manual "Refresh dashboard" stays. Open the dashboard embedded (or ?standalone=true): no automatic refresh.
  6. API: PUT /api/v1/dashboard/<id> with json_metadata containing a refresh_frequency below minimum_refresh_interval → 422 with an errors entry {"field": "json_metadata.refresh_frequency", "code": "below_minimum", ...}. A PUT that omits auto_refresh_policy keeps it; sending null removes it with the flag on.
  7. Copy the dashboard (Save as): the copy keeps the policy.
  8. Set the flag back to False and restart: Refresh settings and the header menu are stock again, and saves succeed with the stored policy left in json_metadata.

Automated: TZ=UTC pytest tests/unit_tests/dashboards tests/unit_tests/mcp_service/dashboard tests/unit_tests/subjects/test_creator_group_call_sites.py and, in superset-frontend, npm run test -- --maxWorkers=2 src/dashboard/components/PropertiesModal src/dashboard/components/RefreshFrequency src/dashboard/components/Header src/dashboard/components/RefreshIntervalModal src/dashboard/actions/hydrate src/dashboard/components/DashboardBuilder src/dashboard/reducers/dashboardState.

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags: AUTO_REFRESH_POLICY (new, default False)
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

Adds an AUTO_REFRESH_POLICY feature flag (off by default). When on, dashboard
editors can allow or prohibit auto-refresh and bound viewer refresh intervals
to the configured standard intervals; the policy is validated on every
dashboard write path. With the flag off, behaviour is unchanged.
@github-actions github-actions Bot added i18n Namespace | Anything related to localization api Related to the REST API doc Namespace | Anything related to documentation packages labels Nov 5, 2026
@netlify

netlify Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit b91d79a
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6aeca345872b0349f6e78bcd
😎 Deploy Preview https://deploy-preview-46037--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

slug: updates.slug,
description: updates.description,
metadata: JSON.parse(updates.jsonMetadata || '{}'),
metadata: applied,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: The metadata editor omits shared_label_colors and map_label_colors; replacing Redux metadata here drops them when properties are applied, making chart label colors disappear.

Assessment: 🟠 Major · 🔁 Occurrence: Often · 🏷️ Api mismatch

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/dashboard/components/Header/index.tsx
**Line:** 609:609
**Comment:**
	*Api Mismatch: The metadata editor omits `shared_label_colors` and `map_label_colors`; replacing Redux metadata here drops them when properties are applied, making chart label colors disappear.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

if isinstance(value, bool):
return None
if isinstance(value, (int, float)):
seconds = float(value)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: A sufficiently large integer in the configured intervals makes float(value) raise OverflowError, causing policy validation to fail with a server error.

Assessment: 🟠 Major · 🔁 Occurrence: Rarely · 🏷️ Possible bug

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset/dashboards/refresh_policy.py
**Line:** 75:75
**Comment:**
	*Possible Bug: A sufficiently large integer in the configured intervals makes `float(value)` raise `OverflowError`, causing policy validation to fail with a server error.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ CodeAnt verified this suggestion was addressed in subsequent commits and marked this thread resolved as of b91d79a.

_to_seconds now catches OverflowError from float(value) and returns None for values that cannot be converted.

If that's not right, unresolve this thread and CodeAnt will leave it open.

)

# The generic assets error mapping is maintained separately.
assert response.status_code in {422, 500}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: Accepting HTTP 500 lets this test pass when invalid-policy import crashes, so it does not verify the promised 422 validation response.

Assessment: 🟠 Major · 🔁 Occurrence: Rarely · 🏷️ Api mismatch

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** tests/unit_tests/dashboards/commands/importers/v1/refresh_policy_import_test.py
**Line:** 165:165
**Comment:**
	*Api Mismatch: Accepting HTTP 500 lets this test pass when invalid-policy import crashes, so it does not verify the promised 422 validation response.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

metadata[POLICY_KEY] = policy;
}
if (policyOn) {
metadata.refresh_frequency = frequency;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: When the policy is off, Advanced JSON edits do not update refreshFrequency; enabling the policy writes that stale select value here and discards the edited default.

Assessment: 🟠 Major · 🔁 Occurrence: Rarely · 🏷️ Incorrect variable usage

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/dashboard/components/PropertiesModal/index.tsx
**Line:** 679:679
**Comment:**
	*Incorrect Variable Usage: When the policy is off, Advanced JSON edits do not update `refreshFrequency`; enabling the policy writes that stale select value here and discards the edited default.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +206 to +207
(minimum === null || value >= minimum) &&
(maximum === null || value <= maximum),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: A malformed bound saved while the feature flag was off becomes null here and is treated as unbounded, letting viewers refresh outside the intended policy.

Assessment: 🟠 Major · 🔁 Occurrence: Rarely · 🏷️ Incorrect condition logic

Use CodeAnt Skill Fix in Cursor Fix in VSCode Claude

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/dashboard/components/RefreshFrequency/RefreshFrequencySelect.tsx
**Line:** 206:207
**Comment:**
	*Incorrect Condition Logic: A malformed bound saved while the feature flag was off becomes `null` here and is treated as unbounded, letting viewers refresh outside the intended policy.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codecov

codecov Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.79493% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.10%. Comparing base (ffdf7a4) to head (b91d79a).
⚠️ Report is 5 commits behind head on master.

Files with missing lines Patch % Lines
...mponents/PropertiesModal/hooks/useRefreshPolicy.ts 96.15% 7 Missing ⚠️
superset/dashboards/api.py 50.00% 6 Missing ⚠️
...onents/PropertiesModal/sections/RefreshSection.tsx 95.90% 5 Missing ⚠️
...components/Header/useHeaderActionsDropdownMenu.tsx 80.00% 1 Missing ⚠️
superset/versioning/restore.py 93.33% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #46037       +/-   ##
===========================================
+ Coverage   65.38%   85.10%   +19.71%     
===========================================
  Files        3080     3083        +3     
  Lines      209437   210305      +868     
  Branches    49385    49719      +334     
===========================================
+ Hits       136950   178973    +42023     
+ Misses      69350    27954    -41396     
- Partials     3137     3378      +241     
Flag Coverage Δ
hive 34.16% <21.59%> (-0.04%) ⬇️
javascript 81.50% <97.97%> (+0.12%) ⬆️
mysql 51.97% <34.09%> (-0.05%) ⬇️
postgres 51.99% <34.09%> (?)
presto 35.81% <21.59%> (-0.04%) ⬇️
python 87.98% <96.59%> (+35.75%) ⬆️
sqlite 51.74% <34.09%> (-0.05%) ⬇️
unit 83.10% <96.59%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Related to the REST API doc Namespace | Anything related to documentation i18n Namespace | Anything related to localization packages size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant