From a7069e60e24492851ad48872a580be04eada8b0f Mon Sep 17 00:00:00 2001 From: Mehmet Salih Yavuz Date: Wed, 13 Nov 2024 14:07:45 +0300 Subject: [PATCH] refactor(input): Migrate Input component to Ant Design 5 (#30730) --- .../cypress/e2e/explore/control.test.ts | 2 +- superset-frontend/src/GlobalStyles.tsx | 2 +- .../Chart/DrillBy/DrillByMenuItems.tsx | 28 ++-- .../Datasource/ChangeDatasourceModal.tsx | 4 +- .../src/components/Input/Input.stories.tsx | 138 ++++++++++++++++++ .../src/components/Input/Input.test.tsx | 35 +++++ .../src/components/Input/index.tsx | 19 +-- .../controls/BoundsControl.test.jsx | 3 +- .../components/controls/BoundsControl.tsx | 8 +- .../DateFilterControl/DateFilterLabel.tsx | 2 +- .../VizTypeControl/VizTypeGallery.tsx | 2 +- .../src/features/alerts/AlertReportModal.tsx | 10 +- .../components/AlertReportCronScheduler.tsx | 13 +- .../features/rls/RowLevelSecurityModal.tsx | 2 +- superset-frontend/src/theme/index.ts | 14 ++ 15 files changed, 237 insertions(+), 45 deletions(-) create mode 100644 superset-frontend/src/components/Input/Input.stories.tsx create mode 100644 superset-frontend/src/components/Input/Input.test.tsx diff --git a/superset-frontend/cypress-base/cypress/e2e/explore/control.test.ts b/superset-frontend/cypress-base/cypress/e2e/explore/control.test.ts index ccdfcd4512c7d..5fd49efa01908 100644 --- a/superset-frontend/cypress-base/cypress/e2e/explore/control.test.ts +++ b/superset-frontend/cypress-base/cypress/e2e/explore/control.test.ts @@ -234,7 +234,7 @@ describe('Time range filter', () => { cy.get('[data-test=time-range-trigger]').click(); cy.get('[data-test=custom-frame]').then(() => { - cy.get('.ant-input-number-input-wrap > input') + cy.get('.antd5-input-number-input-wrap > input') .invoke('attr', 'value') .should('eq', '7'); }); diff --git a/superset-frontend/src/GlobalStyles.tsx b/superset-frontend/src/GlobalStyles.tsx index b9cb0e55013e0..b0b57133dac15 100644 --- a/superset-frontend/src/GlobalStyles.tsx +++ b/superset-frontend/src/GlobalStyles.tsx @@ -70,7 +70,7 @@ export const GlobalStyles = () => ( } } .column-config-popover { - & .ant-input-number { + & .antd5-input-number { width: 100%; } && .btn-group svg { diff --git a/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx b/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx index b80417a130079..47666db7802f0 100644 --- a/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx +++ b/superset-frontend/src/components/Chart/DrillBy/DrillByMenuItems.tsx @@ -45,7 +45,6 @@ import { import rison from 'rison'; import { debounce } from 'lodash'; import { FixedSizeList as List } from 'react-window'; -import { AntdInput } from 'src/components'; import Icons from 'src/components/Icons'; import { Input } from 'src/components/Input'; import { useToasts } from 'src/components/MessageToasts/withToasts'; @@ -55,6 +54,7 @@ import { supersetGetCache, } from 'src/utils/cachedSupersetGet'; import { useVerboseMap } from 'src/hooks/apiResources/datasets'; +import { InputRef } from 'antd-v5'; import { MenuItemTooltip } from '../DisabledMenuItemTooltip'; import DrillByModal from './DrillByModal'; import { getSubmenuYOffset } from '../utils'; @@ -114,11 +114,12 @@ export const DrillByMenuItems = ({ const { addDangerToast } = useToasts(); const [isLoadingColumns, setIsLoadingColumns] = useState(true); const [searchInput, setSearchInput] = useState(''); + const [debouncedSearchInput, setDebouncedSearchInput] = useState(''); const [dataset, setDataset] = useState(); const [columns, setColumns] = useState([]); const [showModal, setShowModal] = useState(false); const [currentColumn, setCurrentColumn] = useState(); - const ref = useRef(null); + const ref = useRef(null); const showSearch = loadDrillByOptions || columns.length > SHOW_COLUMNS_SEARCH_THRESHOLD; const handleSelection = useCallback( @@ -138,11 +139,11 @@ export const DrillByMenuItems = ({ useEffect(() => { if (open) { - ref.current?.input.focus({ preventScroll: true }); + ref.current?.input?.focus({ preventScroll: true }); } else { // Reset search input when menu is closed - ref.current?.setValue(''); setSearchInput(''); + setDebouncedSearchInput(''); } }, [open]); @@ -207,19 +208,27 @@ export const DrillByMenuItems = ({ hasDrillBy, ]); - const handleInput = debounce( - (value: string) => setSearchInput(value), - FAST_DEBOUNCE, + const debouncedSetSearchInput = useMemo( + () => + debounce((value: string) => { + setDebouncedSearchInput(value); + }, FAST_DEBOUNCE), + [], ); + const handleInput = (value: string) => { + setSearchInput(value); + debouncedSetSearchInput(value); + }; + const filteredColumns = useMemo( () => columns.filter(column => (column.verbose_name || column.column_name) .toLowerCase() - .includes(searchInput.toLowerCase()), + .includes(debouncedSearchInput.toLowerCase()), ), - [columns, searchInput], + [columns, debouncedSearchInput], ); const submenuYOffset = useMemo( @@ -311,6 +320,7 @@ export const DrillByMenuItems = ({ margin: ${theme.gridUnit * 2}px ${theme.gridUnit * 3}px; box-shadow: none; `} + value={searchInput} /> )} {isLoadingColumns ? ( diff --git a/superset-frontend/src/components/Datasource/ChangeDatasourceModal.tsx b/superset-frontend/src/components/Datasource/ChangeDatasourceModal.tsx index ed39a362229b6..e02ad68a7f145 100644 --- a/superset-frontend/src/components/Datasource/ChangeDatasourceModal.tsx +++ b/superset-frontend/src/components/Datasource/ChangeDatasourceModal.tsx @@ -41,13 +41,13 @@ import Dataset from 'src/types/Dataset'; import { useDebouncedEffect } from 'src/explore/exploreUtils'; import { SLOW_DEBOUNCE } from 'src/constants'; import Loading from 'src/components/Loading'; -import { AntdInput } from 'src/components'; import { Input } from 'src/components/Input'; import { PAGE_SIZE as DATASET_PAGE_SIZE, SORT_BY as DATASET_SORT_BY, } from 'src/features/datasets/constants'; import withToasts from 'src/components/MessageToasts/withToasts'; +import { InputRef } from 'antd-v5'; import FacePile from '../FacePile'; const CONFIRM_WARNING_MESSAGE = t( @@ -115,7 +115,7 @@ const ChangeDatasourceModal: FunctionComponent = ({ const [sortBy, setSortBy] = useState(DATASET_SORT_BY); const [confirmChange, setConfirmChange] = useState(false); const [confirmedDataset, setConfirmedDataset] = useState(); - const searchRef = useRef(null); + const searchRef = useRef(null); const { state: { loading, resourceCollection, resourceCount }, diff --git a/superset-frontend/src/components/Input/Input.stories.tsx b/superset-frontend/src/components/Input/Input.stories.tsx new file mode 100644 index 0000000000000..4023c53d97e0f --- /dev/null +++ b/superset-frontend/src/components/Input/Input.stories.tsx @@ -0,0 +1,138 @@ +/** + * 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 { InputProps, TextAreaProps } from 'antd-v5/lib/input'; +import { InputNumberProps } from 'antd-v5/lib/input-number'; +import { AntdThemeProvider } from 'src/components/AntdThemeProvider'; +import { Input, TextArea, InputNumber } from '.'; + +export default { + title: 'Input', + component: Input, +}; + +export const InteractiveInput = (args: InputProps) => ( + + + +); + +export const InteractiveInputNumber = (args: InputNumberProps) => ( + + + +); + +export const InteractiveTextArea = (args: TextAreaProps) => ( + +