1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-06 01:23:56 +00:00
seahub/frontend/src/components/user-select.js
JoinTyang cc625f7815
migrate old wiki to new wiki (#6987)
* migrate old wiki to new wiki

* change style

---------

Co-authored-by: Michael An <2331806369@qq.com>
2024-11-05 18:03:53 +08:00

123 lines
3.8 KiB
JavaScript

import React from 'react';
import PropTypes from 'prop-types';
import AsyncSelect from 'react-select/async';
import { seafileAPI } from '../utils/seafile-api';
import { gettext, enableShowContactEmailWhenSearchUser, enableShowLoginIDWhenSearchUser } from '../utils/constants';
import { Utils } from '../utils/utils';
import toaster from './toast';
import { UserSelectStyle, NoOptionsStyle } from './common/select';
import '../css/user-select.css';
const propTypes = {
placeholder: PropTypes.string.isRequired,
onSelectChange: PropTypes.func.isRequired,
isMulti: PropTypes.bool.isRequired,
className: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
};
class UserSelect extends React.Component {
constructor(props) {
super(props);
this.options = [];
this.finalValue = '';
this.state = {
searchValue: ''
};
this.userSelect = React.createRef();
}
onInputChange = (searchValue) => {
if (!this.props.isMulti && searchValue.trim()) {
this.handleSelectChange(null);
this.clearSelect();
}
this.setState({ searchValue });
};
handleSelectChange = (option) => {
this.options = [];
this.props.onSelectChange(option);
};
loadOptions = (input, callback) => {
const value = input.trim();
this.finalValue = value;
setTimeout(() => {
if (this.finalValue === value && value.length > 0) {
seafileAPI.searchUsers(value).then((res) => {
this.options = [];
for (let i = 0 ; i < res.data.users.length; i++) {
const item = res.data.users[i];
let obj = {};
obj.value = item.name;
obj.email = item.email;
obj.label = (enableShowContactEmailWhenSearchUser || enableShowLoginIDWhenSearchUser) ? (
<div className="d-flex">
<img src={item.avatar_url} className="avatar" width="24" alt="" />
<div className="ml-2">
<span className="user-option-name">{item.name}</span><br />
{enableShowContactEmailWhenSearchUser && <span className="user-option-email">{item.contact_email}</span>}
{enableShowLoginIDWhenSearchUser && <span className="user-option-email">{item.login_id}</span>}
</div>
</div>
) : (
<React.Fragment>
<img src={item.avatar_url} className="select-module select-module-icon avatar" alt=""/>
<span className='select-module select-module-name'>{item.name}</span>
</React.Fragment>
);
this.options.push(obj);
}
callback(this.options);
}).catch(error => {
let errMessage = Utils.getErrorMsg(error);
toaster.danger(errMessage);
});
}
}, 1000);
};
clearSelect = () => {
this.userSelect.current.onChange([], { action: 'clear' });
};
render() {
const searchValue = this.state.searchValue;
return (
<AsyncSelect
isClearable
classNamePrefix
components={{
NoOptionsMessage: (props) => {
return (
<div {...props.innerProps} style={NoOptionsStyle}>
{searchValue ? gettext('User not found') : gettext('Enter characters to start searching')}
</div>
);
}
}}
isMulti={true}
loadOptions={this.loadOptions}
onChange={this.handleSelectChange}
onInputChange={this.onInputChange}
placeholder={this.props.placeholder}
className={`user-select ${this.props.className}`}
value={this.props.value}
ref={this.userSelect}
styles={UserSelectStyle}
/>
);
}
}
UserSelect.propTypes = propTypes;
UserSelect.defaultProps = {
className: ''
};
export default UserSelect;