Skip to content

Commit 1388a62

Browse files
authored
fix(filters): fix filter / customization name not updating in sidebar in real time (#37358)
1 parent 6a6b9b5 commit 1388a62

3 files changed

Lines changed: 66 additions & 4 deletions

File tree

superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/ConfigModalSidebar/ConfigModalSidebar.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
import { FC, ReactNode } from 'react';
19+
import { FC, ReactNode, useCallback } from 'react';
2020
import { t } from '@apache-superset/core';
2121
import { NativeFilterType, ChartCustomizationType } from '@superset-ui/core';
2222
import { styled } from '@apache-superset/core/ui';
@@ -77,6 +77,7 @@ export interface ConfigModalSidebarProps {
7777
sourceType: 'filter' | 'customization',
7878
targetType: 'filter' | 'customization',
7979
) => void;
80+
itemTitles?: Record<string, string>;
8081
}
8182

8283
const ConfigModalSidebar: FC<ConfigModalSidebarProps> = ({
@@ -99,7 +100,13 @@ const ConfigModalSidebar: FC<ConfigModalSidebarProps> = ({
99100
restoreItem,
100101
onCollapseChange,
101102
onCrossListDrop,
103+
itemTitles,
102104
}) => {
105+
const getTitle = useCallback(
106+
(id: string) => itemTitles?.[id] ?? getItemTitle(id),
107+
[itemTitles, getItemTitle],
108+
);
109+
103110
const handleFilterCrossListDrop = (
104111
sourceId: string,
105112
targetIndex: number,
@@ -150,7 +157,7 @@ const ConfigModalSidebar: FC<ConfigModalSidebarProps> = ({
150157
items={filterOrderedIds}
151158
removedItems={filterRemovedItems}
152159
erroredItems={filterErroredItems}
153-
getItemTitle={getItemTitle}
160+
getItemTitle={getTitle}
154161
onChange={onChange}
155162
onRearrange={onRearrange}
156163
onRemove={onRemove}
@@ -172,7 +179,7 @@ const ConfigModalSidebar: FC<ConfigModalSidebarProps> = ({
172179
items={customizationOrderedIds}
173180
removedItems={customizationRemovedItems}
174181
erroredItems={customizationErroredItems}
175-
getItemTitle={getItemTitle}
182+
getItemTitle={getTitle}
176183
onChange={onChange}
177184
onRearrange={onRearrange}
178185
onRemove={onRemove}

superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.test.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,45 @@ test('rearranges three filters and deletes one of them', async () => {
630630
);
631631
});
632632

633+
test('updates sidebar title when filter name changes', async () => {
634+
const nativeFilterConfig = [
635+
buildNativeFilter('NATIVE_FILTER-1', 'state', []),
636+
buildNativeFilter('NATIVE_FILTER-2', 'country', []),
637+
];
638+
639+
const state = {
640+
...defaultState(),
641+
dashboardInfo: {
642+
metadata: {
643+
native_filter_configuration: nativeFilterConfig,
644+
},
645+
},
646+
dashboardLayout,
647+
};
648+
649+
defaultRender(state, {
650+
...props,
651+
createNewOnOpen: false,
652+
});
653+
654+
const filterNameInput = screen.getByRole('textbox', {
655+
name: FILTER_NAME_REGEX,
656+
});
657+
658+
const filterContainer = screen.getByTestId('filter-title-container');
659+
const tabsBeforeChange = within(filterContainer).getAllByRole('tab');
660+
661+
expect(tabsBeforeChange[0]).not.toHaveTextContent('New Filter Name');
662+
663+
await userEvent.clear(filterNameInput);
664+
await userEvent.type(filterNameInput, 'New Filter Name');
665+
666+
await waitFor(() => {
667+
const tabsAfterChange = within(filterContainer).getAllByRole('tab');
668+
expect(tabsAfterChange[0]).toHaveTextContent('New Filter Name');
669+
});
670+
});
671+
633672
test('modifies the name of a filter', async () => {
634673
jest.useFakeTimers();
635674
try {

superset-frontend/src/dashboard/components/nativeFilters/FiltersConfigModal/FiltersConfigModal.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,17 @@ function FiltersConfigModal({
450450
? Icons.FullscreenExitOutlined
451451
: Icons.FullscreenOutlined;
452452

453-
const handleValuesChange = useMemo(
453+
const [formValuesVersion, setFormValuesVersion] = useState(0);
454+
455+
const itemTitles = useMemo(() => {
456+
const titles: Record<string, string> = {};
457+
[...filterIds, ...chartCustomizationIds].forEach(id => {
458+
titles[id] = modalSaveLogic.getItemTitle(id);
459+
});
460+
return titles;
461+
}, [filterIds, chartCustomizationIds, modalSaveLogic, formValuesVersion]);
462+
463+
const debouncedErrorHandling = useMemo(
454464
() =>
455465
debounce(() => {
456466
setSaveAlertVisible(false);
@@ -459,6 +469,11 @@ function FiltersConfigModal({
459469
[modalSaveLogic],
460470
);
461471

472+
const handleValuesChange = useCallback(() => {
473+
setFormValuesVersion(prev => prev + 1);
474+
debouncedErrorHandling();
475+
}, [debouncedErrorHandling]);
476+
462477
const handleActiveFilterPanelChange = useCallback(
463478
(key: string | string[]) => setActiveFilterPanelKey(key),
464479
[],
@@ -557,6 +572,7 @@ function FiltersConfigModal({
557572
customizationErroredItems={customizationState.erroredIds}
558573
activeCollapseKeys={activeCollapseKeys}
559574
getItemTitle={modalSaveLogic.getItemTitle}
575+
itemTitles={itemTitles}
560576
onAddFilter={filterOperations.addFilter}
561577
onAddCustomization={
562578
customizationOperations.addChartCustomization

0 commit comments

Comments
 (0)