diff --git a/frontend/src/components/common/notification.js b/frontend/src/components/common/notification.js index 9d57c828d4..ed318ce0ce 100644 --- a/frontend/src/components/common/notification.js +++ b/frontend/src/components/common/notification.js @@ -5,7 +5,7 @@ import { gettext } from '../../utils/constants'; import NoticeItem from './notice-item'; import UserNotificationsDialog from '../../user-notifications'; import { Utils } from '../../utils/utils'; -import './notification.css'; +import '../../css/notification.css'; class Notification extends React.Component { constructor(props) { diff --git a/frontend/src/components/common/select/index.js b/frontend/src/components/common/select/index.js new file mode 100644 index 0000000000..17d8a9bfe1 --- /dev/null +++ b/frontend/src/components/common/select/index.js @@ -0,0 +1,5 @@ +import SeahubSelect from './seahub-select'; +import { NoGroupMessage } from './no-group-message'; +import { MenuSelectStyle, UserSelectStyle } from './seahub-select-style'; + +export { SeahubSelect, NoGroupMessage, MenuSelectStyle, UserSelectStyle }; diff --git a/frontend/src/components/common/select/no-group-message.js b/frontend/src/components/common/select/no-group-message.js new file mode 100644 index 0000000000..7a9abcc9fa --- /dev/null +++ b/frontend/src/components/common/select/no-group-message.js @@ -0,0 +1,15 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { gettext } from '../../../utils/constants'; + +const NoGroupMessage = (props) => { + return ( +
{gettext('Group not found')}
+ ); +}; + +NoGroupMessage.propTypes = { + innerProps: PropTypes.any.isRequired, +}; + +export { NoGroupMessage }; diff --git a/frontend/src/components/common/select/seahub-select-style.js b/frontend/src/components/common/select/seahub-select-style.js new file mode 100644 index 0000000000..d72734626e --- /dev/null +++ b/frontend/src/components/common/select/seahub-select-style.js @@ -0,0 +1,49 @@ +const MenuSelectStyle = { + option: (provided, state) => { + const { isDisabled, isSelected, isFocused } = state; + return ({ + ...provided, + cursor: isDisabled ? 'default' : 'pointer', + backgroundColor: isSelected ? '#20a0ff' : (isFocused ? '#f5f5f5' : '#fff'), + '.header-icon .dtable-font': { + color: isSelected ? '#fff' : '#aaa', + }, + }); + }, + control: (provided) => ({ + ...provided, + fontSize: '14px', + cursor: 'pointer', + lineHeight: '1.5', + }), + menuPortal: base => ({ ...base, zIndex: 9999 }), + indicatorSeparator: () => {}, +}; + +const UserSelectStyle = { + option: (provided, state) => { + const { isDisabled, isFocused } = state; + return ({ + ...provided, + cursor: isDisabled ? 'default' : 'pointer', + backgroundColor: isFocused ? '#f5f5f5' : '#fff', + }); + }, + control: (provided) => ({ + ...provided, + fontSize: '14px', + cursor: 'pointer', + lineHeight: '1.5', + }), + indicatorSeparator: () => ({ + display: 'none', + }), + dropdownIndicator: () => ({ + display: 'none', + }), + clearIndicator: () => ({ + display: 'none', + }), +}; + +export { MenuSelectStyle, UserSelectStyle }; diff --git a/frontend/src/components/common/select/seahub-select.js b/frontend/src/components/common/select/seahub-select.js new file mode 100644 index 0000000000..a791f704d5 --- /dev/null +++ b/frontend/src/components/common/select/seahub-select.js @@ -0,0 +1,110 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Select, { components, createFilter } from 'react-select'; +import { MenuSelectStyle } from './seahub-select-style'; + +const ClearIndicator = ({ innerProps, ...props }) => { + const onMouseDown = e => { + e.nativeEvent.stopImmediatePropagation(); + innerProps.onMouseDown(e); + }; + props.innerProps = { ...innerProps, onMouseDown }; + return ; +}; + +ClearIndicator.propTypes = { + innerProps: PropTypes.object, +}; + +const MenuList = (props) => ( +
e.nativeEvent.stopImmediatePropagation()} onMouseDown={e => e.nativeEvent.stopImmediatePropagation()} > + {props.children} +
+); + +MenuList.propTypes = { + children: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), +}; + +const Option = props => { + return ( +
+ +
+ ); +}; + +Option.propTypes = { + data: PropTypes.shape({ + style: PropTypes.object, + }), +}; + +export default class SeahubSelect extends React.Component { + + static propTypes = { + isMulti: PropTypes.bool, + options: PropTypes.array.isRequired, + value: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.string]), + isSearchable: PropTypes.bool, + isClearable: PropTypes.bool, + placeholder: PropTypes.string, + classNamePrefix: PropTypes.string, + form: PropTypes.string, + onChange: PropTypes.func.isRequired, + menuPortalTarget: PropTypes.string, + menuPosition: PropTypes.string, + noOptionsMessage: PropTypes.func, + innerRef: PropTypes.object, + isDisabled: PropTypes.bool, + }; + + static defaultProps = { + options: [], + value: {}, + isDisabled: false, + isSearchable: false, + isClearable: false, + placeholder: '', + isMulti: false, + menuPortalTarget: '.modal', + noOptionsMessage: () => { + return null; + }, + }; + + getMenuPortalTarget = () => { + return document.querySelector(this.props.menuPortalTarget); + }; + + render() { + const { options, onChange, value, isSearchable, placeholder, isMulti, menuPosition, isClearable, noOptionsMessage, + classNamePrefix, innerRef, isDisabled, form } = this.props; + return ( + {gettext('Template')} + { return {value: item, label: item}; })} onChange={this.handlelibraryTemplatesInputChange} @@ -201,9 +200,8 @@ class CreateRepoDialog extends React.Component { {storages.length > 0 && ( - - {showPath && diff --git a/frontend/src/components/dialog/share-to-group.js b/frontend/src/components/dialog/share-to-group.js index c720ec0040..e8419d8fe4 100644 --- a/frontend/src/components/dialog/share-to-group.js +++ b/frontend/src/components/dialog/share-to-group.js @@ -1,12 +1,12 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; import { Button } from 'reactstrap'; -import Select from 'react-select'; import { gettext, isPro, enableShareToDepartment } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; import toaster from '../toast'; import SharePermissionEditor from '../select-editor/share-permission-editor'; +import { SeahubSelect, NoGroupMessage } from '../common/select'; class GroupItem extends React.Component { @@ -117,16 +117,6 @@ const propTypes = { onAddCustomPermissionToggle: PropTypes.func, }; -const NoOptionsMessage = (props) => { - return ( -
{gettext('Group not found')}
- ); -}; - -NoOptionsMessage.propTypes = { - innerProps: PropTypes.object.isRequired, -}; - class ShareToGroup extends React.Component { constructor(props) { @@ -340,15 +330,13 @@ class ShareToGroup extends React.Component { - { - return ( -
{gettext('Group not found')}
- ); -}; - -NoOptionsMessage.propTypes = { - innerProps: PropTypes.any.isRequired, -}; - class SysAdminShareToGroup extends React.Component { constructor(props) { @@ -257,15 +247,13 @@ class SysAdminShareToGroup extends React.Component { - : -