Skip to content

feat(semantic-layer): guide semantic layer setup - #45649

Open
mikebridge wants to merge 10 commits into
apache:masterfrom
mikebridge:sc-129096-semantic-layer-setup-guidance
Open

mikebridge wants to merge 10 commits into
apache:masterfrom
mikebridge:sc-129096-semantic-layer-setup-guidance

Conversation

@mikebridge

@mikebridge mikebridge commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

The semantic view and layer dialogs now explain empty and unavailable choices and provide a next step. Users who can create layers can open layer setup directly from an empty view picker; other users see guidance to contact an administrator.

SUMMARY

Distinguish loading, empty results and request failures, with an explicit retry. Display the selected provider's existing description during setup, and return to a refreshed view picker after layer creation or cancellation. Ignore late responses from closed dialogs.

Add optional SEMANTIC_LAYER_DOCUMENTATION_URL configuration for a setup guide in both dialogs. It defaults to None; invalid URLs and URLs containing credentials stay hidden. The main documentation menu is unchanged. This uses existing provider metadata and permissions.

Provider descriptions use a runtime t(description) lookup with source-language fallback. Dynamic provider text is not automatically extracted into the host translation catalog; this does not add a new metadata field.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Before: empty selectors offer no setup guidance. After: the empty view picker explains the next step, and the layer picker shows provider setup information or a distinct loading/error/empty state.

Screenshots and a real-browser accessibility walkthrough are still pending. This is a draft with placeholder copy pending product review.

TESTING INSTRUCTIONS

  • 172 tests pass across both semantic modal suites and DatasetList behavior/permission suites. New behavior was tested red-first, including late-response and cancellation regressions.
  • 23 bootstrap tests pass; source-resolved full TypeScript and changed-file hooks pass.
  • Full Python unit suite: 30,504 passed, 56 skipped, 5 xfailed; two known Mac ARM longdouble failures in untouched dataframe/numeric-contract tests. No other failures.
  • Translation-template drift passes; OpenAPI generation produces no change.

Manual checks with SEMANTIC_LAYERS enabled:

  1. With no accessible layers, open New → Semantic View. A layer writer can choose “Create semantic layer”; a user without layer-write permission sees administrator guidance.
  2. Cancel layer setup, then repeat and create a layer. Each return opens a fresh view picker without selecting or saving a view automatically.
  3. Exercise empty, delayed, failed and populated type responses. Select two providers and confirm their descriptions change. Close during a pending request, reopen, and confirm the late response cannot replace the new dialog.
  4. Set SEMANTIC_LAYER_DOCUMENTATION_URL to an absolute HTTP(S) setup-guide URL. Confirm it remains available during loading and opens in a new tab. Unset it and confirm the link is hidden.
  5. Check keyboard focus, Escape, and screen-reader announcements in a real browser before marking ready.

Copy is placeholder pending product review; no production documentation URL is supplied or activated.

ADDITIONAL INFORMATION

Companion provider-description change: https://github.com/preset-io/superset-shell/pull/5640. This host change remains compatible with providers that omit a description.

  • Has associated issue:
  • Required feature flags: SEMANTIC_LAYERS (existing)
  • Changes UI
  • Includes DB Migration
  • Introduces new feature or API: optional setup-guide configuration; no new API endpoint
  • Removes existing feature or API

@github-actions github-actions Bot added i18n Namespace | Anything related to localization doc Namespace | Anything related to documentation labels Oct 23, 2026
@netlify

netlify Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 2c72d33
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6ae3d2e7d2b2c3ab9e872922
😎 Deploy Preview https://deploy-preview-45649--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.

@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.72%. Comparing base (492494b) to head (32ffea6).
⚠️ Report is 10 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #45649      +/-   ##
==========================================
+ Coverage   84.70%   84.72%   +0.01%     
==========================================
  Files        3069     3070       +1     
  Lines      205610   205784     +174     
  Branches    48330    48406      +76     
==========================================
+ Hits       174157   174342     +185     
+ Misses      28160    28149      -11     
  Partials     3293     3293              
Flag Coverage Δ
hive 34.51% <45.00%> (+<0.01%) ⬆️
javascript 80.97% <100.00%> (+0.03%) ⬆️
mysql 52.58% <45.00%> (-0.01%) ⬇️
postgres 52.58% <45.00%> (-0.01%) ⬇️
presto 36.24% <45.00%> (+<0.01%) ⬆️
python 87.75% <100.00%> (+<0.01%) ⬆️
sqlite 52.35% <45.00%> (-0.01%) ⬇️
unit 82.48% <100.00%> (+<0.01%) ⬆️

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.

{semanticSetup === 'layer' && (
<SemanticLayerModal
show
onHide={() => setSemanticSetup('view')}

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 creation succeeds after Cancel, its POST has committed but unmounting ignores the response; if the picker refreshed first, it stays empty until reopened.

Assessment: 🟠 Major · 🔁 Occurrence: Rarely · 🏷️ Race condition

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/pages/DatasetList/index.tsx
**Line:** 1667:1667
**Comment:**
	*Race Condition: When creation succeeds after Cancel, its POST has committed but unmounting ignores the response; if the picker refreshed first, it stays empty until reopened.

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
Member

Choose a reason for hiding this comment

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

Agreed—if the user cancels while the create POST is in flight, the unmounted modal drops the response, so the freshly mounted view picker can load its list before the layer exists and stay empty until the dialog is reopened. Should the create completion be reported back to the parent (or the picker refetched on a later signal) even after cancel?

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.

Yes. Cancel currently only closes/unmounts the modal; it doesn’t guarantee the POST was canceled or rolled back. If that POST later succeeds, the parent should receive a creation-completed signal even though the modal is stale, and use it only to invalidate/refetch the semantic-layer list.

Keep that signal separate from onHide: a late completion must not switch dialogs, close a newer session, or show a stale success toast. A parent-owned refresh signal can trigger a refetch if the view picker is already open, while its normal initial fetch handles the case where creation finishes before the picker remounts. This closes the race without letting the late response take over the UI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, and fixed in 33fe0325be. The create response now signals the parent even if the layer dialog was cancelled, so the view picker refetches its layer list. A stale response can't reopen a dialog or show a success toast. A delayed-POST regression test failed before the fix and passes now.

Comment thread superset/views/base.py
from .utils import bootstrap_user_data, get_config_value

FRONTEND_CONF_KEYS = (
"SEMANTIC_LAYER_DOCUMENTATION_URL",

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: This sends the raw configured URL to every user's bootstrap payload, exposing embedded credentials even though the UI hides links containing them.

Assessment: 🔴 Critical · 🔁 Occurrence: Rarely · 🏷️ Security

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/views/base.py
**Line:** 84:84
**Comment:**
	*Security: This sends the raw configured URL to every user's bootstrap payload, exposing embedded credentials even though the UI hides links containing them.

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
Member

Choose a reason for hiding this comment

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

Agreed—SEMANTIC_LAYER_DOCUMENTATION_URL is added to the common bootstrap conf unchanged, so a URL with embedded credentials is delivered to every user's page even though the dialog only hides the link; the docs say such URLs are hidden. Should the server drop or sanitize credential-bearing URLs before exposing them?

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.

Yes. The concern is valid: client-side hiding does not prevent the raw value from appearing in the bootstrap payload. The server should validate SEMANTIC_LAYER_DOCUMENTATION_URL before adding it to conf and return None for URLs with credentials (and, ideally, other invalid URLs). Rejecting the whole URL is safer than stripping credentials, which could silently change its destination. Keep the frontend check as defense in depth, and add a bootstrap test confirming credential-bearing URLs are not exposed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, and fixed in 33fe0325be. The server now leaves credential-bearing, non-HTTP(S) and malformed setup URLs out of the common bootstrap (they become None) and logs one warning, without the URL. The bootstrap tests failed before the filter and pass now, and the configuration docs describe the behavior.

@codeant-ai-for-open-source

codeant-ai-for-open-source Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

CodeAnt  CodeAnt PR Risk

🟢  Low Risk

  • The PR appears safe to merge; the setup URL is validated server-side before it reaches the bootstrap payload.
  • Successful layer creation after Cancel still signals the parent to refresh, without reopening dialogs or showing stale success UI.

Assessed commit: 32ffea67d726

Comment thread superset-frontend/src/features/semanticLayers/SemanticLayerModal.tsx Outdated
Comment thread superset-frontend/src/features/semanticLayers/SemanticLayerModal.tsx Outdated
Comment thread superset-frontend/src/features/semanticLayers/SemanticLayerModal.tsx Outdated
>
{t('Reload metadata')}
</Button>
{/* COPY-TBD: semantic setup guidance, pending product copy. */}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

IIUC the description still calls the copy a placeholder pending product review. Is it final now, or would it make sense to keep this in draft until it is, so the COPY-TBD notes don't land?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not final yet. I've asked product to review the copy. I'll update the text and remove the COPY-TBD markers before this merges, and it won't land with them in place.

Comment thread superset/config.py
Comment on lines +2940 to +2942
# Optional setup guide shown in the semantic layer and semantic view dialogs.
# Use an absolute HTTP(S) URL; unset deployments show no setup-guide link.
SEMANTIC_LAYER_DOCUMENTATION_URL: str | None = None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: this lands between DOCUMENTATION_URL and DOCUMENTATION_TEXT/DOCUMENTATION_ICON, which the navbar reads together, so DOCUMENTATION_TEXT now reads like the label for the setup guide. Would it make sense to move it below DOCUMENTATION_ICON?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved in 537733d. SEMANTIC_LAYER_DOCUMENTATION_URL now sits below DOCUMENTATION_ICON, so the navbar documentation settings stay together.

Comment thread superset-frontend/src/features/semanticLayers/SemanticLayerModal.tsx Outdated
Comment thread superset-frontend/src/pages/DatasetList/DatasetList.permissions.test.tsx Outdated
/>
<SemanticLayerModal
show={!!slCurrentlyEditing}
onUpdated={refreshData}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If the Edit flow commits its PUT after Cancel, DatabaseList only gets the Connections refresh from onUpdated={refreshData} here, and the page tests cover that wiring only for create. Dropping this prop would leave the list stale after a late edit without failing any test, because the modal test passes its own callback. Could you add a DatabaseList test that opens Edit, defers the PUT, cancels, waits for the cancel-triggered refresh, resolves the PUT, and asserts a further Connections request?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a layer updated after Cancel refreshes the Connections list again in DatabaseList.semanticLayerDelete.test.tsx. It opens Edit, holds the PUT pending, cancels, waits for the cancel-triggered Connections refresh, then resolves the PUT and verifies a further Connections request. Removing onUpdated={refreshData} makes the test fail at that final assertion; with the callback restored, all 19 tests in the file pass.

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

doc Namespace | Anything related to documentation i18n Namespace | Anything related to localization size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants