diff --git a/frontend/src/metadata/components/popover/column-popover/custom-dropdown-menu.js b/frontend/src/metadata/components/popover/column-popover/custom-dropdown-menu.js new file mode 100644 index 0000000000..a26b7c6fc3 --- /dev/null +++ b/frontend/src/metadata/components/popover/column-popover/custom-dropdown-menu.js @@ -0,0 +1,252 @@ +import React, { useCallback, useMemo, useRef, useState } from 'react'; +import { Dropdown, DropdownItem, DropdownMenu, DropdownToggle, Input } from 'reactstrap'; +import classnames from 'classnames'; +import PropTypes from 'prop-types'; +import Icon from '../../../../components/icon'; +import { gettext } from '../../../../utils/constants'; +import { CellType, COLUMNS_ICON_CONFIG, DEFAULT_DATE_FORMAT, DEFAULT_RATE_DATA, DEFAULT_SHOOTING_TIME_FORMAT, PRIVATE_COLUMN_KEY } from '../../../constants'; +import { getColumnDisplayName } from '../../../utils/column'; + +const COLUMNS = [ + { + icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], + type: CellType.COLLABORATOR, + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_COLLABORATORS), + unique: true, + key: PRIVATE_COLUMN_KEY.FILE_COLLABORATORS, + canChangeName: false, + groupby: 'predefined' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], + type: CellType.COLLABORATOR, + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_REVIEWER), + unique: true, + key: PRIVATE_COLUMN_KEY.FILE_REVIEWER, + canChangeName: false, + groupby: 'predefined' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], + type: CellType.COLLABORATOR, + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.OWNER), + unique: true, + key: PRIVATE_COLUMN_KEY.OWNER, + canChangeName: false, + groupby: 'predefined' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.DATE], + type: CellType.DATE, + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME), + unique: true, + key: PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME, + canChangeName: false, + data: { format: DEFAULT_DATE_FORMAT }, + groupby: 'predefined' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.LONG_TEXT], + type: CellType.LONG_TEXT, + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_DESCRIPTION), + unique: true, + key: PRIVATE_COLUMN_KEY.FILE_DESCRIPTION, + canChangeName: false, + groupby: 'predefined' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.SINGLE_SELECT], + type: CellType.SINGLE_SELECT, + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_STATUS), + unique: true, + key: PRIVATE_COLUMN_KEY.FILE_STATUS, + canChangeName: false, + groupby: 'predefined' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.DATE], + type: CellType.DATE, + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.CAPTURE_TIME), + unique: true, + key: PRIVATE_COLUMN_KEY.CAPTURE_TIME, + canChangeName: false, + data: { format: DEFAULT_SHOOTING_TIME_FORMAT }, + groupby: 'predefined' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.RATE], + type: CellType.RATE, + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_RATE), + unique: true, + key: PRIVATE_COLUMN_KEY.FILE_RATE, + canChangeName: false, + data: DEFAULT_RATE_DATA, + groupby: 'predefined' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.TEXT], + type: CellType.TEXT, + name: gettext('Text'), + canChangeName: true, + key: CellType.TEXT, + groupby: 'basics' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.LONG_TEXT], + type: CellType.LONG_TEXT, + name: gettext('Long text'), + canChangeName: true, + key: CellType.LONG_TEXT, + groupby: 'basics' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.NUMBER], + type: CellType.NUMBER, + name: gettext('Number'), + canChangeName: true, + key: CellType.NUMBER, + groupby: 'basics' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], + type: CellType.COLLABORATOR, + name: gettext('Collaborator'), + canChangeName: true, + key: CellType.COLLABORATOR, + groupby: 'basics' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.CHECKBOX], + type: CellType.CHECKBOX, + name: gettext('Checkbox'), + canChangeName: true, + key: CellType.CHECKBOX, + groupby: 'basics' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.DATE], + type: CellType.DATE, + name: gettext('Date'), + canChangeName: true, + key: CellType.DATE, + data: { format: DEFAULT_DATE_FORMAT }, + groupby: 'basics' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.SINGLE_SELECT], + type: CellType.SINGLE_SELECT, + name: gettext('Single select'), + canChangeName: true, + key: CellType.SINGLE_SELECT, + groupby: 'basics' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.MULTIPLE_SELECT], + type: CellType.MULTIPLE_SELECT, + name: gettext('Multiple select'), + canChangeName: true, + key: CellType.MULTIPLE_SELECT, + groupby: 'basics' + }, { + icon: COLUMNS_ICON_CONFIG[CellType.RATE], + type: CellType.RATE, + name: gettext('Rate'), + canChangeName: true, + key: CellType.RATE, + data: DEFAULT_RATE_DATA, + groupby: 'basics', + }, +]; + +const CustomDropdownMenu = ({ column, modifiers, onSelect }) => { + const [searchValue, setSearchValue] = useState(''); + const [isCustomPropertiesOpen, setCustomPropertiesOpen] = useState(false); + const inputRef = useRef(null); + + const displayColumns = useMemo(() => { + const validValue = searchValue.trim().toLocaleLowerCase(); + return COLUMNS.filter(item => { + const columnName = item.name.toLocaleLowerCase(); + return columnName.indexOf(validValue) > -1; + }); + }, [searchValue]); + + const basicsColumns = useMemo(() => { + return displayColumns.filter(item => item.groupby === 'basics'); + }, [displayColumns]); + + const predefinedColumns = useMemo(() => { + return displayColumns.filter(item => item.groupby === 'predefined'); + }, [displayColumns]); + + const toggleCustomProperties = useCallback((e) => { + e?.stopPropagation(); + setCustomPropertiesOpen(prev => !prev); + setSearchValue(''); + }, []); + + const onSearchColumn = useCallback((event) => { + const value = event.target.value; + if (value === searchValue) return; + setSearchValue(value); + }, [searchValue]); + + const onSearchClick = useCallback((event) => { + event.stopPropagation(); + }, []); + + const handleSelect = useCallback((column) => { + onSelect(column); + setSearchValue(''); + }, [onSelect]); + + return ( + +
+ +
+ {displayColumns.length > 0 && predefinedColumns.length > 0 && ( + <> + {predefinedColumns.map(item => ( + setCustomPropertiesOpen(false)} + onClick={() => handleSelect(item)} + > + + {item.name} + + ))} + {basicsColumns.length > 0 && ( + <> + + setCustomPropertiesOpen(true)} + onMouseMove={(e) => {e.stopPropagation();}} + > + + + {gettext('Custom properties')} + + + + {basicsColumns.map((item, index) => ( + handleSelect(item)} + > + + {item.name} + + ))} + + + + )} + + )} +
+ ); +}; + +CustomDropdownMenu.propTypes = { + column: PropTypes.object, + modifiers: PropTypes.array, + onSelect: PropTypes.func, +}; + +export default CustomDropdownMenu; diff --git a/frontend/src/metadata/components/popover/column-popover/data/index.js b/frontend/src/metadata/components/popover/column-popover/data/index.js index 9ecb2beeeb..23c760e830 100644 --- a/frontend/src/metadata/components/popover/column-popover/data/index.js +++ b/frontend/src/metadata/components/popover/column-popover/data/index.js @@ -12,13 +12,11 @@ const Data = forwardRef(({ column }, ref) => { const [value, setValue] = useState(column.data || {}); const [popoverShow, setPopoverShow] = useState(false); const columnKey = useRef(null); - // const [error, setError] = useState(''); useImperativeHandle(ref, () => ({ getValue: () => value, setValue: (value) => setValue(value), getIsPopoverShow: () => popoverShow, - // setError: (error) => setError(error), }), [popoverShow, value]); const onChange = useCallback((value) => { diff --git a/frontend/src/metadata/components/popover/column-popover/index.js b/frontend/src/metadata/components/popover/column-popover/index.js index 1b2dcf1f51..2b13319672 100644 --- a/frontend/src/metadata/components/popover/column-popover/index.js +++ b/frontend/src/metadata/components/popover/column-popover/index.js @@ -1,6 +1,6 @@ -import React, { useCallback, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useMemo, useRef } from 'react'; import PropTypes from 'prop-types'; -import { Button, UncontrolledPopover } from 'reactstrap'; +import { Button, Popover } from 'reactstrap'; import classnames from 'classnames'; import { gettext } from '../../../../utils/constants'; import { useMetadataView } from '../../../hooks/metadata-view'; @@ -18,9 +18,7 @@ import './index.css'; const DEFAULT_POPOVER_INNER_WIDTH = 350; const COLUMN_TYPE_POPOVER_INNER_WIDTH = {}; -const ColumnPopover = ({ target, onChange }) => { - const [column, setColumn] = useState({}); - const popoverRef = useRef(null); +const ColumnPopover = ({ target, column, onSelect, onCancel, onSubmit }) => { const popoverInnerRef = useRef(null); const nameRef = useRef(null); const typeRef = useRef(null); @@ -31,23 +29,17 @@ const ColumnPopover = ({ target, onChange }) => { return COLUMN_TYPE_POPOVER_INNER_WIDTH[column.type] || DEFAULT_POPOVER_INNER_WIDTH; }, [column]); - const toggle = useCallback((event) => { - if (typeRef.current?.getIsPopoverShow()) return; - if (dataRef.current?.getIsPopoverShow()) return; - popoverRef.current.toggle(); - }, [typeRef, dataRef]); - const onColumnChange = useCallback((newColumn) => { setTimeout(() => { typeRef.current.setPopoverState(false); }, 100); if (ObjectUtils.isSameObject(column, newColumn)) return; - setColumn(newColumn); + onSelect(newColumn); if (newColumn.type === column.type) return; dataRef.current.setValue({}); - }, [typeRef, column]); + }, [typeRef, column, onSelect]); - const onSubmit = useCallback(() => { + const handleSubmit = useCallback(() => { nameRef.current.setError(''); typeRef.current.setError(''); let flag = 1; @@ -80,19 +72,16 @@ const ColumnPopover = ({ target, onChange }) => { } } } - onChange(column.unique ? column.key : columnName, column.type, { key: column.unique ? column.key : '', data }); - toggle(); - }, [nameRef, column, metadata, onChange, toggle]); + onSubmit(column.unique ? column.key : columnName, column.type, { key: column.unique ? column.key : '', data }); + }, [nameRef, column, metadata, onSubmit]); return ( -
@@ -102,17 +91,20 @@ const ColumnPopover = ({ target, onChange }) => {
- - + +
-
+ ); }; ColumnPopover.propTypes = { target: PropTypes.string.isRequired, - onChange: PropTypes.func.isRequired, + column: PropTypes.object.isRequired, + onSelect: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, + onSubmit: PropTypes.func.isRequired, }; export default ColumnPopover; diff --git a/frontend/src/metadata/components/popover/column-popover/name/index.js b/frontend/src/metadata/components/popover/column-popover/name/index.js index 6c9b9aba7b..69a14a2a0b 100644 --- a/frontend/src/metadata/components/popover/column-popover/name/index.js +++ b/frontend/src/metadata/components/popover/column-popover/name/index.js @@ -22,6 +22,7 @@ const Name = forwardRef(({ readOnly, value }, ref) => { useEffect(() => { setName(value); + setError(''); }, [value]); return ( diff --git a/frontend/src/metadata/components/popover/column-popover/type/index.js b/frontend/src/metadata/components/popover/column-popover/type/index.js index 6b48df78ca..96f1d7046c 100644 --- a/frontend/src/metadata/components/popover/column-popover/type/index.js +++ b/frontend/src/metadata/components/popover/column-popover/type/index.js @@ -1,204 +1,24 @@ -import React, { forwardRef, useImperativeHandle, useState, useCallback, useRef, useEffect, useMemo } from 'react'; -import { FormGroup, FormFeedback, Label, Dropdown, DropdownToggle, DropdownMenu, Input, DropdownItem } from 'reactstrap'; +import React, { forwardRef, useImperativeHandle, useState, useCallback, useRef, useEffect } from 'react'; +import { FormGroup, FormFeedback, Label, Dropdown, DropdownToggle } from 'reactstrap'; import Icon from '@/components/icon'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { gettext } from '../../../../../utils/constants'; -import { getColumnDisplayName } from '../../../../utils/column'; -import { CellType, COLUMNS_ICON_CONFIG, DEFAULT_DATE_FORMAT, DEFAULT_SHOOTING_TIME_FORMAT, PRIVATE_COLUMN_KEY, DEFAULT_RATE_DATA } from '../../../../constants'; +import CustomDropdownMenu from '../custom-dropdown-menu'; import './index.css'; -const COLUMNS = [ - { - icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], - type: CellType.COLLABORATOR, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_COLLABORATORS), - unique: true, - key: PRIVATE_COLUMN_KEY.FILE_COLLABORATORS, - canChangeName: false, - groupby: 'predefined' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], - type: CellType.COLLABORATOR, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_REVIEWER), - unique: true, - key: PRIVATE_COLUMN_KEY.FILE_REVIEWER, - canChangeName: false, - groupby: 'predefined' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], - type: CellType.COLLABORATOR, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.OWNER), - unique: true, - key: PRIVATE_COLUMN_KEY.OWNER, - canChangeName: false, - groupby: 'predefined' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.DATE], - type: CellType.DATE, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME), - unique: true, - key: PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME, - canChangeName: false, - data: { format: DEFAULT_DATE_FORMAT }, - groupby: 'predefined' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.LONG_TEXT], - type: CellType.LONG_TEXT, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_DESCRIPTION), - unique: true, - key: PRIVATE_COLUMN_KEY.FILE_DESCRIPTION, - canChangeName: false, - groupby: 'predefined' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.SINGLE_SELECT], - type: CellType.SINGLE_SELECT, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_STATUS), - unique: true, - key: PRIVATE_COLUMN_KEY.FILE_STATUS, - canChangeName: false, - groupby: 'predefined' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.DATE], - type: CellType.DATE, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.CAPTURE_TIME), - unique: true, - key: PRIVATE_COLUMN_KEY.CAPTURE_TIME, - canChangeName: false, - data: { format: DEFAULT_SHOOTING_TIME_FORMAT }, - groupby: 'predefined' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.RATE], - type: CellType.RATE, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_RATE), - unique: true, - key: PRIVATE_COLUMN_KEY.FILE_RATE, - canChangeName: false, - data: DEFAULT_RATE_DATA, - groupby: 'predefined' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.TEXT], - type: CellType.TEXT, - name: gettext('Text'), - canChangeName: true, - key: CellType.TEXT, - groupby: 'basics' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.LONG_TEXT], - type: CellType.LONG_TEXT, - name: gettext('Long text'), - canChangeName: true, - key: CellType.LONG_TEXT, - groupby: 'basics' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.NUMBER], - type: CellType.NUMBER, - name: gettext('Number'), - canChangeName: true, - key: CellType.NUMBER, - groupby: 'basics' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], - type: CellType.COLLABORATOR, - name: gettext('Collaborator'), - canChangeName: true, - key: CellType.COLLABORATOR, - groupby: 'basics' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.CHECKBOX], - type: CellType.CHECKBOX, - name: gettext('Checkbox'), - canChangeName: true, - key: CellType.CHECKBOX, - groupby: 'basics' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.DATE], - type: CellType.DATE, - name: gettext('Date'), - canChangeName: true, - key: CellType.DATE, - data: { format: DEFAULT_DATE_FORMAT }, - groupby: 'basics' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.SINGLE_SELECT], - type: CellType.SINGLE_SELECT, - name: gettext('Single select'), - canChangeName: true, - key: CellType.SINGLE_SELECT, - groupby: 'basics' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.MULTIPLE_SELECT], - type: CellType.MULTIPLE_SELECT, - name: gettext('Multiple select'), - canChangeName: true, - key: CellType.MULTIPLE_SELECT, - groupby: 'basics' - }, { - icon: COLUMNS_ICON_CONFIG[CellType.RATE], - type: CellType.RATE, - name: gettext('Rate'), - canChangeName: true, - key: CellType.RATE, - data: DEFAULT_RATE_DATA, - groupby: 'basics', - }, -]; - const Type = forwardRef(({ column, onChange }, ref) => { const [error, setError] = useState(''); - const [searchValue, setSearchValue] = useState(''); const [isPredefinedPropertiesOpen, setPredefinedPropertiesOpen] = useState(false); const [isCustomPropertiesOpen, setCustomPropertiesOpen] = useState(false); const inputRef = useRef(null); - const displayColumns = useMemo(() => { - const validValue = searchValue.trim().toLocaleLowerCase(); - return COLUMNS.filter(item => { - const columnName = item.name.toLocaleLowerCase(); - return columnName.indexOf(validValue) > -1; - }); - }, [searchValue]); - - const basicsColumns = useMemo(() => { - return displayColumns.filter(item => item.groupby === 'basics'); - }, [displayColumns]); - - const predefinedColumns = useMemo(() => { - return displayColumns.filter(item => item.groupby === 'predefined'); - }, [displayColumns]); - const togglePredefinedProperties = useCallback((e) => { e?.stopPropagation(); setPredefinedPropertiesOpen(prev => !prev); }, []); - const toggleCustomProperties = useCallback((e) => { - e?.stopPropagation(); - setCustomPropertiesOpen(prev => !prev); - setSearchValue(''); - }, []); - - const onSelectPredefinedColumn = useCallback((column) => { - onChange(column); - setSearchValue(''); - }, [onChange]); - - const onSelectCustomColumn = useCallback((column) => { - onChange(column); - togglePredefinedProperties(); - }, [onChange, togglePredefinedProperties]); - - const onSearchColumn = useCallback((event) => { - const value = event.target.value; - if (value === searchValue) return; - setSearchValue(value); - }, [searchValue]); - - const onSearchClick = useCallback((event) => { - event.stopPropagation(); - }, []); - useImperativeHandle(ref, () => ({ setError: (error) => setError(error), getIsPopoverShow: () => isPredefinedPropertiesOpen || isCustomPropertiesOpen, @@ -213,8 +33,7 @@ const Type = forwardRef(({ column, onChange }, ref) => { }), [isPredefinedPropertiesOpen, isCustomPropertiesOpen]); useEffect(() => { - onChange(COLUMNS.find(c => c.groupby === 'basics') || COLUMNS[0]); - // eslint-disable-next-line react-hooks/exhaustive-deps + setError(''); }, []); return ( @@ -231,70 +50,20 @@ const Type = forwardRef(({ column, onChange }, ref) => { tag="span" className="sf-metadata-column-type-info" > - + {column.name} - -
- -
- {displayColumns.length > 0 && predefinedColumns.length > 0 && ( - <> - {predefinedColumns.map(item => ( - setCustomPropertiesOpen(false)} - onClick={() => onSelectPredefinedColumn(item)} - > - - {item.name} - - ))} - {basicsColumns.length > 0 && ( - <> - - setCustomPropertiesOpen(true)} - onMouseMove={(e) => {e.stopPropagation();}} - > - - - {gettext('Custom properties')} - - - - {basicsColumns.map((item, index) => ( - onSelectCustomColumn(item)} - > - - {item.name} - - ))} - - - - )} - - )} -
+ }]} + onSelect={onChange} + /> {error && ({error})} diff --git a/frontend/src/metadata/views/table/table-main/records-header/insert-column/index.js b/frontend/src/metadata/views/table/table-main/records-header/insert-column/index.js index 8c9a4d00a0..9cfeb85fc0 100644 --- a/frontend/src/metadata/views/table/table-main/records-header/insert-column/index.js +++ b/frontend/src/metadata/views/table/table-main/records-header/insert-column/index.js @@ -1,14 +1,20 @@ -import React, { useCallback, useEffect, useMemo, useRef } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { Dropdown, DropdownToggle } from 'reactstrap'; import PropTypes from 'prop-types'; import ColumnPopover from '../../../../../components/popover/column-popover'; import Icon from '../../../../../../components/icon'; -import { isEnter } from '../../../../../../utils/hotkey'; +import { getEventClassName } from '../../../../../../utils/dom'; +import CustomDropdownMenu from '../../../../../components/popover/column-popover/custom-dropdown-menu'; import './index.css'; const InsertColumn = ({ lastColumn, height, groupOffsetLeft, insertColumn: insertColumnAPI }) => { + const [isColumnMenuOpen, setColumnMenuOpen] = useState(false); + const [isColumnPopoverShow, setColumnPopoverShow] = useState(false); + const [selectedColumn, setSelectedColumn] = useState(null); + const id = useMemo(() => 'sf-metadata-add-column', []); - const ref = useRef(null); + const style = useMemo(() => { return { height: height, @@ -20,36 +26,73 @@ const InsertColumn = ({ lastColumn, height, groupOffsetLeft, insertColumn: inser }; }, [lastColumn, height, groupOffsetLeft]); - const openPopover = useCallback(() => { - ref?.current?.click(); - }, [ref]); - const insertColumn = useCallback((name, type, { key, data }) => { + const toggleAddColumn = useCallback(() => { + setColumnMenuOpen(!isColumnMenuOpen); + }, [isColumnMenuOpen]); + + const handleCancel = useCallback(() => { + setColumnMenuOpen(false); + setColumnPopoverShow(false); + setSelectedColumn(null); + }, []); + + const handleSubmit = useCallback((name, type, { key, data }) => { insertColumnAPI(name, type, { key, data }); + setColumnPopoverShow(false); }, [insertColumnAPI]); - const onHotKey = useCallback((event) => { - if (isEnter(event) && document.activeElement && document.activeElement.id === id) { - openPopover(); - } - }, [id, openPopover]); + const handleSelect = useCallback((column) => { + setSelectedColumn(column); + setColumnMenuOpen(false); + setColumnPopoverShow(true); + }, []); + + const handleClickOutside = useCallback((event) => { + if (!isColumnPopoverShow) return; + if (!event.target) return; + const className = getEventClassName(event); + if (className.indexOf('column-type-item') > -1) return; + const popover = document.querySelector('.sf-metadata-column-popover'); + if ((popover && popover.contains(event.target))) return; + setColumnPopoverShow(false); + }, [isColumnPopoverShow]); useEffect(() => { - document.addEventListener('keydown', onHotKey); + document.addEventListener('mousedown', handleClickOutside); + return () => { - document.removeEventListener('keydown', onHotKey); + document.removeEventListener('mousedown', handleClickOutside); }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }); return ( <> -
-
+ + -
-
- + + + + {isColumnPopoverShow && !isColumnMenuOpen && ( + + )} ); };