This commit is contained in:
caishi 2023-08-24 11:42:42 +08:00
parent 8421a8526f
commit d32ed9be61
3 changed files with 259 additions and 94 deletions

34
package-lock.json generated
View File

@ -11096,7 +11096,7 @@
},
"node-sass": {
"version": "4.14.1",
"resolved": "https://registry.npmmirror.com/node-sass/-/node-sass-4.14.1.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/node-sass/-/node-sass-4.14.1.tgz",
"integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==",
"dev": true,
"requires": {
@ -15690,7 +15690,7 @@
},
"sass-graph": {
"version": "2.2.5",
"resolved": "https://registry.npmmirror.com/sass-graph/-/sass-graph-2.2.5.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/sass-graph/-/sass-graph-2.2.5.tgz",
"integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==",
"dev": true,
"requires": {
@ -15708,13 +15708,13 @@
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
"cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-5.0.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/cliui/-/cliui-5.0.0.tgz",
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"dev": true,
"requires": {
@ -15731,7 +15731,7 @@
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/find-up/-/find-up-3.0.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/find-up/-/find-up-3.0.0.tgz",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"requires": {
@ -15740,13 +15740,13 @@
},
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-3.0.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/locate-path/-/locate-path-3.0.0.tgz",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"requires": {
@ -15756,7 +15756,7 @@
},
"p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
@ -15765,7 +15765,7 @@
},
"p-locate": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-3.0.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/p-locate/-/p-locate-3.0.0.tgz",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"requires": {
@ -15774,19 +15774,19 @@
},
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-3.1.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
@ -15797,7 +15797,7 @@
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-5.2.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
@ -15812,7 +15812,7 @@
},
"wrap-ansi": {
"version": "5.1.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
"dev": true,
"requires": {
@ -15823,13 +15823,13 @@
},
"y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true
},
"yargs": {
"version": "13.3.2",
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-13.3.2.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/yargs/-/yargs-13.3.2.tgz",
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true,
"requires": {
@ -15847,7 +15847,7 @@
},
"yargs-parser": {
"version": "13.1.2",
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-13.1.2.tgz",
"resolved": "http://173.15.15.82:8081/repository/npm-all/yargs-parser/-/yargs-parser-13.1.2.tgz",
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true,
"requires": {

View File

@ -32,7 +32,7 @@ export function initAxiosInterceptors(props) {
// 判断网络是否连接
initOnlineOfflineListener();
var proxy = "https://testforgeplus.educoder.net";
var proxy = "https://testforgeplus.trustie.net";
//响应前的设置
axios.interceptors.request.use(
config => {

View File

@ -1,90 +1,255 @@
import React, { useEffect, useState } from 'react';
import { AutoComplete , Button , Icon } from 'antd';
// import React, { useEffect, useState } from 'react';
// import { AutoComplete , Button , Icon , Select } from 'antd';
// import axios from 'axios';
// import { getImageUrl } from 'educoder';
// const { Option } = Select;
// function AddMember({getID,login,showNotification}){
// const [ id , setID ] = useState(undefined);
// const [ source , setSource ] = useState(undefined);
// const [ searchKey , setSearchKey ] = useState(undefined);
// useEffect(()=>{
// getUserList();
// },[searchKey])
// function getUserList(){
// const url = `/users/list.json`;
// axios.get(url, {
// params: {
// search: searchKey,
// },
// }).then((result) => {
// if (result) {
// setSource(result.data.users);
// }
// })
// .catch((error) => {
// console.log(error);
// });
// };
// function changeInputUser(e){
// setSearchKey(e);
// };
// //
// function selectInputUser(e, option){
// setID(login ? e : option.props.login);
// setSearchKey(option.props.name);
// };
// function addCollaborator(){
// if(source && source.length>0&&searchKey){
// getID && getID(id);
// setSearchKey(undefined);
// setID(undefined)
// }else{
// showNotification("!");
// }
// }
// return(
// <div className="addPanel">
// <Select
// showSearch
// style={{ width: 300 }}
// placeholder="..."
// className="plateAutoComplete"
// optionFilterProp="children"
// filterOption={(input, option) =>
// option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
// }
// >
// {source && source.length > 0 &&
// source.map((item,key)=>{
// return(
// <Option value={`${item.user_id}`}
// login={`${item.login}`}
// name={item.username}
// >
// <img
// className="user_img radius"
// width="28"
// height="28"
// src={getImageUrl(`/${item && item.image_url}`)}
// alt=""
// />
// <span className="ml10" style={{ verticalAlign: "middle" }}>
// {item.username}
// <span className="color-grey ml10">({item.login})</span>
// </span>
// </Option>
// )
// })
// }
// </Select>
// <Select
// value={searchKey}
// style={{ width: 300 }}
// // onChange={changeInputUser}
// onSearch={(e)=>{setSearchKey(e)}}
// onSelect={selectInputUser}
// placeholder="..."
// allowClear
// showSearch
// suffixIcon={<i className="iconfont icon-sousuo1 font-14"></i>}
// >
// {
// source && source.length > 0 &&
// source.map((item,key)=>{
// return(
// <Option
// key={key}
// value={`${item.user_id}`}
// login={`${item.login}`}
// name={item.username}
// >
// <img
// className="user_img radius"
// width="28"
// height="28"
// src={getImageUrl(`/${item && item.image_url}`)}
// alt=""
// />
// <span className="ml10" style={{ verticalAlign: "middle" }}>
// {item.username}
// <span className="color-grey ml10">({item.login})</span>
// </span>
// </Option>
// )
// })
// }
// </Select>
// <Button
// type="primary"
// ghost
// onClick={addCollaborator}
// className="ml15"
// >
// <Icon type="plus" size="16"></Icon>
//
// </Button>
// </div>
// )
// }
// export default AddMember;
import React, { useEffect, useMemo, useRef, useState } from 'react';
import debounce from 'lodash/debounce';
import { Select, Spin , Button , Icon } from 'antd';
import axios from 'axios';
import { getImageUrl } from 'educoder';
function DebounceSelect({ fetchOptions, debounceTimeout = 600, ...props }) {
const [fetching, setFetching] = useState(false);
const [options, setOptions] = useState([]);
const fetchRef = useRef(0);
const { Option } = AutoComplete;
function AddMember({getID,login,showNotification}){
const [ id , setID ] = useState(undefined);
const [ source , setSource ] = useState(undefined);
const [ searchKey , setSearchKey ] = useState(undefined);
useEffect(()=>{
getUserList();
},[searchKey])
fetchOptions("").then((newOptions) => {
setOptions(newOptions);
});
},[])
function getUserList(e){
const url = `/users/list.json`;
axios.get(url, {
params: {
search: searchKey,
},
}).then((result) => {
if (result) {
sourceOptions(result.data.users);
const debounceFetcher = useMemo(() => {
const loadOptions = (value) => {
fetchRef.current += 1;
const fetchId = fetchRef.current;
setOptions([]);
setFetching(true);
fetchOptions(value).then((newOptions) => {
if (fetchId !== fetchRef.current) {
// for fetch callback order
return;
}
setOptions(newOptions);
setFetching(false);
});
};
return debounce(loadOptions, debounceTimeout);
}, [fetchOptions, debounceTimeout]);
return (
<Select
labelInValue
filterOption={false}
onSearch={debounceFetcher}
notFoundContent={fetching ? <Spin size="small" /> : null}
{...props}
defaultActiveFirstOption={false}
>
{
options && options.length >0 &&
options.map((i)=>{
return(
<Select.Option value={i.value}>
{/* <img
className="user_img radius"
width="28"
height="28"
src={getImageUrl(`/${i && i.image_url}`)}
alt=""
/> */}
<span style={{ verticalAlign: "middle" }}>
{i.label}
<span className="color-grey ml10">({i.login})</span>
</span>
</Select.Option>
)
})
}
})
.catch((error) => {
console.log(error);
});
};
</Select>
);
}
function sourceOptions(userDataSource){
const s = userDataSource && userDataSource.map((item, key) => {
return (
<Option
key={key}
value={`${item.user_id}`}
login={`${item.login}`}
name={item.username}
>
<img
className="user_img radius"
width="28"
height="28"
src={getImageUrl(`/${item && item.image_url}`)}
alt=""
/>
<span className="ml10" style={{ verticalAlign: "middle" }}>
{item.username}
<span className="color-grey ml10">({item.login})</span>
</span>
</Option>
);
});
setSource(s);
}
// Usage of DebounceSelect
function changeInputUser(e){
setSearchKey(e);
};
//
function selectInputUser(e, option){
setID(login ? e : option.props.login);
setSearchKey(option.props.name);
};
async function fetchUserList(username) {
const url = `/users/list.json`;
let list = [];
await axios.get(url, {
params: {
search: username,
},
}).then((result) => {
if (result && result.data) {
list = result.data.users && result.data.users.map((i)=>({
label:i.username,
value:i.user_id,
image_url:i.image_url,
login:i.login
}));
}
})
return list;
}
const App = ({getID,login,showNotification}) => {
const [value, setValue] = useState([]);
const [ chooseValue , setChooseValue ] = useState(undefined);
function addCollaborator(){
if(source && source.length>0&&searchKey){
getID && getID(id);
setSearchKey(undefined);
setID(undefined)
}else{
if(chooseValue){
getID(chooseValue);
setValue([])
} else{
showNotification("请选择存在的用户!");
}
}
return(
<div className="addPanel">
<AutoComplete
dataSource={source}
value={searchKey}
style={{ width: 300 }}
onChange={changeInputUser}
onSelect={selectInputUser}
function selectValue(e){
setChooseValue(e.key);
}
return (
<div>
<DebounceSelect
value={value}
style={{width:300}}
placeholder="搜索需要添加的用户..."
allowClear
fetchOptions={fetchUserList}
onChange={(newValue) => {
setValue(newValue);
}}
showSearch
onSelect={selectValue}
/>
<Button
type="primary"
@ -96,6 +261,6 @@ function AddMember({getID,login,showNotification}){
添加成员
</Button>
</div>
)
}
export default AddMember;
);
};
export default App;