Merge branch 'cs_news' into feature/zhuanqu
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1682403222759') format('woff2'),
|
||||
url('iconfont.woff?t=1682403222759') format('woff'),
|
||||
url('iconfont.ttf?t=1682403222759') format('truetype');
|
||||
src: url('iconfont.woff2?t=1686823554834') format('woff2'),
|
||||
url('iconfont.woff?t=1686823554834') format('woff'),
|
||||
url('iconfont.ttf?t=1686823554834') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
|
@ -13,6 +13,22 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-a-zu2044:before {
|
||||
content: "\e96d";
|
||||
}
|
||||
|
||||
.icon-cuo:before {
|
||||
content: "\e96c";
|
||||
}
|
||||
|
||||
.icon-dui:before {
|
||||
content: "\e96b";
|
||||
}
|
||||
|
||||
.icon-zanting:before {
|
||||
content: "\e96a";
|
||||
}
|
||||
|
||||
.icon-cangkuyuyanicon:before {
|
||||
content: "\e962";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,34 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "36020261",
|
||||
"name": "组 2044",
|
||||
"font_class": "a-zu2044",
|
||||
"unicode": "e96d",
|
||||
"unicode_decimal": 59757
|
||||
},
|
||||
{
|
||||
"icon_id": "5287658",
|
||||
"name": "错",
|
||||
"font_class": "cuo",
|
||||
"unicode": "e96c",
|
||||
"unicode_decimal": 59756
|
||||
},
|
||||
{
|
||||
"icon_id": "8802648",
|
||||
"name": "对",
|
||||
"font_class": "dui",
|
||||
"unicode": "e96b",
|
||||
"unicode_decimal": 59755
|
||||
},
|
||||
{
|
||||
"icon_id": "887857",
|
||||
"name": "暂停",
|
||||
"font_class": "zanting",
|
||||
"unicode": "e96a",
|
||||
"unicode_decimal": 59754
|
||||
},
|
||||
{
|
||||
"icon_id": "34965902",
|
||||
"name": "仓库语言icon",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ if (isDev) {
|
|||
}
|
||||
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
|
||||
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
|
||||
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'student'
|
||||
}
|
||||
window._debugType = debugType;
|
||||
export function initAxiosInterceptors(props) {
|
||||
|
|
|
|||
|
|
@ -11,10 +11,12 @@ export default(({ header , nav })=>{
|
|||
nav && nav.list && nav.list.length>0 ?
|
||||
nav.list.map((item,key)=>{
|
||||
return(
|
||||
<li key={key} className={nav.active === key?"active":''}>
|
||||
!item.hide &&<li key={key} className={nav.active === key?"active":''}>
|
||||
<p>
|
||||
<Link to={item.href}>
|
||||
<i className={`iconfont ${item.icon || 'icon-huabanfuben'} font-18 mr10`}></i>{item.name}
|
||||
{item.icon && <i className={`iconfont ${item.icon || 'icon-huabanfuben'} font-18 mr10`}></i>}
|
||||
{item.img && <img src={item.img} alt="" width="20px" className="mr10"/>}
|
||||
{item.name}
|
||||
</Link>
|
||||
</p>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ function NewsDetail(props){
|
|||
<p className="i_name">{detail.name}</p>
|
||||
<ul className="i_ul_value">
|
||||
{ cmsDir && <li>{cmsDir.name}</li> }
|
||||
{ cmsDir && <li>发布于{cmsDir.createdAt}</li> }
|
||||
{ cmsDir && <li>发布于{detail.publishTime}</li> }
|
||||
{ detail.visits && <li><img src={liulan} alt="" className="mr5" />{detail.visits}</li> }
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -92,8 +92,8 @@ function Index(props){
|
|||
|
||||
function getAdminUrl(id){
|
||||
getCheckZoneRole(id).then(response=>{
|
||||
if(response && response.data.code === 200){
|
||||
setAdminUrl(response.data);
|
||||
if(response && response.data.data){
|
||||
setAdminUrl(response.data.data);
|
||||
}else{
|
||||
setAdminUrl(undefined);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1022,12 +1022,6 @@
|
|||
margin: 25px 25px 25px 0;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.informations_detail.markdown-body{
|
||||
&>p{
|
||||
line-height: 32px;
|
||||
margin-bottom: 8px!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.zone_parter{
|
||||
background-color: #fff;
|
||||
|
|
@ -1195,4 +1189,10 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.informations_detail.markdown-body{
|
||||
&>p{
|
||||
line-height: 32px;
|
||||
margin-bottom: 8px!important;
|
||||
}
|
||||
}
|
||||
|
|
@ -63,9 +63,9 @@ function CoderDepot(props){
|
|||
branchName = returnbar(branchName);
|
||||
const details = props.projectDetail;
|
||||
let pathname = props.history.location.pathname;
|
||||
const { platform } = props ;
|
||||
const { platform , mirror_status } = props ;
|
||||
//distribution:判断此用户是否可以创建发行版
|
||||
const distribution = details && details.type !== 2 && ( details.permission && details.permission !== "Reporter");
|
||||
const distribution = details && details.type ===0 && ( details.permission && details.permission !== "Reporter");
|
||||
const { bannerList } = props;
|
||||
useEffect(()=>{
|
||||
if(bannerList && bannerList.length>0){
|
||||
|
|
@ -93,7 +93,7 @@ function CoderDepot(props){
|
|||
|
||||
|
||||
useEffect(()=>{
|
||||
if(details){
|
||||
if(details && mirror_status===0){
|
||||
setProjectDetail(details);
|
||||
setTopics(details.topics);
|
||||
setDesc(details.description);
|
||||
|
|
@ -102,7 +102,7 @@ function CoderDepot(props){
|
|||
setDefaultBranch(details.default_branch);
|
||||
setInviteCode(details.invite_code);
|
||||
}
|
||||
},[details])
|
||||
},[details,mirror_status])
|
||||
|
||||
useEffect(()=>{
|
||||
// 设置网页标题
|
||||
|
|
@ -126,7 +126,7 @@ function CoderDepot(props){
|
|||
},[treeValue])
|
||||
|
||||
useEffect(()=>{
|
||||
if (projectsId && owner && defaultBranch){
|
||||
if (projectsId && owner && defaultBranch && mirror_status===0){
|
||||
let b = turnbar(branchName) ;
|
||||
if(pathname.indexOf(`/${owner}/${projectsId}`) > -1 && pathname.indexOf(`/tree/${b}/`) > -1) {
|
||||
let url = pathname.split(`/tree/${b}/`)[1];
|
||||
|
|
@ -139,10 +139,10 @@ function CoderDepot(props){
|
|||
setType("dir");
|
||||
}
|
||||
}
|
||||
},[projectsId,owner,pathname,defaultBranch])
|
||||
},[projectsId,owner,pathname,defaultBranch,mirror_status])
|
||||
|
||||
useEffect(()=>{
|
||||
if(platform){
|
||||
if(platform && mirror_status===0){
|
||||
setReadOnly(props.history.location.search.indexOf('edit') !== -1);
|
||||
axios.get(`/${owner}/${projectsId}/releases.json`).then((result)=>{
|
||||
if(result && result.data){
|
||||
|
|
@ -154,7 +154,7 @@ function CoderDepot(props){
|
|||
}
|
||||
})
|
||||
}
|
||||
},[platform])
|
||||
},[platform,mirror_status])
|
||||
|
||||
// 获取readme信息
|
||||
function getReadmeInfo(path, ref) {
|
||||
|
|
@ -386,14 +386,14 @@ function CoderDepot(props){
|
|||
|
||||
const { current_user , checkIfLogin , showLoginDialog } = props;
|
||||
const baseOper = current_user && current_user.login && issuesFlag;
|
||||
const baseOperate = projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter" && projectDetail.type !== 2 && pullsFlag && props.platform;
|
||||
const fileOperate = type === "dir" && projectDetail && projectDetail.type !== 2 && ((projectDetail.permission && projectDetail.permission !=="Reporter") || (current_user && current_user.admin));
|
||||
const baseOperate = projectDetail && projectDetail.permission && projectDetail.permission !=="Reporter" && projectDetail.type ===0 && pullsFlag && props.platform;
|
||||
const fileOperate = type === "dir" && projectDetail && projectDetail.type ===0 && ((projectDetail.permission && projectDetail.permission !=="Reporter") || (current_user && current_user.admin));
|
||||
return(
|
||||
<WhiteBack>
|
||||
<UpdateDescModal desc={desc} website={website} lesson_url={lesson_url} topicsInfo={topics} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/>
|
||||
{mirror_status ===0 && <UpdateDescModal desc={desc} website={website} lesson_url={lesson_url} topicsInfo={topics} visible={openModal} onCancel={()=>setOpenModal(false)} onOk={okUpdate}/> }
|
||||
<Spin spinning={isSpin}>
|
||||
{
|
||||
(dirInfo || fileInfo) &&
|
||||
((dirInfo || fileInfo) && mirror_status===0 ) &&
|
||||
<React.Fragment>
|
||||
<DrawerPanel
|
||||
history={props.history}
|
||||
|
|
@ -421,7 +421,7 @@ function CoderDepot(props){
|
|||
<AlignCenter>
|
||||
<div className="mr30">
|
||||
{
|
||||
props && props.platform ?
|
||||
props && (props.platform && mirror_status ===0) ?
|
||||
<SelectBranch
|
||||
repo_id={projectDetail && projectDetail.repo_id}
|
||||
projectsId={projectsId}
|
||||
|
|
@ -651,9 +651,9 @@ function CoderDepot(props){
|
|||
</React.Fragment>
|
||||
}
|
||||
{/* 贡献者 */}
|
||||
<Contributors owner={owner} projectsId={projectsId} />
|
||||
{mirror_status ===0 && <Contributors owner={owner} projectsId={projectsId} /> }
|
||||
{/* 语言 */}
|
||||
<LanguagePower owner={owner} projectsId={projectsId}/>
|
||||
{ mirror_status ===0 && <LanguagePower owner={owner} projectsId={projectsId}/> }
|
||||
</Gap>
|
||||
</ShortWidth>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ class Detail extends Component {
|
|||
|
||||
// 非本平台项目
|
||||
platform: false,
|
||||
mirror_status:1
|
||||
mirror_status:2
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +240,6 @@ class Detail extends Component {
|
|||
open_devops: result.data.open_devops,
|
||||
platform: result.data.platform && result.data.platform !== 'educoder'
|
||||
})
|
||||
|
||||
if (result.data.type !== 0 && result.data.mirror_status === 1) {
|
||||
console.log("--------start channel --------");
|
||||
// 是镜像项目,且未完成迁移
|
||||
|
|
@ -260,16 +259,18 @@ class Detail extends Component {
|
|||
mirror_status:1
|
||||
})
|
||||
} else if (result.data.mirror_status === 2) {
|
||||
this.deleteProjectBack();
|
||||
this.setState({
|
||||
mirror_status:2
|
||||
mirror_status:2,
|
||||
firstSync: false
|
||||
})
|
||||
this.deleteProjectBack();
|
||||
} else {
|
||||
this.getBanner();
|
||||
this.getDetail();
|
||||
this.setState({
|
||||
firstSync: false,
|
||||
secondSync: false
|
||||
secondSync: false,
|
||||
mirror_status:0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -860,7 +861,7 @@ class Detail extends Component {
|
|||
></Route>
|
||||
<Route path="/:owner/:projectsId"
|
||||
render={
|
||||
(props) => (mirror_status!==2 ? <CoderDepot {...this.props} {...props} {...this.state} {...common} /> :<Spin />)
|
||||
(props) => <CoderDepot {...this.props} {...props} {...this.state} {...common} mirror_status={mirror_status}/>
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,10 @@ class Index extends Component {
|
|||
licenseFlag:false,
|
||||
|
||||
// 区块链确权
|
||||
tokenConTri: false
|
||||
tokenConTri: false,
|
||||
|
||||
gitHubUrl:false,
|
||||
checkToken:undefined
|
||||
}
|
||||
}
|
||||
componentDidMount = () => {
|
||||
|
|
@ -203,7 +206,9 @@ class Index extends Component {
|
|||
isSpin: true
|
||||
})
|
||||
const { projectsType } = this.props.match.params;
|
||||
const { project_language_id, project_category_id, license_id, ignore_id, owners_id, ignoreFlag, licenseFlag, categoreFlag, languageFlag, tokenConTri} = this.state;
|
||||
const { project_language_id, project_category_id, license_id
|
||||
, ignore_id, owners_id, ignoreFlag, licenseFlag,
|
||||
categoreFlag, languageFlag, tokenConTri,gitHubUrl} = this.state;
|
||||
const decoderPass = Base64.encode(values.password);
|
||||
const url = (projectsType && projectsType === "mirror") ? "/projects/migrate.json" : "/projects.json";
|
||||
// 新建项目的时候,暂存数据,如果失败,返回的时候可以重新赋值
|
||||
|
|
@ -220,7 +225,8 @@ class Index extends Component {
|
|||
user_id:owners_id,
|
||||
blockchain: tokenConTri,
|
||||
blockchain_token_all: 10000,
|
||||
blockchain_init_token: parseInt(blockchain_init)
|
||||
blockchain_init_token: parseInt(blockchain_init),
|
||||
auth_token:gitHubUrl ? values.auth_token : undefined
|
||||
}).then((result) => {
|
||||
if (result && result.data.id) {
|
||||
projectsType && projectsType !== "mirror" && this.props.showNotification(`项目创建成功!`);
|
||||
|
|
@ -235,6 +241,7 @@ class Index extends Component {
|
|||
})
|
||||
})
|
||||
} else {
|
||||
window.scrollTo(0,0);
|
||||
this.setState({
|
||||
isSpin: false
|
||||
})
|
||||
|
|
@ -301,6 +308,9 @@ class Index extends Component {
|
|||
repository_name:first
|
||||
})
|
||||
}
|
||||
this.setState({gitHubUrl:value.indexOf("https://github.com")>-1 ? true : false})
|
||||
}else{
|
||||
this.setState({gitHubUrl:false,checkToken:undefined})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -344,6 +354,29 @@ class Index extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
blurFunc=(e)=>{
|
||||
let value = e.target.value;
|
||||
if(value){
|
||||
const { clone_addr } = this.props.form.getFieldsValue();
|
||||
if(clone_addr){
|
||||
const u = `/projects/verify_auth_token.json`;
|
||||
axios.post(u,{
|
||||
auth_token:value,
|
||||
clone_addr
|
||||
}).then(response=>{
|
||||
if(response && response.data){
|
||||
this.setState({
|
||||
checkToken:response.data.data
|
||||
})
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
}else{
|
||||
this.setState({checkToken:undefined})
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
// 项目类型:deposit-托管项目,mirror-镜像项目
|
||||
|
|
@ -372,7 +405,9 @@ class Index extends Component {
|
|||
licenseFlag,
|
||||
languageFlag,
|
||||
categoreFlag,
|
||||
tokenConTri
|
||||
tokenConTri,
|
||||
gitHubUrl,
|
||||
checkToken
|
||||
} = this.state;
|
||||
return (
|
||||
<div className="main back-white" style={{padding:"0px",border:"none"}}>
|
||||
|
|
@ -381,7 +416,6 @@ class Index extends Component {
|
|||
<Spin spinning={isSpin}>
|
||||
<Form>
|
||||
<div className="newPanel_content">
|
||||
|
||||
{
|
||||
projectsType && projectsType === "mirror" &&
|
||||
<React.Fragment>
|
||||
|
|
@ -398,7 +432,7 @@ class Index extends Component {
|
|||
<Input placeholder="请输入需要导入到本项目的仓库地址" onBlur={this.ChangeAddr} />
|
||||
)}
|
||||
</Form.Item>
|
||||
<p className="formTip color-orange">示例:https://github.com/Stability-AI/StableStudio.git</p>
|
||||
<p className="formTip" style={{color:"#D1d1c9"}}>示例:https://github.com/Stability-AI/StableStudio.git</p>
|
||||
</React.Fragment>
|
||||
}
|
||||
{
|
||||
|
|
@ -406,10 +440,32 @@ class Index extends Component {
|
|||
<div className="pb10">
|
||||
<p className="mt10 mb10 color-grey-3 pointer" onClick={this.changeMirrorCheck}>
|
||||
需要授权验证<i className={mirrorCheck ? "iconfont icon-xiajiantou font-13 ml10 color-grey-8":"iconfont icon-youjiantou font-13 ml10 color-grey-8"}></i>
|
||||
<span className="ml20 font-12 color-red">如果导入项目为私有仓库,则必须填写相应平台正确的用户名和密码</span>
|
||||
<span className="ml20 font-12" style={{color:"#D1d1c9"}}>
|
||||
如果导入项目为私有仓库,{gitHubUrl ? `则需输入目标平台用户token进行授权,`:"则必须填写相应平台正确的用户名和密码"}
|
||||
{gitHubUrl && <a href="https://forum.gitlink.org.cn/forums/8516/detail" className="color-blue" target="_blank">如何获取token?</a>}
|
||||
</span>
|
||||
</p>
|
||||
{
|
||||
mirrorCheck &&
|
||||
mirrorCheck && gitHubUrl &&
|
||||
<div className="df mb10 token_box">
|
||||
<span className="mr10">Token</span>
|
||||
<input type="password" style={{display:"none"}} />
|
||||
<Form.Item
|
||||
style={{ marginBottom: "0px" }}
|
||||
label=""
|
||||
>
|
||||
{getFieldDecorator('auth_token')(
|
||||
<Input placeholder="请输入对应平台的有效token" style={{width:"240px"}} onBlur={this.blurFunc} />
|
||||
)}
|
||||
</Form.Item>
|
||||
<span style={{marginLeft:"-20px"}}>
|
||||
{ checkToken === false && <i className="iconfont icon-cuo color-red"></i>}
|
||||
{ checkToken === true && <i className="iconfont icon-dui color-green"></i>}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
mirrorCheck && !gitHubUrl &&
|
||||
<div className="df mb10" style={{alignItems:'center'}}>
|
||||
<span className="mr10">用户名</span>
|
||||
<input type="password" style={{display:"none"}} />
|
||||
|
|
@ -447,19 +503,26 @@ class Index extends Component {
|
|||
{getFieldDecorator('user_id', {
|
||||
rules: [{
|
||||
required: true, message: '请选择拥有者'
|
||||
},{
|
||||
validator:(rule, value, callback) => this.checkId(rule, value, callback, OwnerList, '拥有者')
|
||||
}],
|
||||
})(
|
||||
<AutoComplete
|
||||
style={{width:"260px",height:"35px"}}
|
||||
<Select
|
||||
showSearch
|
||||
style={{width:"260px",height:"33px"}}
|
||||
placeholder="请选择拥有者"
|
||||
onChange={(value, e) => this.ChangePlatform(value, e, 'owners', OwnerList)}
|
||||
className="plateAutoComplete"
|
||||
onBlur={(value) => this.blurCategory(value, OwnerList, "owners")}
|
||||
optionFilterProp="children"
|
||||
filterOption={(input, option) =>
|
||||
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}
|
||||
>
|
||||
{owners_list}
|
||||
</AutoComplete>
|
||||
{OwnerList && OwnerList.length > 0 &&
|
||||
OwnerList.map((i,k)=>{
|
||||
return(
|
||||
<Option value={i.id}>{i.name}</Option>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
)}
|
||||
</Form.Item>
|
||||
<span className="ml10 mr10 mt10 font-18">/</span>
|
||||
|
|
@ -681,4 +744,6 @@ class Index extends Component {
|
|||
}
|
||||
}
|
||||
const WrappedIndexForm = Form.create({ name: 'NewWorkForm' })(Index);
|
||||
export default WrappedIndexForm;
|
||||
export default WrappedIndexForm;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@
|
|||
font-size: 1.6em;
|
||||
border-bottom: 1px solid #f0f0f0
|
||||
}
|
||||
.token_box{
|
||||
align-items: center;
|
||||
}
|
||||
.token_box .ant-form-explain{
|
||||
position: absolute;
|
||||
}
|
||||
.newPanel_content{
|
||||
padding:2rem;
|
||||
}
|
||||
|
|
@ -25,7 +31,7 @@
|
|||
min-width: 280px;
|
||||
}
|
||||
.newPanel_content .ant-select-selection{
|
||||
height: 37px;
|
||||
height: 35px;
|
||||
}
|
||||
.newPanel_content .ant-select-selection__rendered,.newPanel_content input{
|
||||
height: 35px;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ class m_editor extends Component {
|
|||
|
||||
render() {
|
||||
const { editorValue, changeValue } = this.state;
|
||||
console.log("editorValue:",editorValue)
|
||||
const { readOnly, editorType,onEmpty,filename,empty, currentBranch, descName, checkName, detail, match: { params },filepath,ideTheme } = this.props;
|
||||
const editor_options = {
|
||||
lineNumbers: "on",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ const NoticeManager = Loadable({
|
|||
loader: () => import("./notice/manager/Index"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const CLAList = Loadable({
|
||||
loader: () => import("./cla/Index"),
|
||||
loading: Loading,
|
||||
});
|
||||
const SSHNew = Loadable({
|
||||
loader: () => import("./sub/New"),
|
||||
loading: Loading,
|
||||
|
|
@ -116,6 +119,7 @@ function Index(props){
|
|||
<ul className="securityUl ul-border-buttom">
|
||||
<li>安全设置</li>
|
||||
<li className={pathname.indexOf("/settings/SSH")>-1 ?"active":""}><Link to={`/settings/SSH`}><i className="iconfont icon-xuanzhongssh_icon mr5 font-14"></i><span className="text-shodow-bold">SSH密钥</span></Link></li>
|
||||
<li className={pathname.indexOf("/settings/CLA")>-1 ?"active":""}><Link to={`/settings/CLA`}><i className="iconfont icon-a-zu2044 mr5 font-13"></i><span className="text-shodow-bold">我的CLA</span></Link></li>
|
||||
</ul>
|
||||
<ul className="securityUl">
|
||||
<li>Bot开发</li>
|
||||
|
|
@ -138,6 +142,12 @@ function Index(props){
|
|||
<PrivateLetter{...props} {...p}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/settings/CLA"
|
||||
render={(p) => (
|
||||
<CLAList {...props} {...p}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/settings/notice"
|
||||
render={(p) => (
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
import React from 'react';
|
||||
import { AlignCenter } from '../../Component/layout';
|
||||
import Modals from '../../Component/PublicModal/Index';
|
||||
import { Button } from 'antd';
|
||||
|
||||
function DeleteBox({visible , onCancel,onSuccess,pr_need}){
|
||||
return(
|
||||
<Modals
|
||||
visible={visible}
|
||||
onCancel={onCancel}
|
||||
title={"解除协议"}
|
||||
btn={
|
||||
<div>
|
||||
<Button size={'large'} onClick={onCancel}>取消</Button>
|
||||
<Button type={"danger"} size={"large"} onClick={onSuccess}>确定</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="desc">
|
||||
<AlignCenter className="descMain">
|
||||
<i className="iconfont icon-jinggao1 mr10 font-20 red"></i>确定解除协议吗?</AlignCenter>
|
||||
{ pr_need && <p>您解除协议后,提交的合并请求对项目成员将不再可见(已存在的开启的合并请求也将被隐藏)</p> }
|
||||
</div>
|
||||
</Modals>
|
||||
)
|
||||
}
|
||||
export default DeleteBox;
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
import React,{useEffect,useState} from 'react';
|
||||
import './index.scss';
|
||||
import logo from '../img/icon.svg';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Button , Spin } from 'antd';
|
||||
import Nodata from '../../Nodata';
|
||||
import DeleteBox from './DeleteBox';
|
||||
import axios from 'axios';
|
||||
|
||||
function Index(props){
|
||||
const { current_user } = props;
|
||||
const[ lists, setLists] = useState(undefined);
|
||||
const[ isSpin, setIsSpin] = useState(false);
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ cancelKey , setCancelKey ] = useState(undefined);
|
||||
const [ pr_need , setPr_need ] = useState(true);
|
||||
useEffect(()=>{
|
||||
document.title = "我的CLA";
|
||||
},[])
|
||||
|
||||
useEffect(()=>{
|
||||
if(current_user && current_user.user_id){
|
||||
setIsSpin(true);
|
||||
getClaLists();
|
||||
}
|
||||
},[current_user])
|
||||
|
||||
function getClaLists(){
|
||||
const url = `/users/${current_user.user_id}/clas.json`;
|
||||
axios.get(url).then(response=>{
|
||||
if(response && response.data){
|
||||
setLists(response.data.user_clas);
|
||||
setIsSpin(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function onSuccess(){
|
||||
if(cancelKey && (current_user && current_user.user_id)){
|
||||
const url = `/users/${current_user && current_user.user_id}/clas/${cancelKey}.json`;
|
||||
axios.delete(url).then(response=>{
|
||||
if(response){
|
||||
setVisible(false);
|
||||
props.showNotification("协议解除成功!");
|
||||
getClaLists();
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
}
|
||||
return(
|
||||
<div className="cla_personal">
|
||||
<DeleteBox visible={visible} pr_need={pr_need} onCancel={()=>{setVisible(false);setCancelKey(undefined)}} onSuccess={onSuccess}/>
|
||||
<div className="default_head">我签署的CLA(开源贡献者协议)</div>
|
||||
{
|
||||
lists && lists.length>0 &&
|
||||
<ul className="cla_lists">
|
||||
{
|
||||
lists.map((i,k)=>{
|
||||
return(
|
||||
<li key={k}>
|
||||
<img src={logo} alt="" />
|
||||
<div>
|
||||
<Link to={`/${i.organization && i.organization.name}/cla/${i.cla && i.cla.key}`} className="agree_name task-hide">{i.cla && i.cla.name}</Link>
|
||||
{i.state && <span className="agree_status">签署状态<span className={i.state === "signed" ? "green_tip" :"grey_tip"}>{i.state === "signed" ? "生效中" : "已解除"}</span></span> }
|
||||
<span>签署邮箱<span className="ml10">{i.email}</span></span>
|
||||
<span>签署时间<span className="ml10">{i.created_at}</span></span>
|
||||
<p className="mt8">
|
||||
<Button onClick={()=>{props.history.push(`/${i.organization && i.organization.name}/cla/${i.cla && i.cla.key}`)}} style={{color:"#466aff",borderColor:"#466aff"}}>查看协议</Button>
|
||||
{ i.state === "signed" && <Button style={{color:"#ff0c0c",borderColor:"#ff0c0c"}} className="ml20" onClick={()=>{setVisible(true);setCancelKey(i.id);setPr_need(i.cla.pr_need)}}>解除协议</Button>}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
{
|
||||
lists && lists.length === 0 && <Nodata _html="暂无数据"/>
|
||||
}
|
||||
{
|
||||
!lists && <div style={{minHeight:"300px",display:'flex',alignItems:"center",justifyContent:"center"}}><Spin spinning={isSpin}></Spin></div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Index;
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
.default_head{
|
||||
height: 65px;
|
||||
line-height: 64px;
|
||||
border-bottom: 1px solid rgba(224, 230, 245, 1);
|
||||
color:#151d40;
|
||||
font-size:17px;
|
||||
padding-bottom:20px;
|
||||
}
|
||||
.cla_lists{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
li{
|
||||
width: 478px;
|
||||
margin-right: 26px;
|
||||
border:1px solid;
|
||||
border-color:rgba(153, 153, 153, 0.3);
|
||||
border-radius:6px;
|
||||
padding:30px 26px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-top: 25px;
|
||||
&>img{
|
||||
width: 65px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
&>div{
|
||||
flex:1;
|
||||
width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
&>span{
|
||||
color:rgba(76, 88, 118, 1);
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 10px!important;
|
||||
}
|
||||
.agree_status{
|
||||
>span{
|
||||
margin-left: 20px;
|
||||
position: relative;
|
||||
color:#8a94a2 ;
|
||||
&::before{
|
||||
position: absolute;
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-radius: 50%;
|
||||
left: -11px;
|
||||
content: "";
|
||||
background-color: #8a94a2;
|
||||
top:50%;
|
||||
margin-top: -3px;
|
||||
}
|
||||
&.green_tip{
|
||||
color: #009b28;
|
||||
}
|
||||
&.green_tip::before{
|
||||
background-color: #009b28;
|
||||
}
|
||||
}
|
||||
}
|
||||
.agree_name{
|
||||
color:#151d40;
|
||||
font-size:16px;
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
&:nth-child(2n){
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="65.368" height="70.129" viewBox="0 0 65.368 70.129">
|
||||
<g id="icon" transform="translate(-680.606 -410)">
|
||||
<path id="路径_3391" data-name="路径 3391" d="M190.644,100.032H130.724A2.724,2.724,0,0,0,128,102.756v64.682a2.724,2.724,0,0,0,2.724,2.724h59.921a2.724,2.724,0,0,0,2.724-2.724V102.756A2.724,2.724,0,0,0,190.644,100.032Z" transform="translate(552.606 309.968)" fill="#e6e6e6"/>
|
||||
<rect id="矩形_367" data-name="矩形 367" width="49" height="53" transform="translate(689 419)" fill="#fff"/>
|
||||
<g id="协议" transform="translate(687.555 417.455)">
|
||||
<path id="路径_3391-2" data-name="路径 3391" d="M177.325,100.032H130.145A2.145,2.145,0,0,0,128,102.177v50.93a2.145,2.145,0,0,0,2.145,2.145h47.181a2.145,2.145,0,0,0,2.145-2.145v-50.93A2.145,2.145,0,0,0,177.325,100.032Zm1.187,1.058v53.25H129.125V101.09Z" transform="translate(-128 -100.032)" fill="#aeb4bb"/>
|
||||
<path id="路径_3392" data-name="路径 3392" d="M308.3,544v4.289H288V544Zm-11.6,8.578v4.289H288v-4.289Z" transform="translate(-280.604 -510.521)" fill="#c4c7cc"/>
|
||||
<text id="CLA" transform="translate(25.444 22.609)" fill="#5f6872" stroke="rgba(0,0,0,0)" stroke-width="1" font-size="17" font-family="STFangsong"><tspan x="-16.023" y="0">CLA</tspan></text>
|
||||
</g>
|
||||
<path id="icon_徽章" d="M204.579,70.459a6.149,6.149,0,1,0-10.543,4.3,6.22,6.22,0,0,0,.855.729v5a.194.194,0,0,0,.278.174l3.246-1.569,3.246,1.569a.194.194,0,0,0,.278-.174V75.509a6.212,6.212,0,0,0,.837-.7A6.108,6.108,0,0,0,204.579,70.459Zm-11.071,0a4.922,4.922,0,1,1,4.922,4.922A4.928,4.928,0,0,1,193.507,70.459Zm7.206,8.384-2.213-1.07a.194.194,0,0,0-.168,0l-2.213,1.07V76.16a6.19,6.19,0,0,0,4.6.011v2.672Z" transform="translate(526.76 384.613)" fill="#009b28"/>
|
||||
<circle id="椭圆_67" data-name="椭圆 67" cx="3" cy="3" r="3" transform="translate(722 452)" fill="rgba(0,155,40,0.31)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -14,6 +14,10 @@ const GroupNew = Loadable({
|
|||
loader: () => import("./Group/GroupNew"),
|
||||
loading: Loading,
|
||||
});
|
||||
const CLAinfos = Loadable({
|
||||
loader: () => import("./Setting/cla/CLAinfos"),
|
||||
loading: Loading,
|
||||
});
|
||||
const New = Loadable({
|
||||
loader: () => import("./New"),
|
||||
loading: Loading,
|
||||
|
|
@ -40,6 +44,13 @@ export default withRouter(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(
|
|||
return (
|
||||
<div className="newMain">
|
||||
<Switch>
|
||||
{/* 协议详情+签署协议 */}
|
||||
<Route
|
||||
path="/:OIdentifier/cla/:claid"
|
||||
render={(p) => (
|
||||
<CLAinfos {...props} {...p}/>
|
||||
)}
|
||||
></Route>
|
||||
{/* 新建组织 */}
|
||||
<Route
|
||||
path="/organize/new"
|
||||
|
|
@ -75,7 +86,6 @@ export default withRouter(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(
|
|||
return <TeamDetailIndex {...props} {...p}/>
|
||||
}}
|
||||
></Route>
|
||||
|
||||
|
||||
{/* 组织详情(包含组织设置) */}
|
||||
<Route
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ export default Form.create()(
|
|||
}
|
||||
const url = `/organizations.json`;
|
||||
axios.post(url,{
|
||||
...values,image
|
||||
...values,image,visibility:"common"
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
showNotification("组织创建成功!");
|
||||
|
|
@ -121,7 +121,7 @@ export default Form.create()(
|
|||
[],
|
||||
<Input placeholder="请输入地址" maxLength={50}/>,false
|
||||
)}
|
||||
{helper(
|
||||
{/* {helper(
|
||||
'可见性',
|
||||
"visibility",
|
||||
[{ required: true, message: "请选择可见性" }],
|
||||
|
|
@ -130,7 +130,7 @@ export default Form.create()(
|
|||
<Radio style={radioStyle} value="limited" key={2}>受限<span className="color-grey-8">(仅对登录用户可见)</span></Radio>
|
||||
<Radio style={radioStyle} value="privacy" key={3}>私有<span className="color-grey-8">(仅对组织成员可见)</span></Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
<p className="font-16 lables must">选择头像</p>
|
||||
<UploadImage getImage={getImage}/>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ const ListName = styled.div`{
|
|||
margin-bottom:8px;
|
||||
height:18px;
|
||||
line-height:18px;
|
||||
width:210px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}`;
|
||||
const ColorListName = styled.div`{
|
||||
color:rgba(31, 35, 41, 1);
|
||||
|
|
@ -34,6 +38,10 @@ const ColorListName = styled.div`{
|
|||
margin-bottom:8px;
|
||||
height:18px;
|
||||
line-height:18px;
|
||||
width:230px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}`
|
||||
const Img = styled.img`{
|
||||
border-radius:50%;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export default Form.create()(
|
|||
if(!error){
|
||||
const url = `/organizations/${organizeDetail.id}.json`;
|
||||
axios.patch(url,{
|
||||
...values,image:imageFlag ? image : undefined
|
||||
...values,image:imageFlag ? image : undefined,visibility:"common"
|
||||
}).then(result=>{
|
||||
if(result && result.data){
|
||||
showNotification("组织信息更新成功!");
|
||||
|
|
@ -122,7 +122,7 @@ export default Form.create()(
|
|||
})
|
||||
}
|
||||
return(
|
||||
<div>
|
||||
<div style={{border:"1px solid #eee"}}>
|
||||
<WhiteBack>
|
||||
<Title>基本设置</Title>
|
||||
<Modals visible={privacyVisible} okText={"确认"} cancelText={"取消"} onCancel={concelChangePrivacy} onOk={()=>setPrivacyVisible(false)}>
|
||||
|
|
@ -172,7 +172,7 @@ export default Form.create()(
|
|||
[],
|
||||
<Input placeholder="请输入城市"/>
|
||||
)}
|
||||
{helper(
|
||||
{/* {helper(
|
||||
'可见性:',
|
||||
"visibility",
|
||||
[],
|
||||
|
|
@ -181,7 +181,7 @@ export default Form.create()(
|
|||
<Radio value="limited" style={radioStyle}>受限<span>(仅对登录用户可见)</span></Radio>
|
||||
<Radio value="privacy" style={radioStyle}>私有<span>(仅对组织成员可见)</span></Radio>
|
||||
</Radio.Group>
|
||||
)}
|
||||
)} */}
|
||||
{helper(
|
||||
'权限:',
|
||||
"repo_admin_change_team_access",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import GroupItems from '../TeamGroupItems';
|
|||
const limit = 8;
|
||||
function TeamSettingGroup({organizeDetail,history,current_user}){
|
||||
return(
|
||||
<WhiteBack>
|
||||
<WhiteBack style={{border:"1px solid #eee"}}>
|
||||
<Banner>组织团队管理</Banner>
|
||||
<GroupItems limit={limit} organizeDetail={organizeDetail} count={4} history={history} current_user={current_user}/>
|
||||
</WhiteBack>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ import React , { useEffect , useState } from 'react';
|
|||
import { Box , Long , Short , Gap } from '../../Component/layout';
|
||||
import Title from '../../Component/Title';
|
||||
import Setnav from '../../Component/Setnav';
|
||||
import './teamSetting.scss';
|
||||
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import Loadable from "react-loadable";
|
||||
import Loading from "../../../Loading";
|
||||
import claIcon from '../images/cla-icon.png';
|
||||
|
||||
|
||||
const Group = Loadable({
|
||||
|
|
@ -28,11 +30,18 @@ const Hooks = Loadable({
|
|||
loader: () => import("./TeamSettingHooks"),
|
||||
loading: Loading,
|
||||
});
|
||||
const CLA = Loadable({
|
||||
loader: () => import("./cla/TeamSettingCLA"),
|
||||
loading: Loading,
|
||||
});
|
||||
const CLANew = Loadable({
|
||||
loader: () => import("./cla/TeamSettingCLAEdit"),
|
||||
loading: Loading,
|
||||
});
|
||||
export default (( props )=>{
|
||||
const pathname = props.location.pathname;
|
||||
const OIdentifier = props.match.params.OIdentifier;
|
||||
const {organizeDetail} = props;
|
||||
|
||||
useEffect(()=>{
|
||||
if(organizeDetail){
|
||||
const {nickname} = organizeDetail;
|
||||
|
|
@ -48,7 +57,9 @@ export default (( props )=>{
|
|||
a = 1;
|
||||
}else if(pathname === `/${OIdentifier}/setting/group`){
|
||||
a = 3;
|
||||
}else if(pathname === `/${OIdentifier}/setting/hooks`){
|
||||
// }else if(pathname === `/${OIdentifier}/setting/hooks`){
|
||||
// a = 4;
|
||||
}else if(pathname.indexOf(`/${OIdentifier}/setting/agreement`)>-1){
|
||||
a = 4;
|
||||
}
|
||||
return a;
|
||||
|
|
@ -60,6 +71,7 @@ export default (( props )=>{
|
|||
{name:'组织成员管理',icon:"icon-zuzhichengyuan",href:`/${OIdentifier}/setting/member`},
|
||||
{name:'组织团队管理',icon:"icon-zuzhixiangmu",href:`/${OIdentifier}/setting/group`},
|
||||
// {name:'管理web钩子',icon:"icon-zhongqingdianxinicon10",href:`/${OIdentifier}/setting/hooks`}
|
||||
{name:'CLA管理',img:claIcon,href:`/${OIdentifier}/setting/agreement`,hide:organizeDetail && !organizeDetail.enabling_cla}
|
||||
],
|
||||
active
|
||||
}
|
||||
|
|
@ -70,8 +82,29 @@ export default (( props )=>{
|
|||
</Short>
|
||||
<Long>
|
||||
<Gap >
|
||||
<div style={{border:"1px solid #eee"}}>
|
||||
<div>
|
||||
<Switch>
|
||||
{organizeDetail && organizeDetail.enabling_cla &&
|
||||
<Route
|
||||
path="/:OIdentifier/setting/agreement/new"
|
||||
render={(p) => (
|
||||
<CLANew {...props} {...p}/>
|
||||
)}
|
||||
></Route>
|
||||
}
|
||||
{organizeDetail && organizeDetail.enabling_cla && <Route
|
||||
path="/:OIdentifier/setting/agreement/:claid"
|
||||
render={(p) => (
|
||||
<CLANew {...props} {...p}/>
|
||||
)}
|
||||
></Route>}
|
||||
{organizeDetail && organizeDetail.enabling_cla &&<Route
|
||||
path="/:OIdentifier/setting/agreement"
|
||||
render={(p) => (
|
||||
<CLA {...props} {...p}/>
|
||||
)}
|
||||
></Route>
|
||||
}
|
||||
<Route
|
||||
path="/:OIdentifier/setting/hooks"
|
||||
render={() => (
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ export default (({organizeDetail,history,match})=>{
|
|||
}).catch(error=>{})
|
||||
}
|
||||
return(
|
||||
<WhiteBack>
|
||||
<WhiteBack style={{border:"1px solid #eee"}}>
|
||||
<Title>
|
||||
<span>组织成员管理</span>
|
||||
{/* <AlignCenter>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export default Form.create()(forwardRef((props)=>{
|
|||
})
|
||||
}
|
||||
return(
|
||||
<div>
|
||||
<div style={{border:"1px solid #eee"}}>
|
||||
<Title>
|
||||
<span>组织首页管理</span>
|
||||
</Title>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
import React,{ forwardRef, useState , useEffect } from 'react';
|
||||
import '../teamSetting.scss';
|
||||
import RenderHtml from '../../../../components/render-html';
|
||||
import { Button , Form , Input , Spin } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
function CLAinfos(props){
|
||||
const { form , current_user , showLoginDialog } = props;
|
||||
const { getFieldDecorator , validateFields , setFieldsValue , getFieldsValue} = form;
|
||||
|
||||
const OIdentifier = props.match.params.OIdentifier;
|
||||
const claid = props.match.params.claid;
|
||||
|
||||
const [ details, setDetails ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
if(current_user && current_user.email){
|
||||
setFieldsValue({
|
||||
email:current_user.email
|
||||
})
|
||||
}
|
||||
},[current_user,details])
|
||||
|
||||
useEffect(()=>{
|
||||
if(current_user &&!current_user.login){
|
||||
props.history.push(`/login?go_page=/${OIdentifier}/cla/${claid}`);
|
||||
}
|
||||
},[current_user])
|
||||
|
||||
useEffect(()=>{
|
||||
if(claid){
|
||||
getDetails();
|
||||
}
|
||||
},[claid])
|
||||
|
||||
function getDetails(){
|
||||
const url = `/organizations/${OIdentifier}/clas/${claid}.json`;
|
||||
axios.get(url).then(response=>{
|
||||
if(response && response.data){
|
||||
setDetails(response.data);
|
||||
document.title = `${response.data.name}`;
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function agreeFunc(){
|
||||
validateFields((error,values)=>{
|
||||
if(!error){
|
||||
const url = `/users/${current_user && current_user.user_id}/clas.json`;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
cla_id:details && details.id,
|
||||
email:(current_user && current_user.email) || values.email
|
||||
}).then(response=>{
|
||||
if(response && response.data){
|
||||
props.showNotification('协议签署成功!');
|
||||
window.scrollTo(0,0);
|
||||
getDetails();
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return(
|
||||
details ?
|
||||
<div className="cla_allinfos">
|
||||
<div className="cla_infos_header">
|
||||
<div>
|
||||
<img src={getImageUrl(details.organization && details.organization.avatar_url)} alt="" />
|
||||
<div className="cla_i">
|
||||
<p className="cla_i_name">{details.name}</p>
|
||||
<p className="cla_o_name">{details.organization && details.organization.nickname}</p>
|
||||
{details.is_sign && details.cla_sign_email && <p className="cla_i_email">签署邮箱<span className="ml10">{details.cla_sign_email}</span></p> }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{margin:"0px auto",width:"1200px",paddingBottom:"50px"}}>
|
||||
{details.is_sign && <div className="wirtes_tips"><span>您已签署协议,可在“个人设置 > 我的 CLA”中查看和管理本协议</span></div> }
|
||||
<div className="cla_c">
|
||||
<p className="cla_c_title">协议内容</p>
|
||||
<RenderHtml className="cla_c_html imageLayerParent" value={details.content} url={props.history.location}/>
|
||||
</div>
|
||||
{
|
||||
!details.is_sign && !details.is_member &&
|
||||
<Form>
|
||||
<div className="form_div">
|
||||
<Form.Item label="真实姓名">
|
||||
{getFieldDecorator("real_name",{
|
||||
rules:[{ required: true, message: "请输入您的真实姓名" }]
|
||||
})(
|
||||
<Input placeholder="请输入真实姓名" maxLength={30}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="签署邮箱">
|
||||
{getFieldDecorator("email",{
|
||||
rules:[{ required: true, message: "请输入签署邮箱" }]
|
||||
})(
|
||||
<Input placeholder="请输入签署邮箱" maxLength={30} disabled={current_user && current_user.email}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
<Button type={"primary"} style={{marginTop:"20px"}} onClick={agreeFunc}>接受并签署协议</Button>
|
||||
</Form>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div style={{display:'flex',alignItems:'center',justifyContent:"center",minHeight:"500px"}}><Spin /></div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(forwardRef(CLAinfos))
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import React,{ useState , useEffect } from 'react';
|
||||
import Title from '../../../Component/Title';
|
||||
import defaultimg from '../../images/cla-icon-big.png';
|
||||
import Logo from '../../images/icon.svg';
|
||||
import { Button, Spin } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
function TeamSettingCLA(props){
|
||||
const OIdentifier = props.match.params.OIdentifier;
|
||||
const [ list , setList ] = useState(undefined);
|
||||
const [ isSpin , setisSpin ] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if(OIdentifier){
|
||||
setisSpin(true);
|
||||
getList();
|
||||
}
|
||||
},[OIdentifier])
|
||||
|
||||
function getList(){
|
||||
const url = `/organizations/${OIdentifier}/clas.json`;
|
||||
axios.get(url).then(response=>{
|
||||
if(response){
|
||||
let l = {...response.data};
|
||||
setList(l);
|
||||
setisSpin(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
return(
|
||||
<div style={{border:list && list.id ? "none":"1px solid #eee"}}>
|
||||
<Title>CLA管理</Title>
|
||||
{
|
||||
(list && list.id) &&
|
||||
<ul className="cla_list_box">
|
||||
<li>
|
||||
<img src={Logo} width="65px" className="mr20" alt="" />
|
||||
<div className="cla_list_infos">
|
||||
<p className="task-hide cla_name">{list.name}</p>
|
||||
<span className="cla_personCount">签署人数<span>{list.count || 0}</span></span>
|
||||
<div className="cla_btn">
|
||||
<Button href={`/${OIdentifier}/cla/${list.key}`} target="_blank" style={{color:"#466aff",borderColor:"#466aff"}}>查看协议</Button>
|
||||
<Button onClick={()=>{props.history.push(`/${OIdentifier}/setting/agreement/${list.key}`)}} style={{color:"#466aff",borderColor:"#466aff"}} className="ml22">编辑</Button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
}
|
||||
{
|
||||
(list && !list.id) &&
|
||||
<div className="cla_default_box">
|
||||
<img src={defaultimg} alt="" width="68px"/>
|
||||
<p className="cla_default_desc">CLA( Contributor License Agreement)指开源贡献者许可协议。您可以为本组织配置CLA,当非组织用户作为贡献者在组织仓库提交合并请求之前,需要签署CLA后才可正常提交合并请求</p>
|
||||
<Button type={'primary'} onClick={()=>{props.history.push(`/${OIdentifier}/setting/agreement/new`)}}>添加协议</Button>
|
||||
</div>
|
||||
}
|
||||
{ list === undefined && <div style={{minHeight:"280px",display:"flex",alignItems:'center',justifyContent:"center"}}><Spin spinning={isSpin}/></div>}
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default TeamSettingCLA;
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
import React ,{ forwardRef , useState , useEffect } from 'react';
|
||||
import Title from '../../../Component/Title';
|
||||
import MdEditor from "../../../../modules/tpm/challengesnew/tpm-md-editor";
|
||||
import { Button, Form , Input , Switch } from 'antd';
|
||||
import { turnbar , returnbar } from 'educoder';
|
||||
import { Link } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
|
||||
export default Form.create()(
|
||||
forwardRef((props)=>{
|
||||
const { form , match , showNotification , history , location } = props;
|
||||
const { getFieldDecorator , validateFields , setFieldsValue , getFieldsValue} = form;
|
||||
const [ switchBtn , setSwitchBtn ] = useState(false);
|
||||
const [ details , setDetails] = useState(undefined);
|
||||
const OIdentifier = match.params.OIdentifier;
|
||||
const claid = match.params.claid;
|
||||
const keyBefore = window.location.origin+`/${OIdentifier}/cla/`;
|
||||
|
||||
useEffect(()=>{
|
||||
if(claid){
|
||||
getDetails();
|
||||
}
|
||||
},[claid])
|
||||
|
||||
function getDetails(){
|
||||
const url = `/organizations/${OIdentifier}/clas/${claid}.json`;
|
||||
axios.get(url).then(response=>{
|
||||
if(response && response.data){
|
||||
setFieldsValue({
|
||||
...response.data
|
||||
})
|
||||
setSwitchBtn(response.data.pr_need);
|
||||
setDetails(response.data);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
|
||||
// 新建保存
|
||||
function saveClaFunc(){
|
||||
validateFields((error,values)=>{
|
||||
if(!error){
|
||||
const params = {
|
||||
pr_need:switchBtn,
|
||||
...values,
|
||||
key:turnbar(values.key)
|
||||
}
|
||||
if(claid){
|
||||
const url = `/organizations/${OIdentifier}/clas/${claid}.json`;
|
||||
axios.put(url,{
|
||||
...params
|
||||
}).then(response=>{
|
||||
if(response && response.data){
|
||||
window.scrollTo(0,0);
|
||||
showNotification("协议更新成功!");
|
||||
history.push(`/${OIdentifier}/setting/agreement`);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}else{
|
||||
const url = `/organizations/${OIdentifier}/clas.json`;
|
||||
axios.post(url,{
|
||||
...params
|
||||
}).then(response=>{
|
||||
if(response && response.data && response.data.id){
|
||||
window.scrollTo(0,0);
|
||||
showNotification("协议创建成功!");
|
||||
history.push(`/${OIdentifier}/setting/agreement`);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function checkKeyReg(rule, value, callback){
|
||||
let reg = /^[a-zA-Z0-9][a-zA-Z0-9_]*[a-zA-Z0-9]+$/g
|
||||
if(value && !reg.test(value)){
|
||||
callback("协议标识长度2-30,只能以数字、字母开头结尾,可包含下划线");
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
return(
|
||||
<div style={{border:'1px solid #eee'}}>
|
||||
{
|
||||
claid ?
|
||||
<Title><span><Link to={`/${OIdentifier}/setting/agreement`} className="color-blue mr3">CLA管理</Link>><span className="ml2">编辑协议</span></span></Title>
|
||||
: <Title>创建CLA</Title>
|
||||
}
|
||||
|
||||
<Form style={{padding:"20px 30px 30px 30px"}}>
|
||||
<Form.Item label="协议名称">
|
||||
{getFieldDecorator("name",{
|
||||
rules:[{ required: true, message: "请输入协议名称" }]
|
||||
})(
|
||||
<Input placeholder="请输入协议名称" maxLength={30}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="协议标识">
|
||||
{getFieldDecorator("key",{
|
||||
rules:[
|
||||
{ required: true, message: "请输入协议标识" },
|
||||
{ validator: checkKeyReg }
|
||||
]
|
||||
})(
|
||||
<Input addonBefore={keyBefore} autoComplete={"off"} placeholder="请输入协议标识" minLength={2} maxLength={30}/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="协议内容">
|
||||
{getFieldDecorator("content",{
|
||||
rules:[{ required: true, message: "请输入协议内容" }]
|
||||
})(
|
||||
<MdEditor
|
||||
height={280}
|
||||
mdID={"cla_md"}
|
||||
noStorage={true}
|
||||
placeholder="请输入协议内容"
|
||||
initValue={details && details.content}
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<p className="mb10">合并请求准入设置:</p>
|
||||
<span style={{display:"flex",alignItems:"center"}}>
|
||||
<Switch checked={switchBtn} onChange={(e)=>setSwitchBtn(e)}/>
|
||||
<span className={`ml10`} style={{color:switchBtn ? "#466aff" :"#4c5b76"}}>要求 Pull Request 中所有提交者必须签署 CLA 方可合并</span>
|
||||
</span>
|
||||
<Button onClick={saveClaFunc} className="mt30" type={"primary"}>确认</Button>
|
||||
{/* { claid && <Button style={{color:"#ff0c0c",borderColor:"#ff0c0c"}} className="ml20">解除协议</Button>} */}
|
||||
</Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
))
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
.cla_default_box{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 320px;
|
||||
.cla_default_desc{
|
||||
width: 80%;
|
||||
color:#666666;
|
||||
font-size:15px;
|
||||
line-height:30px;
|
||||
text-align:center;
|
||||
margin:20px 0px!important;
|
||||
}
|
||||
}
|
||||
.cla_list_box{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 25px;
|
||||
li{
|
||||
margin-right: 24px;
|
||||
border:1px solid;
|
||||
border-color:rgba(153, 153, 153, 0.3);
|
||||
border-radius:6px;
|
||||
width: 446px;
|
||||
display: flex;
|
||||
padding:30px 26px;
|
||||
box-sizing: border-box;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 25px;
|
||||
&:nth-child(2n){
|
||||
margin-right: 0px;
|
||||
}
|
||||
.cla_list_infos{
|
||||
flex:1;
|
||||
width: 0;
|
||||
.cla_name{
|
||||
color:#151d40;
|
||||
font-size:16px;
|
||||
padding-bottom:20px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
word-break: break-all;
|
||||
margin-bottom: 14px!important;
|
||||
}
|
||||
.cla_personCount{
|
||||
color:#4c5876;
|
||||
display: block;
|
||||
margin-bottom: 15px!important;
|
||||
span{
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.cla_allinfos{
|
||||
.cla_infos_header{
|
||||
background-color:rgba(70, 106, 255, 0.05);
|
||||
padding:30px 0px;
|
||||
&>div{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin:0px auto;
|
||||
width: 1200px;
|
||||
&>img{
|
||||
height: 94px;
|
||||
margin-right: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.cla_i{
|
||||
flex: 1;
|
||||
width: 0;
|
||||
.cla_i_name{
|
||||
font-weight:700;
|
||||
color:#333333;
|
||||
font-size:24px;
|
||||
height: 33px;
|
||||
line-height: 33px;
|
||||
margin-bottom: 0px!important;
|
||||
}
|
||||
.cla_o_name,.cla_i_email{
|
||||
color:#4c5b76;
|
||||
font-size:15px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
.cla_i_email{
|
||||
margin-top: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.wirtes_tips{
|
||||
margin:25px 0px;
|
||||
span{
|
||||
padding:9px 18px;
|
||||
font-size:15px;
|
||||
border:1px solid;
|
||||
border-radius:6px;
|
||||
border-color:#009b28;
|
||||
color: #009b28;
|
||||
}
|
||||
}
|
||||
.cla_c{
|
||||
width: 100%;
|
||||
background-color:rgba(245, 245, 245, 0.5);
|
||||
border-radius: 2px;
|
||||
padding:25px;
|
||||
margin:16px auto;
|
||||
.cla_c_title{
|
||||
font-weight:700;
|
||||
color:#202d40;
|
||||
font-size:15px;
|
||||
padding-bottom:20px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin-bottom: 15px!important;
|
||||
}
|
||||
}
|
||||
.form_div{
|
||||
display: flex;
|
||||
&>div{
|
||||
flex:1
|
||||
}
|
||||
&>div:first-child{
|
||||
margin-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ import { setSeoMeta } from "educoder";
|
|||
import Cards from '../../Component/Cards';
|
||||
import axios from 'axios';
|
||||
import '../Index.scss';
|
||||
|
||||
const GroupDetails = Loadable({
|
||||
loader: () => import("../Group/GroupDetails"),
|
||||
loading: Loading,
|
||||
|
|
@ -40,6 +39,9 @@ function Detail(props){
|
|||
if(pathname){
|
||||
if(pathname.indexOf(`/${OIdentifier}/setting`)>-1){
|
||||
setFlag(false);
|
||||
if(detail && !detail.is_admin ){
|
||||
props.history.push("/nopage");
|
||||
}
|
||||
}else{
|
||||
setFlag(true);
|
||||
}
|
||||
|
|
@ -49,7 +51,7 @@ function Detail(props){
|
|||
setButtonflagFlag(false);
|
||||
}
|
||||
}
|
||||
},[pathname])
|
||||
},[pathname,detail])
|
||||
|
||||
useEffect(()=>{
|
||||
if(OIdentifier){
|
||||
|
|
@ -111,7 +113,7 @@ function Detail(props){
|
|||
}
|
||||
/>
|
||||
}
|
||||
<Switch {...props}>
|
||||
<Switch>
|
||||
|
||||
{/* 组织团队-详情 */}
|
||||
<Route
|
||||
|
|
@ -134,12 +136,14 @@ function Detail(props){
|
|||
return <Group {...props} {...p} organizeDetail={detail}/>
|
||||
}}
|
||||
></Route>
|
||||
<Route
|
||||
path="/:OIdentifier/setting"
|
||||
render={(p) => {
|
||||
return <Setting {...props} {...p} organizeDetail={detail} updateFunc={updateDetail}/>
|
||||
}}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/:OIdentifier/setting"
|
||||
render={(p) => {
|
||||
return <Setting {...props} {...p} organizeDetail={detail} updateFunc={updateDetail}/>
|
||||
}}
|
||||
></Route>
|
||||
|
||||
<Route
|
||||
path="/:OIdentifier"
|
||||
render={(p) => {
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 743 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="65.368" height="70.129" viewBox="0 0 65.368 70.129">
|
||||
<g id="icon" transform="translate(-680.606 -410)">
|
||||
<path id="路径_3391" data-name="路径 3391" d="M190.644,100.032H130.724A2.724,2.724,0,0,0,128,102.756v64.682a2.724,2.724,0,0,0,2.724,2.724h59.921a2.724,2.724,0,0,0,2.724-2.724V102.756A2.724,2.724,0,0,0,190.644,100.032Z" transform="translate(552.606 309.968)" fill="#e6e6e6"/>
|
||||
<rect id="矩形_367" data-name="矩形 367" width="49" height="53" transform="translate(689 419)" fill="#fff"/>
|
||||
<g id="协议" transform="translate(687.555 417.455)">
|
||||
<path id="路径_3391-2" data-name="路径 3391" d="M177.325,100.032H130.145A2.145,2.145,0,0,0,128,102.177v50.93a2.145,2.145,0,0,0,2.145,2.145h47.181a2.145,2.145,0,0,0,2.145-2.145v-50.93A2.145,2.145,0,0,0,177.325,100.032Zm1.187,1.058v53.25H129.125V101.09Z" transform="translate(-128 -100.032)" fill="#aeb4bb"/>
|
||||
<path id="路径_3392" data-name="路径 3392" d="M308.3,544v4.289H288V544Zm-11.6,8.578v4.289H288v-4.289Z" transform="translate(-280.604 -510.521)" fill="#c4c7cc"/>
|
||||
<text id="CLA" transform="translate(25.444 22.609)" fill="#5f6872" stroke="rgba(0,0,0,0)" stroke-width="1" font-size="17" font-family="STFangsong"><tspan x="-16.023" y="0">CLA</tspan></text>
|
||||
</g>
|
||||
<path id="icon_徽章" d="M204.579,70.459a6.149,6.149,0,1,0-10.543,4.3,6.22,6.22,0,0,0,.855.729v5a.194.194,0,0,0,.278.174l3.246-1.569,3.246,1.569a.194.194,0,0,0,.278-.174V75.509a6.212,6.212,0,0,0,.837-.7A6.108,6.108,0,0,0,204.579,70.459Zm-11.071,0a4.922,4.922,0,1,1,4.922,4.922A4.928,4.928,0,0,1,193.507,70.459Zm7.206,8.384-2.213-1.07a.194.194,0,0,0-.168,0l-2.213,1.07V76.16a6.19,6.19,0,0,0,4.6.011v2.672Z" transform="translate(526.76 384.613)" fill="#009b28"/>
|
||||
<circle id="椭圆_67" data-name="椭圆 67" cx="3" cy="3" r="3" transform="translate(722 452)" fill="rgba(0,155,40,0.31)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -260,7 +260,6 @@ form{
|
|||
margin-bottom: 12px;
|
||||
border-radius:2px;
|
||||
background-color: #fff;
|
||||
padding: 20px 0;
|
||||
border:1px solid rgba(79, 108, 188, 0.21);
|
||||
&>li{
|
||||
font-size: 15px;
|
||||
|
|
|
|||
|
|
@ -222,4 +222,13 @@ export function deleteApplyInfo(data) {
|
|||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 判断课题是否有学生报名
|
||||
export async function findStudentTaskByTaskId(params) {
|
||||
return await fetch({
|
||||
url: '/api/applyInformation/findStudentTaskByTaskId',
|
||||
method: 'get',
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React , { useCallback, useEffect , useState } from 'react';
|
||||
import { Button, Form, Input, Select, Upload, message, Popconfirm } from 'antd';
|
||||
import {getUploadActionUrl} from 'educoder';
|
||||
import {applyGlcc, updateApplyGlcc} from '../api';
|
||||
import {applyGlcc, findStudentTaskByTaskId, updateApplyGlcc} from '../api';
|
||||
import TextArea from 'antd/lib/input/TextArea';
|
||||
import { main_site_url } from '../fetch';
|
||||
import TaskApply from './taskApply';
|
||||
|
|
@ -13,7 +13,7 @@ function EditRepoApplyInfo(props) {
|
|||
const {form, applyInfo, current_user, round, cateList, setReload, isAddRepo, setIsAddRepo, setIsEdit, setEditRepoCount} = props;
|
||||
const phonereg = /(^|\s*\+?0?0?86|\D)(1\d{2})[-\s]{0,3}(\d{4})[-\s]{0,3}(\d{4})(?=\D|$)/
|
||||
const emailreg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
|
||||
const {getFieldDecorator, validateFields, setFieldsValue, validateFieldsAndScroll } = form;
|
||||
const {getFieldDecorator, validateFields, setFieldsValue, validateFieldsAndScroll, getFieldValue } = form;
|
||||
const [imageUrl, setImageUrl] = useState(undefined);
|
||||
// 提交按钮loading效果
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
|
@ -27,7 +27,7 @@ function EditRepoApplyInfo(props) {
|
|||
const taskCountArr = []
|
||||
registrationTaskList.map((item, index)=>{
|
||||
taskCountArr.push(index+1);
|
||||
const{taskName, taskUrl, taskDifficulty, taskReward, tutorName, tutorMail, taskDesc, tutorPhone} = item;
|
||||
const{taskName, taskUrl, taskDifficulty, taskReward, tutorName, tutorMail, taskDesc, tutorPhone, id} = item;
|
||||
taskInfo[`taskName${index+1}`] = taskName;
|
||||
taskInfo[`taskUrl${index+1}`] = taskUrl;
|
||||
taskInfo[`taskDifficulty${index+1}`] = taskDifficulty;
|
||||
|
|
@ -36,6 +36,7 @@ function EditRepoApplyInfo(props) {
|
|||
taskInfo[`tutorMail${index+1}`] = tutorMail;
|
||||
taskInfo[`taskDesc${index+1}`] = taskDesc;
|
||||
taskInfo[`tutorPhone${index+1}`] = tutorPhone;
|
||||
taskInfo[`taskId${index+1}`] = id;
|
||||
})
|
||||
setTaskCount(taskCountArr);
|
||||
setTimeout(() => {
|
||||
|
|
@ -76,6 +77,7 @@ function EditRepoApplyInfo(props) {
|
|||
const registrationTaskList = []
|
||||
taskCount && taskCount.map(item=>{
|
||||
registrationTaskList.push({
|
||||
id: values[`taskId${item}`],
|
||||
taskName: values[`taskName${item}`],
|
||||
taskUrl: values[`taskUrl${item}`],
|
||||
taskDifficulty: values[`taskDifficulty${item}`],
|
||||
|
|
@ -157,14 +159,19 @@ function EditRepoApplyInfo(props) {
|
|||
|
||||
// 添加课题输入框
|
||||
function addTaskApplyForm(){
|
||||
setTaskCount(taskCount.concat([taskCount.length+1]));
|
||||
setTaskCount(taskCount.concat([taskCount[taskCount.length-1]+1]));
|
||||
}
|
||||
|
||||
// 删除课题报名
|
||||
function deleteTaskApply(index){
|
||||
const arr = [...taskCount];
|
||||
arr.splice(index-1, 1)
|
||||
setTaskCount(arr);
|
||||
async function deleteTaskApply(index){
|
||||
const delTaskId = getFieldValue(`taskId${index}`);
|
||||
const res = delTaskId ? await findStudentTaskByTaskId({ taskId: delTaskId }) : "newTask";
|
||||
if((res && res.data && res.data.length)){
|
||||
message.error("已有学生报名,不允许删除");
|
||||
}else{
|
||||
const arr = taskCount.filter(item=>item!== index);
|
||||
setTaskCount(arr);
|
||||
}
|
||||
}
|
||||
|
||||
// 取消编辑点击函数
|
||||
|
|
@ -267,7 +274,7 @@ function EditRepoApplyInfo(props) {
|
|||
<div className='taskApplyTitle font-16'>课题信息(<span>{index+1}</span>/5)</div>
|
||||
{index>0 && <Button type="link" onClick={()=>{deleteTaskApply(item)}}><i className='iconfont icon-shanchuicon3 mr5 font-15'></i>删除</Button>}
|
||||
</FlexAJ>
|
||||
<TaskApply helper={helper} taskKey={item} phonereg={phonereg} emailreg={emailreg}/>
|
||||
<TaskApply helper={helper} taskKey={item} phonereg={phonereg} emailreg={emailreg} getFieldDecorator={getFieldDecorator}/>
|
||||
</div>
|
||||
})}
|
||||
{taskCount && taskCount.length<5 && <div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import TextArea from 'antd/lib/input/TextArea';
|
|||
const Option = Select.Option;
|
||||
// 课题信息编辑
|
||||
function TaskApply(props) {
|
||||
const {helper, disabled, taskKey, phonereg, emailreg} = props;
|
||||
const {helper, disabled, taskKey, phonereg, emailreg, getFieldDecorator} = props;
|
||||
// 低、中、高
|
||||
const difficultyList = [
|
||||
{id: 1, name: "低"},
|
||||
|
|
@ -26,6 +26,9 @@ function TaskApply(props) {
|
|||
return(
|
||||
<div className="taskApplyForm">
|
||||
<div className="pt20 glcc_info_form">
|
||||
<Form.Item label="课题id" hidden>
|
||||
{getFieldDecorator(`taskId${taskKey}`, {})(<Input/>)}
|
||||
</Form.Item>
|
||||
{helper('课题名称',
|
||||
'',
|
||||
`taskName${taskKey}`,
|
||||
|
|
|
|||