gabotorresruiz commented on code in PR #44096:
URL: https://github.com/apache/superset/pull/44096#discussion_r4029996176
##########
superset/constants.py:
##########
@@ -40,6 +40,10 @@
NO_TIME_RANGE = "No filter"
+# Keep in sync with superset-frontend/src/utils/common.ts; select-filter masks
+# and dataMask hydration use this exact predicate to recognize an explicit
clear.
+EMPTY_FILTER_SQL_EXPRESSION = "1 = 0"
Review Comment:
Just a small NIT, not a blocker: there is one more copy of this predicate
that did not get folded in. `superset/security/manager.py:1235` keeps its own
`_EMPTY_FILTER_SENTINEL = "1 = 0"`, used as the guest token allow-list for
`extras.where` validation (`extras_allowed: set[str] =
{_EMPTY_FILTER_SENTINEL}` at line 1308), and its comment points straight at
`superset-frontend/src/filters/utils.ts`, one of the producers this PR just
switched over.
That makes the drift you are guarding against fail in a place the tests will
not catch: change `EMPTY_FILTER_SQL_EXPRESSION` later and
`getSelectExtraFormData` emits the new predicate while the security manager
still allows only the old literal, so an embedded chart whose required Select
filter has no value selected gets rejected, which is exactly what that comment
says must not happen.
It already does `from superset.constants import RouteMethod` at line 77, so
`_EMPTY_FILTER_SENTINEL = EMPTY_FILTER_SQL_EXPRESSION` is a one line swap. A
guest token test asserting that an unselected required Select filter still
passes `extras.where` validation would lock the coupling in.
##########
docs/admin_docs/configuration/mcp-server.mdx:
##########
@@ -41,6 +41,74 @@ flowchart LR
C --> D[("Database<br/>(Postgres)")]
```
+## Dashboard filter notifications
+
+`apply_dashboard_filters` supports exact-match select filters without inverse
+selection, and time filters. Inverse-selection configurations are rejected.
+Select filters configured for contains, starts-with, or ends-with matching are
+rejected rather than silently applying exact matching. A single-select filter
+accepts at most one value; a longer list is rejected rather than stored as a
+selection the control cannot render. Clearing a required select
+filter with `values: []` matches no rows, including when opening the returned
+permalink; an explicit clear does not restore its saved default.
+
+Returned dashboard permalink URLs use `WEBDRIVER_BASEURL_USER_FRIENDLY` as
+the public origin and respect `APPLICATION_ROOT` (or the request's WSGI
+`SCRIPT_NAME` when mounted behind a proxy). Set the public URL to the
+browser-accessible Superset host; the MCP service's own host may be different.
+
+To stack filters across chat turns, pass the previous
+`apply_dashboard_filters` response's `permalink_key` as `base_permalink_key`
+in the next request for the same dashboard. For example, apply Region = EMEA,
+then pass that key with a Time Range = `2024-01-01 : 2025-01-01` request to
+keep EMEA and add the year constraint. Each new value replaces that filter's
+entire prior entry; unmentioned filters persist. Omit the base key to start
+from dashboard defaults. `applied_filters` summarizes only the new request,
+not the inherited selections. Inherited entries for filters the dashboard no
+longer defines are dropped, so a filter deleted or recreated between turns
+does not carry a stale predicate forward.
+
+Base state is resolved server-side under the calling user's dashboard access
+and merged without display redaction; the raw base mask is not returned.
+Missing or expired keys, resolution failures, access denial, and dashboard
+mismatches fail explicitly without creating a replacement link. Missing and
+expired keys share an error because the permalink store does not distinguish
+them.
+
+After creating a dashboard permalink, `apply_dashboard_filters` attempts a
+best-effort `dashboard.filters_applied` realtime notification scoped to the
+calling principal. Its payload contains only `dashboard_id` and
`permalink_key`;
+filter values and resolved state are not included. Consumers must resolve the
+key through the dashboard's authorized permalink load path.
+
+Live browser updates require `WEBSOCKET_ENABLE = True`, a configured
+`DISTRIBUTED_COORDINATION_CONFIG` backend, a running `superset-websocket`
+server, and a strong, non-default `WEBSOCKET_JWT_SECRET` of at least 32 bytes.
+`WEBSOCKET_URL` must also point at a `ws://`/`wss://` endpoint the browser can
+reach. Its default, `ws://127.0.0.1:8080/`, resolves to the browser's own
+loopback, so a remote deployment that leaves it unchanged has every
+server-side piece configured correctly while live updates never connect.
+The browser user also needs
+`can_read` on `Realtime`. With the default configuration the realtime half
+is inert, but the tool still creates and returns a permalink URL.
+The MCP process and websocket transport must use the same
+`REALTIME_CHANNEL_PREFIX`. This publisher does not require the Global Task
+Framework feature flag.
+
+The response's `live_update_pushed` field reports publication success, not
+browser receipt or application. Without a backend, an identifiable principal,
+or a successful publish, it is `false`; the created `dashboard_url` remains
+the fallback. An open dashboard resolves matching notifications through the
+existing dashboard permalink API and applies the returned filters without a
+reload. A “Filters applied from chat” toast offers **Undo** for eight seconds,
Review Comment:
Small NIT: this line is stale after `10196a117d`. `Toast.tsx:103` now skips
the auto dismiss timer whenever `toast.action` is set, so the Undo toast stays
up until the user activates or closes it. I confirmed it on this branch: `an
actionable toast remains until it is explicitly dismissed` passes at head and
fails as soon as the `!toast.action` guard is removed.
Worth saying the toast persists until dismissed rather than eight seconds,
here and in the PR body. Same for `duration: 8000` in
`useDashboardFilterSync.ts:82`, which is now inert for this toast.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]