You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by "sadpandajoe (via GitHub)" <gi...@apache.org> on 2026/06/24 02:15:40 UTC
[PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
sadpandajoe opened a new pull request, #41351:
URL: https://github.com/apache/superset/pull/41351
### SUMMARY
When a horizontal filter bar has enough native filters to overflow into the "More filters" dropdown, applying a cross-filter (which prepends a chip to the bar) could make the overflowed native filters disappear from both the bar and the dropdown, while the "More filters" button itself also vanished, leaving the hidden filters unreachable. Clearing the cross-filter restored them. The failure depends on the number of configured filters, not screen resolution.
Root cause: on an item-set change `DropdownContainer` resets its positional overflow index and re-measures; if that measurement catches a transient mid-reflow layout it can settle a "nothing overflows" verdict that never self-corrects (the recalculation effect's dependencies don't change again). Because the trigger's visibility is derived solely from the overflow count, that one bad verdict both strands the surplus filters in the clipped bar and removes the trigger to reach them.
Fix: treat a post-item-change "nothing overflows" read as provisional and run a single `requestAnimationFrame` confirmation pass that re-measures once the browser has reflowed, keeping the trigger mounted across the confirmation window. The confirmation is armed on every item-set change (covering a fitβoverflow transition, not only the already-overflowing case) and is versioned/cancelled so a superseded frame from a rapid second change cannot clobber the newer state. This extends the intent of #38193 (which guarded only the transient reset window) to the settled case, in the same overflow/button-visibility area as #28060.
### BEFORE/AFTER
Behavioral overflow bug, no visual redesign. Covered by automated tests rather than screenshots; see Testing Instructions.
### TESTING INSTRUCTIONS
- `cd superset-frontend && npm run test -- DropdownContainer.overflow`
- The new `DropdownContainer.overflow.test.tsx` drives the real overflow recalculation (mocking only the container width and per-element geometry) and covers: clean re-measurement after a prepended chip, the transient-latch regression, the fitβoverflow transition, over-correction (a genuine fit drops the trigger), and re-entrant item-set changes.
- Manual: on a dashboard with enough native filters to show "More filters" in the horizontal filter bar, apply a cross-filter from a chart; the overflowed native filters and the "More filters" button must remain present and reachable.
### ADDITIONAL INFORMATION
- [x] Changes UI
- [ ] Includes DB Migration
- [ ] Introduces new feature or API
- [ ] Removes existing feature or API
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #41351:
URL: https://github.com/apache/superset/pull/41351#discussion_r3476401731
##########
superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.tsx:
##########
@@ -220,6 +325,59 @@ export const DropdownContainer = forwardRef(
}
}
+ // A "nothing overflows" verdict on the pass that consumed an item-set-
+ // change reset may reflect a transient mid-reflow measurement. When that
+ // happens, do NOT settle immediately. Instead:
+ // β’ If the rAF hasn't been scheduled yet: schedule it (one-shot) and
+ // return without settling; recalculating stays true so the trigger
+ // remains mounted throughout the confirmation window.
+ // β’ If the rAF is already scheduled (a second layout effect run
+ // triggered by the setItemsWidth call above): also return without
+ // settling for the same reason.
+ // The rAF callback reads the DOM directly at a point where the browser
+ // has reflowed and calls the setters itself. It also resets the guard
+ // refs so subsequent effect runs (e.g. from a real resize) behave
+ // normally.
+ if (
+ newOverflowingIndex === -1 &&
+ pendingConfirmForLengthRef.current === items.length
+ ) {
+ if (!confirmationScheduledRef.current) {
+ confirmationScheduledRef.current = true;
+ const scheduledVersion = confirmVersionRef.current;
+ rafIdRef.current = requestAnimationFrame(() => {
+ rafIdRef.current = 0;
+ if (!mountedRef.current) return;
+ // A newer item-set change superseded this confirmation while the
+ // frame was queued; let the newer one's own confirmation settle.
+ if (confirmVersionRef.current !== scheduledVersion) return;
+ // Reset guard refs so future layout effect runs are unaffected.
+ pendingConfirmForLengthRef.current = -1;
+ confirmationScheduledRef.current = false;
+ hadContentAtLastChangeRef.current = false;
Review Comment:
The confirmation rAF callback can still run even if a subsequent layout effect run already settled the correct overflowingIndex (e.g. when `setItemsWidth(...)` triggers a rerun). In that case the queued rAF can clobber the newer settled state. Add a guard in the rAF callback to no-op when the pending confirmation was already cleared by a settling pass.
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4977321314
πͺ [Showtime](https://github.com/mistercrunch/superset-showtime) deployed environment on [GHA](https://github.com/apache/superset/actions/runs/29391666885) for [7829ad1](https://github.com/apache/superset/commit/7829ad1)
β’ **Environment:** http://34.220.51.51:8080 (admin/admin)
β’ **Lifetime:** 48h auto-cleanup
β’ **Updates:** New commits create fresh environments automatically
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4963014116
πͺ [Showtime](https://github.com/mistercrunch/superset-showtime) deployed environment on [GHA](https://github.com/apache/superset/actions/runs/29286371982) for [f7c69b3](https://github.com/apache/superset/commit/f7c69b3)
β’ **Environment:** http://35.92.37.38:8080 (admin/admin)
β’ **Lifetime:** 48h auto-cleanup
β’ **Updates:** New commits create fresh environments automatically
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "codecov[bot] (via GitHub)" <gi...@apache.org>.
codecov[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4785344960
## [Codecov](https://app.codecov.io/gh/apache/superset/pull/41351?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
:x: Patch coverage is `88.33333%` with `7 lines` in your changes missing coverage. Please review.
:white_check_mark: Project coverage is 64.39%. Comparing base ([`d6ede99`](https://app.codecov.io/gh/apache/superset/commit/d6ede998619c2193ec1001e9e981f1537b4073ea?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`ca32d9b`](https://app.codecov.io/gh/apache/superset/commit/ca32d9b422ff8519356abcdbf52d424e3252ed3b?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
:warning: Report is 2 commits behind head on master.
| [Files with missing lines](https://app.codecov.io/gh/apache/superset/pull/41351?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Patch % | Lines |
|---|---|---|
| [...components/DropdownContainer/DropdownContainer.tsx](https://app.codecov.io/gh/apache/superset/pull/41351?src=pr&el=tree&filepath=superset-frontend%2Fpackages%2Fsuperset-ui-core%2Fsrc%2Fcomponents%2FDropdownContainer%2FDropdownContainer.tsx&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VwZXJzZXQtZnJvbnRlbmQvcGFja2FnZXMvc3VwZXJzZXQtdWktY29yZS9zcmMvY29tcG9uZW50cy9Ecm9wZG93bkNvbnRhaW5lci9Ecm9wZG93bkNvbnRhaW5lci50c3g=) | 88.33% | [7 Missing :warning: ](https://app.codecov.io/gh/apache/superset/pull/41351?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
<details><summary>Additional details and impacted files</summary>
```diff
@@ Coverage Diff @@
## master #41351 +/- ##
==========================================
+ Coverage 64.37% 64.39% +0.01%
==========================================
Files 2653 2653
Lines 145152 145203 +51
Branches 33491 33502 +11
==========================================
+ Hits 93446 93504 +58
+ Misses 50014 50007 -7
Partials 1692 1692
```
| [Flag](https://app.codecov.io/gh/apache/superset/pull/41351/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Ξ | |
|---|---|---|
| [javascript](https://app.codecov.io/gh/apache/superset/pull/41351/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `68.70% <88.33%> (+0.02%)` | :arrow_up: |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#carryforward-flags-in-the-pull-request-comment) to find out more.
</details>
[:umbrella: View full report in Codecov by Harness](https://app.codecov.io/gh/apache/superset/pull/41351?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
<details><summary> :rocket: New features to boost your workflow: </summary>
- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4879537386
πͺ [Showtime](https://github.com/mistercrunch/superset-showtime) is building environment on [GHA](https://github.com/apache/superset/actions/runs/28685004696) for [1385377](https://github.com/apache/superset/commit/1385377)
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on code in PR #41351:
URL: https://github.com/apache/superset/pull/41351#discussion_r3521961195
##########
superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.tsx:
##########
@@ -220,6 +325,59 @@ export const DropdownContainer = forwardRef(
}
}
+ // A "nothing overflows" verdict on the pass that consumed an item-set-
+ // change reset may reflect a transient mid-reflow measurement. When that
+ // happens, do NOT settle immediately. Instead:
+ // β’ If the rAF hasn't been scheduled yet: schedule it (one-shot) and
+ // return without settling; recalculating stays true so the trigger
+ // remains mounted throughout the confirmation window.
+ // β’ If the rAF is already scheduled (a second layout effect run
+ // triggered by the setItemsWidth call above): also return without
+ // settling for the same reason.
+ // The rAF callback reads the DOM directly at a point where the browser
+ // has reflowed and calls the setters itself. It also resets the guard
+ // refs so subsequent effect runs (e.g. from a real resize) behave
+ // normally.
+ if (
+ newOverflowingIndex === -1 &&
+ pendingConfirmForLengthRef.current === items.length
+ ) {
+ if (!confirmationScheduledRef.current) {
+ confirmationScheduledRef.current = true;
+ const scheduledVersion = confirmVersionRef.current;
+ rafIdRef.current = requestAnimationFrame(() => {
+ rafIdRef.current = 0;
+ if (!mountedRef.current) return;
+ // A newer item-set change superseded this confirmation while the
+ // frame was queued; let the newer one's own confirmation settle.
+ if (confirmVersionRef.current !== scheduledVersion) return;
+ // Reset guard refs so future layout effect runs are unaffected.
+ pendingConfirmForLengthRef.current = -1;
+ confirmationScheduledRef.current = false;
+ hadContentAtLastChangeRef.current = false;
Review Comment:
Addressed in 734f608 β the confirmation rAF callback now no-ops when a settling pass has already cleared the pending confirmation (it checks `confirmVersionRef` for supersession and `pendingConfirmForLengthRef`/`confirmationScheduledRef` for an already-settled state before touching `overflowingIndex`).
##########
superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.tsx:
##########
@@ -220,6 +325,59 @@ export const DropdownContainer = forwardRef(
}
}
+ // A "nothing overflows" verdict on the pass that consumed an item-set-
+ // change reset may reflect a transient mid-reflow measurement. When that
+ // happens, do NOT settle immediately. Instead:
+ // β’ If the rAF hasn't been scheduled yet: schedule it (one-shot) and
+ // return without settling; recalculating stays true so the trigger
+ // remains mounted throughout the confirmation window.
+ // β’ If the rAF is already scheduled (a second layout effect run
+ // triggered by the setItemsWidth call above): also return without
+ // settling for the same reason.
+ // The rAF callback reads the DOM directly at a point where the browser
+ // has reflowed and calls the setters itself. It also resets the guard
+ // refs so subsequent effect runs (e.g. from a real resize) behave
+ // normally.
+ if (
+ newOverflowingIndex === -1 &&
+ pendingConfirmForLengthRef.current === items.length
+ ) {
+ if (!confirmationScheduledRef.current) {
+ confirmationScheduledRef.current = true;
+ const scheduledVersion = confirmVersionRef.current;
+ rafIdRef.current = requestAnimationFrame(() => {
+ rafIdRef.current = 0;
+ if (!mountedRef.current) return;
+ // A newer item-set change superseded this confirmation while the
+ // frame was queued; let the newer one's own confirmation settle.
+ if (confirmVersionRef.current !== scheduledVersion) return;
+ // Reset guard refs so future layout effect runs are unaffected.
+ pendingConfirmForLengthRef.current = -1;
+ confirmationScheduledRef.current = false;
+ hadContentAtLastChangeRef.current = false;
+ const el = containerRef.current;
+ if (!el) {
+ setOverflowingIndex(-1);
+ setRecalculating(false);
+ return;
+ }
+ const kids = Array.from(el.children);
+ const confirmIdx = kids.findIndex(
+ c =>
+ c.getBoundingClientRect().right >
+ el.getBoundingClientRect().right + 1,
+ );
+ setOverflowingIndex(confirmIdx);
+ setRecalculating(false);
+ });
+ }
+ // Either way (just scheduled or already pending): hold off settling so
+ // recalculating stays true and the button guard keeps the trigger mounted.
+ return;
+ }
+
+ pendingConfirmForLengthRef.current = -1;
+ confirmationScheduledRef.current = false;
setOverflowingIndex(newOverflowingIndex);
setRecalculating(false);
Review Comment:
Addressed β the normal settle path now cancels any queued confirmation frame (734f608) and clears `hadContentAtLastChangeRef` (3f365ade38), so a settled state no longer keeps the trigger mounted or lets a stale frame run.
##########
superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.overflow.test.tsx:
##########
@@ -0,0 +1,325 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Overflow-engine regression tests for DropdownContainer.
+ *
+ * jsdom has no real layout, so these tests drive the component's real overflow
+ * recalculation by mocking the two measurement sources it reads:
+ * 1. `useResizeDetector` β supplies the container width.
+ * 2. `getBoundingClientRect` β supplies per-element geometry. The inner
+ * `data-test="container"` spans [0, containerRight]; every child is
+ * ITEM_W wide and laid out left-to-right by its DOM index, so children
+ * whose right edge exceeds `containerRight` overflow.
+ *
+ * This exercises the production code path in DropdownContainer.tsx
+ * (useLayoutEffect β overflowingIndex β notOverflowedItems/overflowedItems β
+ * showDropdownButton) rather than mocking the result.
+ */
+import { screen, render, waitFor, act } from '@superset-ui/core/spec';
+import * as resizeDetector from 'react-resize-detector';
+import { DropdownContainer } from '..';
+
+const ITEM_W = 100;
+// 350px container β at most 3 items (rights 100/200/300) fit before overflow.
+const BAR_WIDTH = 350;
+
+// Mutable so a test can simulate the transient layout window where a freshly
+// enlarged item set is momentarily measured as fitting before reflow settles.
+let containerRight = BAR_WIDTH;
+// Mutable width fed to the component through the mocked resize detector.
+let mockWidth = 0;
+// Stable ref object React attaches the outer node to (mirrors useResizeDetector).
+const fakeRef: { current: HTMLDivElement | null } = { current: null };
+
+const buildRect = (left: number, right: number): DOMRect =>
+ ({
+ left,
+ right,
+ width: right - left,
+ top: 0,
+ bottom: 0,
+ height: 0,
+ x: left,
+ y: 0,
+ toJSON: () => ({}),
+ }) as DOMRect;
+
+const installLayoutMock = () => {
+ HTMLElement.prototype.getBoundingClientRect = function mockRect(
+ this: HTMLElement,
+ ) {
+ const dataTest = this.getAttribute?.('data-test');
+ if (dataTest === 'container') {
+ return buildRect(0, containerRight);
+ }
+ const parent = this.parentElement;
+ if (parent?.getAttribute?.('data-test') === 'container') {
+ const index = Array.prototype.indexOf.call(parent.children, this);
+ return buildRect(index * ITEM_W, index * ITEM_W + ITEM_W);
+ }
+ // Outer wrapper div (its first child is the inner container).
+ if (
+ (this.children[0] as HTMLElement | undefined)?.getAttribute?.(
+ 'data-test',
+ ) === 'container'
+ ) {
+ return buildRect(0, containerRight);
+ }
+ return buildRect(0, 0);
+ };
+};
Review Comment:
Addressed in 3f365ade38 β the original `HTMLElement.prototype.getBoundingClientRect` is captured at module scope and restored in `afterEach` so the mock cannot leak into other suites.
##########
superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.overflow.test.tsx:
##########
@@ -0,0 +1,325 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Overflow-engine regression tests for DropdownContainer.
+ *
+ * jsdom has no real layout, so these tests drive the component's real overflow
+ * recalculation by mocking the two measurement sources it reads:
+ * 1. `useResizeDetector` β supplies the container width.
+ * 2. `getBoundingClientRect` β supplies per-element geometry. The inner
+ * `data-test="container"` spans [0, containerRight]; every child is
+ * ITEM_W wide and laid out left-to-right by its DOM index, so children
+ * whose right edge exceeds `containerRight` overflow.
+ *
+ * This exercises the production code path in DropdownContainer.tsx
+ * (useLayoutEffect β overflowingIndex β notOverflowedItems/overflowedItems β
+ * showDropdownButton) rather than mocking the result.
+ */
+import { screen, render, waitFor, act } from '@superset-ui/core/spec';
+import * as resizeDetector from 'react-resize-detector';
+import { DropdownContainer } from '..';
+
+const ITEM_W = 100;
+// 350px container β at most 3 items (rights 100/200/300) fit before overflow.
+const BAR_WIDTH = 350;
+
+// Mutable so a test can simulate the transient layout window where a freshly
+// enlarged item set is momentarily measured as fitting before reflow settles.
+let containerRight = BAR_WIDTH;
+// Mutable width fed to the component through the mocked resize detector.
+let mockWidth = 0;
+// Stable ref object React attaches the outer node to (mirrors useResizeDetector).
+const fakeRef: { current: HTMLDivElement | null } = { current: null };
+
+const buildRect = (left: number, right: number): DOMRect =>
+ ({
+ left,
+ right,
+ width: right - left,
+ top: 0,
+ bottom: 0,
+ height: 0,
+ x: left,
+ y: 0,
+ toJSON: () => ({}),
+ }) as DOMRect;
+
+const installLayoutMock = () => {
+ HTMLElement.prototype.getBoundingClientRect = function mockRect(
+ this: HTMLElement,
+ ) {
+ const dataTest = this.getAttribute?.('data-test');
+ if (dataTest === 'container') {
+ return buildRect(0, containerRight);
+ }
+ const parent = this.parentElement;
+ if (parent?.getAttribute?.('data-test') === 'container') {
+ const index = Array.prototype.indexOf.call(parent.children, this);
+ return buildRect(index * ITEM_W, index * ITEM_W + ITEM_W);
+ }
+ // Outer wrapper div (its first child is the inner container).
+ if (
+ (this.children[0] as HTMLElement | undefined)?.getAttribute?.(
+ 'data-test',
+ ) === 'container'
+ ) {
+ return buildRect(0, containerRight);
+ }
+ return buildRect(0, 0);
+ };
+};
+
+let resizeSpy: jest.SpyInstance;
+let rafSpy: jest.SpyInstance;
+let cancelRafSpy: jest.SpyInstance;
+
+// Deterministic requestAnimationFrame: the component schedules a one-shot
+// confirmation frame to re-measure after an item-set change. Rather than sleep
+// and hope jsdom's timer-backed rAF fires inside the window, we capture the
+// callbacks and invoke them explicitly via flushRAF(). cancelAnimationFrame
+// removes a queued frame, so the supersession path can be exercised directly.
+let rafQueue: Array<{ id: number; cb: FrameRequestCallback }> = [];
+let rafSeq = 0;
+
+// Run every currently-queued frame once (frames scheduled during the flush are
+// left for the next flush, so a single call models a single browser frame).
+const flushRAF = () => {
+ const pending = rafQueue;
+ rafQueue = [];
+ pending.forEach(({ cb }) => cb(0));
+};
+
+beforeEach(() => {
+ containerRight = BAR_WIDTH;
+ mockWidth = 0;
+ fakeRef.current = null;
+ rafQueue = [];
+ rafSeq = 0;
+ installLayoutMock();
+ global.ResizeObserver = jest.fn().mockImplementation(() => ({
+ observe: jest.fn(),
+ unobserve: jest.fn(),
+ disconnect: jest.fn(),
+ })) as unknown as typeof ResizeObserver;
+ rafSpy = jest
+ .spyOn(window, 'requestAnimationFrame')
+ .mockImplementation((cb: FrameRequestCallback) => {
+ rafSeq += 1;
+ rafQueue.push({ id: rafSeq, cb });
+ return rafSeq;
+ });
+ cancelRafSpy = jest
+ .spyOn(window, 'cancelAnimationFrame')
+ .mockImplementation((id: number) => {
+ rafQueue = rafQueue.filter(frame => frame.id !== id);
+ });
+ resizeSpy = jest
+ .spyOn(resizeDetector, 'useResizeDetector')
+ .mockImplementation(
+ () =>
+ ({ ref: fakeRef, width: mockWidth, height: 50 }) as ReturnType<
+ typeof resizeDetector.useResizeDetector
+ >,
+ );
+});
+
+afterEach(() => {
+ resizeSpy?.mockRestore();
+ rafSpy?.mockRestore();
+ cancelRafSpy?.mockRestore();
+});
Review Comment:
Addressed in 3f365ade38 β the original implementation is restored in `afterEach`.
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "bito-code-review[bot] (via GitHub)" <gi...@apache.org>.
bito-code-review[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4785300003
AI Code Review is in progress (usually takes 3 to 15 minutes unless it's a very large PR).
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4999653879
Closing this one.
The PR targeted a latch in the overflow recalculation: when the item set changes, the reset path zeroes the overflowed items, so the existing `index === -1 && overflowedItems.length > 0` guard can't fire on the pass that follows, and a transient "everything fits" measurement could settle to `-1` with no dependency change left to correct it.
That path is real in the code, but for it to bite, `getBoundingClientRect()` has to report a container wider than its settled width. gBCR forces synchronous layout, so it returns settled geometry rather than mid-reflow geometry β and the resize detector on the container plus the `ResizeObserver` on the children already re-run the recalculation whenever geometry genuinely changes. The behaviour that prompted this never reproduced on master, and #38193 already covers the flicker case it was traced to.
The regression suite here doesn't close that gap either. Against master's component it fails only where it forces `getBoundingClientRect` to return a transient value, or where it asserts on the `requestAnimationFrame` machinery this PR itself introduces; the two tests that measure honestly pass on master unchanged. So it demonstrates that master doesn't recover from a synthetic transient, not that there's a browser-reproducible defect.
On that basis the added ref/rAF coordination isn't carrying its weight in a shared core component. Happy to revisit if a reproduction on master turns up.
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4879601786
πͺ [Showtime](https://github.com/mistercrunch/superset-showtime) deployed environment on [GHA](https://github.com/apache/superset/actions/runs/28685004696) for [1385377](https://github.com/apache/superset/commit/1385377)
β’ **Environment:** http://18.236.196.225:8080 (admin/admin)
β’ **Lifetime:** 48h auto-cleanup
β’ **Updates:** New commits create fresh environments automatically
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4962847563
πͺ [Showtime](https://github.com/mistercrunch/superset-showtime) is building environment on [GHA](https://github.com/apache/superset/actions/runs/29286371982) for [f7c69b3](https://github.com/apache/superset/commit/f7c69b3)
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4977194392
πͺ [Showtime](https://github.com/mistercrunch/superset-showtime) is building environment on [GHA](https://github.com/apache/superset/actions/runs/29391666885) for [7829ad1](https://github.com/apache/superset/commit/7829ad1)
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "sadpandajoe (via GitHub)" <gi...@apache.org>.
sadpandajoe closed pull request #41351: fix(dashboard): keep More filters reachable on cross-filter apply
URL: https://github.com/apache/superset/pull/41351
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #41351:
URL: https://github.com/apache/superset/pull/41351#discussion_r3476401767
##########
superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.tsx:
##########
@@ -220,6 +325,59 @@ export const DropdownContainer = forwardRef(
}
}
+ // A "nothing overflows" verdict on the pass that consumed an item-set-
+ // change reset may reflect a transient mid-reflow measurement. When that
+ // happens, do NOT settle immediately. Instead:
+ // β’ If the rAF hasn't been scheduled yet: schedule it (one-shot) and
+ // return without settling; recalculating stays true so the trigger
+ // remains mounted throughout the confirmation window.
+ // β’ If the rAF is already scheduled (a second layout effect run
+ // triggered by the setItemsWidth call above): also return without
+ // settling for the same reason.
+ // The rAF callback reads the DOM directly at a point where the browser
+ // has reflowed and calls the setters itself. It also resets the guard
+ // refs so subsequent effect runs (e.g. from a real resize) behave
+ // normally.
+ if (
+ newOverflowingIndex === -1 &&
+ pendingConfirmForLengthRef.current === items.length
+ ) {
+ if (!confirmationScheduledRef.current) {
+ confirmationScheduledRef.current = true;
+ const scheduledVersion = confirmVersionRef.current;
+ rafIdRef.current = requestAnimationFrame(() => {
+ rafIdRef.current = 0;
+ if (!mountedRef.current) return;
+ // A newer item-set change superseded this confirmation while the
+ // frame was queued; let the newer one's own confirmation settle.
+ if (confirmVersionRef.current !== scheduledVersion) return;
+ // Reset guard refs so future layout effect runs are unaffected.
+ pendingConfirmForLengthRef.current = -1;
+ confirmationScheduledRef.current = false;
+ hadContentAtLastChangeRef.current = false;
+ const el = containerRef.current;
+ if (!el) {
+ setOverflowingIndex(-1);
+ setRecalculating(false);
+ return;
+ }
+ const kids = Array.from(el.children);
+ const confirmIdx = kids.findIndex(
+ c =>
+ c.getBoundingClientRect().right >
+ el.getBoundingClientRect().right + 1,
+ );
+ setOverflowingIndex(confirmIdx);
+ setRecalculating(false);
+ });
+ }
+ // Either way (just scheduled or already pending): hold off settling so
+ // recalculating stays true and the button guard keeps the trigger mounted.
+ return;
+ }
+
+ pendingConfirmForLengthRef.current = -1;
+ confirmationScheduledRef.current = false;
setOverflowingIndex(newOverflowingIndex);
setRecalculating(false);
Review Comment:
When the layout effect settles normally (i.e. no rAF confirmation is needed), `hadContentAtLastChangeRef` is never cleared and any already-scheduled rAF isn't cancelled. This can cause the dropdown trigger to stay mounted during unrelated future recalculations, and can still allow a previously queued rAF to run after the component has settled. Clear the ref and cancel any queued frame on the settling path.
##########
superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.overflow.test.tsx:
##########
@@ -0,0 +1,325 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Overflow-engine regression tests for DropdownContainer.
+ *
+ * jsdom has no real layout, so these tests drive the component's real overflow
+ * recalculation by mocking the two measurement sources it reads:
+ * 1. `useResizeDetector` β supplies the container width.
+ * 2. `getBoundingClientRect` β supplies per-element geometry. The inner
+ * `data-test="container"` spans [0, containerRight]; every child is
+ * ITEM_W wide and laid out left-to-right by its DOM index, so children
+ * whose right edge exceeds `containerRight` overflow.
+ *
+ * This exercises the production code path in DropdownContainer.tsx
+ * (useLayoutEffect β overflowingIndex β notOverflowedItems/overflowedItems β
+ * showDropdownButton) rather than mocking the result.
+ */
+import { screen, render, waitFor, act } from '@superset-ui/core/spec';
+import * as resizeDetector from 'react-resize-detector';
+import { DropdownContainer } from '..';
+
+const ITEM_W = 100;
+// 350px container β at most 3 items (rights 100/200/300) fit before overflow.
+const BAR_WIDTH = 350;
+
+// Mutable so a test can simulate the transient layout window where a freshly
+// enlarged item set is momentarily measured as fitting before reflow settles.
+let containerRight = BAR_WIDTH;
+// Mutable width fed to the component through the mocked resize detector.
+let mockWidth = 0;
+// Stable ref object React attaches the outer node to (mirrors useResizeDetector).
+const fakeRef: { current: HTMLDivElement | null } = { current: null };
+
+const buildRect = (left: number, right: number): DOMRect =>
+ ({
+ left,
+ right,
+ width: right - left,
+ top: 0,
+ bottom: 0,
+ height: 0,
+ x: left,
+ y: 0,
+ toJSON: () => ({}),
+ }) as DOMRect;
+
+const installLayoutMock = () => {
+ HTMLElement.prototype.getBoundingClientRect = function mockRect(
+ this: HTMLElement,
+ ) {
+ const dataTest = this.getAttribute?.('data-test');
+ if (dataTest === 'container') {
+ return buildRect(0, containerRight);
+ }
+ const parent = this.parentElement;
+ if (parent?.getAttribute?.('data-test') === 'container') {
+ const index = Array.prototype.indexOf.call(parent.children, this);
+ return buildRect(index * ITEM_W, index * ITEM_W + ITEM_W);
+ }
+ // Outer wrapper div (its first child is the inner container).
+ if (
+ (this.children[0] as HTMLElement | undefined)?.getAttribute?.(
+ 'data-test',
+ ) === 'container'
+ ) {
+ return buildRect(0, containerRight);
+ }
+ return buildRect(0, 0);
+ };
+};
+
+let resizeSpy: jest.SpyInstance;
+let rafSpy: jest.SpyInstance;
+let cancelRafSpy: jest.SpyInstance;
+
+// Deterministic requestAnimationFrame: the component schedules a one-shot
+// confirmation frame to re-measure after an item-set change. Rather than sleep
+// and hope jsdom's timer-backed rAF fires inside the window, we capture the
+// callbacks and invoke them explicitly via flushRAF(). cancelAnimationFrame
+// removes a queued frame, so the supersession path can be exercised directly.
+let rafQueue: Array<{ id: number; cb: FrameRequestCallback }> = [];
+let rafSeq = 0;
+
+// Run every currently-queued frame once (frames scheduled during the flush are
+// left for the next flush, so a single call models a single browser frame).
+const flushRAF = () => {
+ const pending = rafQueue;
+ rafQueue = [];
+ pending.forEach(({ cb }) => cb(0));
+};
+
+beforeEach(() => {
+ containerRight = BAR_WIDTH;
+ mockWidth = 0;
+ fakeRef.current = null;
+ rafQueue = [];
+ rafSeq = 0;
+ installLayoutMock();
+ global.ResizeObserver = jest.fn().mockImplementation(() => ({
+ observe: jest.fn(),
+ unobserve: jest.fn(),
+ disconnect: jest.fn(),
+ })) as unknown as typeof ResizeObserver;
+ rafSpy = jest
+ .spyOn(window, 'requestAnimationFrame')
+ .mockImplementation((cb: FrameRequestCallback) => {
+ rafSeq += 1;
+ rafQueue.push({ id: rafSeq, cb });
+ return rafSeq;
+ });
+ cancelRafSpy = jest
+ .spyOn(window, 'cancelAnimationFrame')
+ .mockImplementation((id: number) => {
+ rafQueue = rafQueue.filter(frame => frame.id !== id);
+ });
+ resizeSpy = jest
+ .spyOn(resizeDetector, 'useResizeDetector')
+ .mockImplementation(
+ () =>
+ ({ ref: fakeRef, width: mockWidth, height: 50 }) as ReturnType<
+ typeof resizeDetector.useResizeDetector
+ >,
+ );
+});
+
+afterEach(() => {
+ resizeSpy?.mockRestore();
+ rafSpy?.mockRestore();
+ cancelRafSpy?.mockRestore();
+});
Review Comment:
Restore the original `getBoundingClientRect` implementation in `afterEach` so this suite doesn't affect other tests.
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #41351:
URL: https://github.com/apache/superset/pull/41351#discussion_r3476401787
##########
superset-frontend/packages/superset-ui-core/src/components/DropdownContainer/DropdownContainer.overflow.test.tsx:
##########
@@ -0,0 +1,325 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Overflow-engine regression tests for DropdownContainer.
+ *
+ * jsdom has no real layout, so these tests drive the component's real overflow
+ * recalculation by mocking the two measurement sources it reads:
+ * 1. `useResizeDetector` β supplies the container width.
+ * 2. `getBoundingClientRect` β supplies per-element geometry. The inner
+ * `data-test="container"` spans [0, containerRight]; every child is
+ * ITEM_W wide and laid out left-to-right by its DOM index, so children
+ * whose right edge exceeds `containerRight` overflow.
+ *
+ * This exercises the production code path in DropdownContainer.tsx
+ * (useLayoutEffect β overflowingIndex β notOverflowedItems/overflowedItems β
+ * showDropdownButton) rather than mocking the result.
+ */
+import { screen, render, waitFor, act } from '@superset-ui/core/spec';
+import * as resizeDetector from 'react-resize-detector';
+import { DropdownContainer } from '..';
+
+const ITEM_W = 100;
+// 350px container β at most 3 items (rights 100/200/300) fit before overflow.
+const BAR_WIDTH = 350;
+
+// Mutable so a test can simulate the transient layout window where a freshly
+// enlarged item set is momentarily measured as fitting before reflow settles.
+let containerRight = BAR_WIDTH;
+// Mutable width fed to the component through the mocked resize detector.
+let mockWidth = 0;
+// Stable ref object React attaches the outer node to (mirrors useResizeDetector).
+const fakeRef: { current: HTMLDivElement | null } = { current: null };
+
+const buildRect = (left: number, right: number): DOMRect =>
+ ({
+ left,
+ right,
+ width: right - left,
+ top: 0,
+ bottom: 0,
+ height: 0,
+ x: left,
+ y: 0,
+ toJSON: () => ({}),
+ }) as DOMRect;
+
+const installLayoutMock = () => {
+ HTMLElement.prototype.getBoundingClientRect = function mockRect(
+ this: HTMLElement,
+ ) {
+ const dataTest = this.getAttribute?.('data-test');
+ if (dataTest === 'container') {
+ return buildRect(0, containerRight);
+ }
+ const parent = this.parentElement;
+ if (parent?.getAttribute?.('data-test') === 'container') {
+ const index = Array.prototype.indexOf.call(parent.children, this);
+ return buildRect(index * ITEM_W, index * ITEM_W + ITEM_W);
+ }
+ // Outer wrapper div (its first child is the inner container).
+ if (
+ (this.children[0] as HTMLElement | undefined)?.getAttribute?.(
+ 'data-test',
+ ) === 'container'
+ ) {
+ return buildRect(0, containerRight);
+ }
+ return buildRect(0, 0);
+ };
+};
Review Comment:
This test overwrites `HTMLElement.prototype.getBoundingClientRect` but never restores it, which can leak into other test files and create hard-to-diagnose failures. Capture the original implementation at module scope so it can be restored in `afterEach`/`afterAll`.
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org
Re: [PR] fix(dashboard): keep More filters reachable on cross-filter apply [superset]
Posted by "netlify[bot] (via GitHub)" <gi...@apache.org>.
netlify[bot] commented on PR #41351:
URL: https://github.com/apache/superset/pull/41351#issuecomment-4804908294
### <span aria-hidden="true">β
</span> Deploy Preview for *superset-docs-preview* ready!
| Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">π¨</span> Latest commit | 734f608f4d16a81b636ba315269c95b115a03e82 |
|<span aria-hidden="true">π</span> Latest deploy log | https://app.netlify.com/projects/superset-docs-preview/deploys/6a3db2849934fe00087770d0 |
|<span aria-hidden="true">π</span> Deploy Preview | [https://deploy-preview-41351--superset-docs-preview.netlify.app](https://deploy-preview-41351--superset-docs-preview.netlify.app) |
|<span aria-hidden="true">π±</span> Preview on mobile | <details><summary> Toggle QR Code... </summary><br /><br /><br /><br />_Use your smartphone camera to open QR code link._</details> |
|<span aria-hidden="true">π€</span> Make changes | [Run an agent on this branch](https://app.netlify.com/projects/superset-docs-preview/agent-runs#JcpbCoAgEEDRvcx3wpCR1g5ahk8KrJExehDtPaG_e-E8kJnWvMMI0IBls7m5dlwuEZe0B7aGhWMq5V9BR-CY6Kzah5zonnz1vZHetrobBtnFgIhaKYUe4f0A) |
---
<!-- [superset-docs-preview Preview](https://deploy-preview-41351--superset-docs-preview.netlify.app) -->
_To edit notification comments on pull requests, go to your [Netlify project configuration](https://app.netlify.com/projects/superset-docs-preview/configuration/notifications#deploy-notifications)._
--
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: notifications-unsubscribe@superset.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org