diff --git a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx index d7417ee78b4..7de658c7186 100644 --- a/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx +++ b/superset-frontend/plugins/plugin-chart-table/src/controlPanel.tsx @@ -274,7 +274,7 @@ const config: ControlPanelConfig = { visibility: ({ controls }) => { const dttmLookup = Object.fromEntries( ensureIsArray(controls?.groupby?.options).map(option => [ - option.column_name, + (option.column_name || '').toLowerCase(), option.is_dttm, ]), ); @@ -285,7 +285,7 @@ const config: ControlPanelConfig = { return true; } if (isPhysicalColumn(selection)) { - return !!dttmLookup[selection]; + return !!dttmLookup[(selection || '').toLowerCase()]; } return false; }) diff --git a/superset-frontend/plugins/plugin-chart-table/test/controlPanel.test.ts b/superset-frontend/plugins/plugin-chart-table/test/controlPanel.test.ts new file mode 100644 index 00000000000..e09034fe650 --- /dev/null +++ b/superset-frontend/plugins/plugin-chart-table/test/controlPanel.test.ts @@ -0,0 +1,77 @@ +/* eslint-disable camelcase */ +/** + * 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 + */ + +import { + ControlPanelConfig, + ControlPanelsContainerProps, + ControlState, + CustomControlItem, +} from '@superset-ui/chart-controls'; +import config from '../src/controlPanel'; + +type VisibilityFn = ( + props: ControlPanelsContainerProps, + control?: ControlState, +) => boolean; + +function isControlWithVisibility( + controlItem: unknown, +): controlItem is CustomControlItem & { + config: Required & { visibility: VisibilityFn }; +} { + return ( + typeof controlItem === 'object' && + controlItem !== null && + 'name' in controlItem && + 'config' in controlItem && + typeof (controlItem as CustomControlItem).config?.visibility === 'function' + ); +} + +function getVisibility( + panel: ControlPanelConfig, + controlName: string, +): VisibilityFn { + const item = (panel.controlPanelSections || []) + .flatMap(section => section?.controlSetRows || []) + .flat() + .find(c => isControlWithVisibility(c) && c.name === controlName); + + if (!isControlWithVisibility(item)) { + throw new Error(`Control "${controlName}" with visibility not found`); + } + return item.config.visibility; +} + +function mkProps( + groupbyValue: string[], + options = [ + { column_name: 'ORDERDATE', is_dttm: true }, + { column_name: 'some_other_col', is_dttm: false }, + ], +): ControlPanelsContainerProps { + return { + controls: { + groupby: { value: groupbyValue, options }, + }, + } as unknown as ControlPanelsContainerProps; +} + +test('time_grain_sqla visibility should be case-insensitive', () => { + const vis = getVisibility(config, 'time_grain_sqla'); + const controlState = {} as ControlState; + + expect(vis(mkProps(['orderdate']), controlState)).toBe(true); + expect(vis(mkProps(['ORDERDATE']), controlState)).toBe(true); + expect(vis(mkProps(['some_other_col']), controlState)).toBe(false); +});