This is an automated email from the ASF dual-hosted git repository. kgabryje pushed a commit to branch what-if in repository https://gitbox.apache.org/repos/asf/superset.git
commit 45f198240746dd81a6a7e348e17778b541051fcc Author: Kamil Gabryjelski <[email protected]> AuthorDate: Fri Dec 19 00:54:56 2025 +0100 Smol layout fixes --- .../components/WhatIfDrawer/FilterButton.tsx | 102 ++++++++++++++ .../components/WhatIfDrawer/FilterSection.tsx | 153 --------------------- .../WhatIfDrawer/ModificationsDisplay.tsx | 7 +- .../dashboard/components/WhatIfDrawer/index.tsx | 42 +++++- .../dashboard/components/WhatIfDrawer/styles.ts | 2 +- 5 files changed, 144 insertions(+), 162 deletions(-) diff --git a/superset-frontend/src/dashboard/components/WhatIfDrawer/FilterButton.tsx b/superset-frontend/src/dashboard/components/WhatIfDrawer/FilterButton.tsx new file mode 100644 index 0000000000..071a689881 --- /dev/null +++ b/superset-frontend/src/dashboard/components/WhatIfDrawer/FilterButton.tsx @@ -0,0 +1,102 @@ +/** + * 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. + */ + +import { memo } from 'react'; +import { t } from '@superset-ui/core'; +import { Tooltip, Popover } from '@superset-ui/core/components'; +import { Icons } from '@superset-ui/core/components/Icons'; +import { Datasource } from 'src/dashboard/types'; +import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter'; +import AdhocFilterEditPopover from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopover'; +import { FilterButtonStyled, FilterPopoverContent } from './styles'; + +interface FilterButtonProps { + filterPopoverVisible: boolean; + currentAdhocFilter: AdhocFilter | null; + selectedColumn: string | undefined; + selectedDatasource: Datasource | null; + filterColumnOptions: Datasource['columns']; + onOpenFilterPopover: () => void; + onFilterPopoverVisibleChange: (visible: boolean) => void; + onFilterChange: (adhocFilter: AdhocFilter) => void; + onFilterPopoverClose: () => void; + onFilterPopoverResize: () => void; +} + +/** + * Component for rendering the filter button with popover. + * Uses memo to prevent unnecessary re-renders when parent state changes + * that don't affect this component. + */ +const FilterButton = memo(function FilterButton({ + filterPopoverVisible, + currentAdhocFilter, + selectedColumn, + selectedDatasource, + filterColumnOptions, + onOpenFilterPopover, + onFilterPopoverVisibleChange, + onFilterChange, + onFilterPopoverClose, + onFilterPopoverResize, +}: FilterButtonProps) { + return ( + <Popover + open={filterPopoverVisible} + onOpenChange={onFilterPopoverVisibleChange} + trigger="click" + placement="left" + destroyOnHidden + content={ + currentAdhocFilter && selectedDatasource ? ( + <FilterPopoverContent> + <AdhocFilterEditPopover + adhocFilter={currentAdhocFilter} + options={filterColumnOptions} + datasource={selectedDatasource} + onChange={onFilterChange} + onClose={onFilterPopoverClose} + onResize={onFilterPopoverResize} + requireSave + /> + </FilterPopoverContent> + ) : null + } + > + <Tooltip + title={ + selectedColumn + ? t('Add filter to scope the modification') + : t('Select a column first') + } + > + <FilterButtonStyled + onClick={onOpenFilterPopover} + disabled={!selectedColumn || !selectedDatasource} + aria-label={t('Add filter')} + buttonStyle="tertiary" + > + <Icons.FilterOutlined iconSize="m" /> + </FilterButtonStyled> + </Tooltip> + </Popover> + ); +}); + +export default FilterButton; diff --git a/superset-frontend/src/dashboard/components/WhatIfDrawer/FilterSection.tsx b/superset-frontend/src/dashboard/components/WhatIfDrawer/FilterSection.tsx deleted file mode 100644 index 16ad32555f..0000000000 --- a/superset-frontend/src/dashboard/components/WhatIfDrawer/FilterSection.tsx +++ /dev/null @@ -1,153 +0,0 @@ -/** - * 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. - */ - -import { memo } from 'react'; -import { t } from '@superset-ui/core'; -import { css, useTheme } from '@apache-superset/core/ui'; -import { Tooltip, Tag, Popover } from '@superset-ui/core/components'; -import { Icons } from '@superset-ui/core/components/Icons'; -import { WhatIfFilter, Datasource } from 'src/dashboard/types'; -import AdhocFilter from 'src/explore/components/controls/FilterControl/AdhocFilter'; -import AdhocFilterEditPopover from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopover'; -import { - FilterButton, - FilterPopoverContent, - FiltersSection, - FilterTagsContainer, - Label, -} from './styles'; - -interface FilterSectionProps { - filters: WhatIfFilter[]; - filterPopoverVisible: boolean; - currentAdhocFilter: AdhocFilter | null; - selectedColumn: string | undefined; - selectedDatasource: Datasource | null; - filterColumnOptions: Datasource['columns']; - onOpenFilterPopover: () => void; - onFilterPopoverVisibleChange: (visible: boolean) => void; - onFilterChange: (adhocFilter: AdhocFilter) => void; - onFilterPopoverClose: () => void; - onFilterPopoverResize: () => void; - onEditFilter: (index: number) => void; - onRemoveFilter: (e: React.MouseEvent, index: number) => void; - formatFilterLabel: (filter: WhatIfFilter) => string; -} - -/** - * Component for rendering the filter button and filter tags. - * Uses memo to prevent unnecessary re-renders when parent state changes - * that don't affect this component. - */ -const FilterSection = memo(function FilterSection({ - filters, - filterPopoverVisible, - currentAdhocFilter, - selectedColumn, - selectedDatasource, - filterColumnOptions, - onOpenFilterPopover, - onFilterPopoverVisibleChange, - onFilterChange, - onFilterPopoverClose, - onFilterPopoverResize, - onEditFilter, - onRemoveFilter, - formatFilterLabel, -}: FilterSectionProps) { - const theme = useTheme(); - - return ( - <> - <Popover - open={filterPopoverVisible} - onOpenChange={onFilterPopoverVisibleChange} - trigger="click" - placement="left" - destroyOnHidden - content={ - currentAdhocFilter && selectedDatasource ? ( - <FilterPopoverContent> - <AdhocFilterEditPopover - adhocFilter={currentAdhocFilter} - options={filterColumnOptions} - datasource={selectedDatasource} - onChange={onFilterChange} - onClose={onFilterPopoverClose} - onResize={onFilterPopoverResize} - requireSave - /> - </FilterPopoverContent> - ) : null - } - > - <Tooltip - title={ - selectedColumn - ? t('Add filter to scope the modification') - : t('Select a column first') - } - > - <FilterButton - onClick={onOpenFilterPopover} - disabled={!selectedColumn || !selectedDatasource} - aria-label={t('Add filter')} - buttonStyle="tertiary" - > - <Icons.FilterOutlined iconSize="m" /> - </FilterButton> - </Tooltip> - </Popover> - - {filters.length > 0 && ( - <FiltersSection> - <Label - css={css` - font-size: ${theme.fontSizeSM}px; - color: ${theme.colorTextSecondary}; - `} - > - {t('Filters')} - </Label> - <FilterTagsContainer> - {filters.map((filter, index) => ( - <Tag - key={`${filter.col}-${filter.op}-${index}`} - closable - onClose={e => onRemoveFilter(e, index)} - onClick={() => onEditFilter(index)} - css={css` - cursor: pointer; - margin: 0; - &:hover { - opacity: 0.8; - } - `} - > - {formatFilterLabel(filter)} - </Tag> - ))} - </FilterTagsContainer> - </FiltersSection> - )} - </> - ); -}); - -export default FilterSection; diff --git a/superset-frontend/src/dashboard/components/WhatIfDrawer/ModificationsDisplay.tsx b/superset-frontend/src/dashboard/components/WhatIfDrawer/ModificationsDisplay.tsx index 44f19241d5..825c1544b7 100644 --- a/superset-frontend/src/dashboard/components/WhatIfDrawer/ModificationsDisplay.tsx +++ b/superset-frontend/src/dashboard/components/WhatIfDrawer/ModificationsDisplay.tsx @@ -81,7 +81,7 @@ const ModificationsDisplay = memo(function ModificationsDisplay({ : theme.colorError}; `} > - {formatPercentageChange(mod.multiplier, 1)} + {formatPercentageChange(mod.multiplier, 0)} </span> </Tag> ))} @@ -103,7 +103,10 @@ const ModificationsDisplay = memo(function ModificationsDisplay({ .filter(mod => mod.reasoning) .map((mod, idx) => ( <AIReasoningItem key={idx}> - <strong>{mod.column}:</strong> {mod.reasoning} + <strong> + {mod.column} {formatPercentageChange(mod.multiplier, 0)} + </strong> + <div>{mod.reasoning}</div> </AIReasoningItem> ))} </AIReasoningContent> diff --git a/superset-frontend/src/dashboard/components/WhatIfDrawer/index.tsx b/superset-frontend/src/dashboard/components/WhatIfDrawer/index.tsx index 7d00748bcf..5718de1fc2 100644 --- a/superset-frontend/src/dashboard/components/WhatIfDrawer/index.tsx +++ b/superset-frontend/src/dashboard/components/WhatIfDrawer/index.tsx @@ -25,6 +25,7 @@ import { Select, Checkbox, Tooltip, + Tag, CheckboxChangeEvent, } from '@superset-ui/core/components'; import Slider from '@superset-ui/core/components/Slider'; @@ -33,7 +34,7 @@ import { useNumericColumns } from 'src/dashboard/util/useNumericColumns'; import { RootState, Datasource } from 'src/dashboard/types'; import WhatIfAIInsights from './WhatIfAIInsights'; import HarryPotterWandLoader from './HarryPotterWandLoader'; -import FilterSection from './FilterSection'; +import FilterButton from './FilterButton'; import ModificationsDisplay from './ModificationsDisplay'; import { useWhatIfFilters } from './useWhatIfFilters'; import { useWhatIfApply } from './useWhatIfApply'; @@ -58,6 +59,8 @@ import { CheckboxContainer, ColumnSelectRow, ColumnSelectWrapper, + FiltersSection, + FilterTagsContainer, } from './styles'; export { WHAT_IF_PANEL_WIDTH }; @@ -199,8 +202,7 @@ const WhatIfPanel = ({ onClose, topOffset }: WhatIfPanelProps) => { ariaLabel={t('Select column to adjust')} /> </ColumnSelectWrapper> - <FilterSection - filters={filters} + <FilterButton filterPopoverVisible={filterPopoverVisible} currentAdhocFilter={currentAdhocFilter} selectedColumn={selectedColumn} @@ -211,11 +213,39 @@ const WhatIfPanel = ({ onClose, topOffset }: WhatIfPanelProps) => { onFilterChange={handleFilterChange} onFilterPopoverClose={handleFilterPopoverClose} onFilterPopoverResize={handleFilterPopoverResize} - onEditFilter={handleEditFilter} - onRemoveFilter={handleRemoveFilter} - formatFilterLabel={formatFilterLabel} /> </ColumnSelectRow> + {filters.length > 0 && ( + <FiltersSection> + <Label + css={css` + font-size: ${theme.fontSizeSM}px; + color: ${theme.colorTextSecondary}; + `} + > + {t('Filters')} + </Label> + <FilterTagsContainer> + {filters.map((filter, index) => ( + <Tag + key={`${filter.col}-${filter.op}-${index}`} + closable + onClose={e => handleRemoveFilter(e, index)} + onClick={() => handleEditFilter(index)} + css={css` + cursor: pointer; + margin: 0; + &:hover { + opacity: 0.8; + } + `} + > + {formatFilterLabel(filter)} + </Tag> + ))} + </FilterTagsContainer> + </FiltersSection> + )} </FormSection> <FormSection> diff --git a/superset-frontend/src/dashboard/components/WhatIfDrawer/styles.ts b/superset-frontend/src/dashboard/components/WhatIfDrawer/styles.ts index 34154b061d..07b19317f0 100644 --- a/superset-frontend/src/dashboard/components/WhatIfDrawer/styles.ts +++ b/superset-frontend/src/dashboard/components/WhatIfDrawer/styles.ts @@ -175,7 +175,7 @@ export const ColumnSelectWrapper = styled.div` min-width: 0; `; -export const FilterButton = styled(Button)` +export const FilterButtonStyled = styled(Button)` flex-shrink: 0; padding: 0 ${({ theme }) => theme.sizeUnit * 2}px; `;
