Merge pull request '修改头像、组织添加成员等功能' (#333) from caishi/forgeplus-react:gitlink_server into gitlink_server
This commit is contained in:
commit
7416d9bcb6
|
@ -3934,6 +3934,11 @@
|
|||
"warning": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"cropperjs": {
|
||||
"version": "1.5.12",
|
||||
"resolved": "https://registry.npmmirror.com/cropperjs/download/cropperjs-1.5.12.tgz",
|
||||
"integrity": "sha1-2cDbK/uMDXadUXOej5FrvEThD1A="
|
||||
},
|
||||
"cross-env": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
||||
|
@ -14227,6 +14232,14 @@
|
|||
"countup.js": "^2.0.8"
|
||||
}
|
||||
},
|
||||
"react-cropper": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/react-cropper/download/react-cropper-2.1.8.tgz?cache=0&sync_timestamp=1634379691101&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-cropper%2Fdownload%2Freact-cropper-2.1.8.tgz",
|
||||
"integrity": "sha1-vzWn3mV2n4rTV+iuiE55H+P+khI=",
|
||||
"requires": {
|
||||
"cropperjs": "^1.5.12"
|
||||
}
|
||||
},
|
||||
"react-datepicker": {
|
||||
"version": "2.14.1",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-2.14.1.tgz",
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
"react-content-loader": "^3.1.1",
|
||||
"react-cookies": "^0.1.1",
|
||||
"react-countup": "^6.1.0",
|
||||
"react-cropper": "^2.1.8",
|
||||
"react-datepicker": "^2.14.1",
|
||||
"react-dev-utils": "^9.2.0-next.80",
|
||||
"react-dom": "^16.13.1",
|
||||
|
|
|
@ -7,6 +7,8 @@ export const Banner = styled.div`{
|
|||
border-bottom:1px solid #eee;
|
||||
background-color:#fff;
|
||||
border-radius:5px 5px 0px 0px;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
}`
|
||||
export const AlignCenterBetween = styled.div`{
|
||||
display:flex;
|
||||
|
|
|
@ -42,8 +42,8 @@ class NewHeader extends Component {
|
|||
setevaluatinghides: false,
|
||||
occupation: 0,
|
||||
mydisplay: false,
|
||||
headtypesonClickbool: false,
|
||||
headtypess: "/",
|
||||
// headtypesonClickbool: false,
|
||||
// headtypess: "/",
|
||||
settings: null,
|
||||
visiblemyss: false,
|
||||
openSearch:false,
|
||||
|
@ -137,12 +137,12 @@ class NewHeader extends Component {
|
|||
AccountProfiletype: false
|
||||
})
|
||||
};
|
||||
headtypesonClick = (url, bool) => {
|
||||
this.setState({
|
||||
headtypess: url,
|
||||
headtypesonClickbool: bool,
|
||||
})
|
||||
}
|
||||
// headtypesonClick = (url, bool) => {
|
||||
// this.setState({
|
||||
// headtypess: url,
|
||||
// headtypesonClickbool: bool,
|
||||
// })
|
||||
// }
|
||||
//获取数据为空的时候
|
||||
gettablogourlnull = () => {
|
||||
this.setState({
|
||||
|
@ -295,12 +295,14 @@ class NewHeader extends Component {
|
|||
{...this.props}
|
||||
{...this.state}
|
||||
/> : ""}
|
||||
{
|
||||
publicNav &&
|
||||
<a href={'https://www.ccf.org.cn/'} className={"fl pr15"}>
|
||||
<img src={MainLogo} alt="ccf" />
|
||||
</a>
|
||||
}
|
||||
<div style={{width:"78px"}}>
|
||||
{
|
||||
publicNav &&
|
||||
<a href={'https://www.ccf.org.cn/'} className={"fl"}>
|
||||
<img src={MainLogo} alt="ccf" />
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
{
|
||||
settings && settings.nav_logo_url ?
|
||||
<a href={settings && settings.new_course.default_url} className={"fl mr50"}>
|
||||
|
@ -316,26 +318,26 @@ class NewHeader extends Component {
|
|||
{
|
||||
settings.navbar && settings.navbar.map((item, key) => {
|
||||
var new_link = item.link;
|
||||
var user_login = current_user && current_user.login;
|
||||
var is_hidden = item.hidden
|
||||
if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) {
|
||||
if (user_login) {
|
||||
if (new_link.indexOf("courses") > -1) {
|
||||
new_link = new_link.replace(/courses/g, user_login + "/courses")
|
||||
} else if (new_link.indexOf("contests") > -1) {
|
||||
new_link = new_link.replace(/contests/g, user_login + "/contests")
|
||||
}
|
||||
} else {
|
||||
is_hidden = true
|
||||
}
|
||||
}
|
||||
if (user_login && (new_link && new_link.indexOf("homes") > -1)) {
|
||||
new_link = new_link.replace(/homes/g, user_login + "/user_activities")
|
||||
}
|
||||
// var user_login = current_user && current_user.login;
|
||||
var is_hidden = item.hidden;
|
||||
// if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) {
|
||||
// if (user_login) {
|
||||
// if (new_link.indexOf("courses") > -1) {
|
||||
// new_link = new_link.replace(/courses/g, user_login + "/courses")
|
||||
// } else if (new_link.indexOf("contests") > -1) {
|
||||
// new_link = new_link.replace(/contests/g, user_login + "/contests")
|
||||
// }
|
||||
// } else {
|
||||
// is_hidden = true
|
||||
// }
|
||||
// }
|
||||
// if (user_login && (new_link && new_link.indexOf("homes") > -1)) {
|
||||
// new_link = new_link.replace(/homes/g, user_login + "/user_activities")
|
||||
// }
|
||||
var waiLian = (new_link && str.filter(item=>new_link.indexOf(item)>-1) );
|
||||
var wl = waiLian && waiLian.length>0;
|
||||
return (
|
||||
<li key={key} onClick={() => this.headtypesonClick(item.link, true)} className={`${this.matchpaths(new_link) === true ? 'pr active' : 'pr'}`} style={!is_hidden ? { display: 'flex' } : { display: 'none' }}>
|
||||
<li key={key} className={`${this.matchpaths(new_link) === true ? 'pr active' : 'pr'}`} style={{display:!is_hidden ? 'flex' : 'none'} }>
|
||||
<a href={new_link} target={wl ? "_self":"_blank"}>{item.name}</a>
|
||||
</li>
|
||||
)
|
||||
|
@ -350,7 +352,6 @@ class NewHeader extends Component {
|
|||
{
|
||||
current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)?
|
||||
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
|
||||
{/* <i className="iconfont icon-tianjiafangda ml30 mr15"></i> */}
|
||||
<img src={require(`./img/add.png`)} alt="" width="16px" className="mr15 ml30"/>
|
||||
</Dropdown>:""
|
||||
}
|
||||
|
|
|
@ -36,8 +36,9 @@ const Infos = styled.div`
|
|||
}
|
||||
& > .f-wrap-between {
|
||||
padding: 14px 20px 14px 16px;
|
||||
border-radius: 3px 3px 0px 0px;
|
||||
border-radius: 0px 0px 3px 3px;
|
||||
border: 1px solid #D0D0D0;
|
||||
border-top: none;
|
||||
.df{
|
||||
align-items: center;
|
||||
& .underline:hover{
|
||||
|
|
|
@ -321,7 +321,7 @@ class MilepostDetail extends Component {
|
|||
</div>
|
||||
{
|
||||
search_count > limit?
|
||||
<div className="mt30 pb30 edu-txt-center">
|
||||
<div className="pt30 pb30 edu-txt-center" style={{borderTop:"1px solid #eee"}}>
|
||||
<Pagination simple current={page} total={search_count} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>:""
|
||||
}
|
||||
|
|
|
@ -232,6 +232,9 @@
|
|||
border-bottom: 1px solid #eee;
|
||||
padding: 16px 0px 16px 20px;
|
||||
}
|
||||
.issueItem:last-child{
|
||||
border-bottom: none;
|
||||
}
|
||||
.issueNo {
|
||||
padding: 0px 5px;
|
||||
border-radius: 4px;
|
||||
|
|
|
@ -6,7 +6,7 @@ import moment from 'moment';
|
|||
|
||||
import NoneData from "../Nodata";
|
||||
import OrderItem from "./OrderItem";
|
||||
import CheckProfile from '../Component/ProfileModal/Profile';
|
||||
import cookie from 'react-cookies';
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
|
@ -76,6 +76,14 @@ class order extends Component {
|
|||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
// const selectParams = cookie.load('selectParams');
|
||||
// let states = selectParams.select_params;
|
||||
// this.setState({
|
||||
// ...states
|
||||
// },()=>{
|
||||
// this.getSelectList();
|
||||
// this.getIssueList('1');
|
||||
// })
|
||||
this.getSelectList();
|
||||
this.getIssueList('1');
|
||||
};
|
||||
|
@ -102,11 +110,11 @@ class order extends Component {
|
|||
|
||||
// 获取列表数据
|
||||
getIssueList = (status_type, begin, end) => {
|
||||
cookie.remove('selectParams');
|
||||
this.setState({
|
||||
isSpin: true
|
||||
})
|
||||
const { select_params } = this.state;
|
||||
console.log(select_params);
|
||||
const { projectsId, owner } = this.props.match.params;
|
||||
const url = `/${owner }/${projectsId}/issues.json`;
|
||||
axios
|
||||
|
@ -120,7 +128,9 @@ class order extends Component {
|
|||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
const issues = result.data.issues
|
||||
const issues = result.data.issues;
|
||||
// let inFifteenMinutes = new Date(new Date().getTime() + 24 * 3600 * 1000);
|
||||
// cookie.save('selectParams', {states:this.state},{ expires: inFifteenMinutes,path:`/${owner}/${projectsId}/issues` });
|
||||
this.setState({
|
||||
data: result.data,
|
||||
issues: issues,
|
||||
|
@ -193,11 +203,12 @@ class order extends Component {
|
|||
select_params,
|
||||
author_id,
|
||||
assigned_to_id
|
||||
},()=>{
|
||||
if (!toGet) {
|
||||
const { status_type } = this.state;
|
||||
this.getIssueList(status_type);
|
||||
}
|
||||
});
|
||||
if (!toGet) {
|
||||
const { status_type } = this.state;
|
||||
this.getIssueList(status_type);
|
||||
}
|
||||
};
|
||||
|
||||
renderMenu = (array, name, id, toGet) => {
|
||||
|
@ -852,7 +863,7 @@ class order extends Component {
|
|||
)}
|
||||
{
|
||||
search_count > select_params.limit ?
|
||||
<div className="mt30 mb30 edu-txt-center">
|
||||
<div className="pt30 mb30 edu-txt-center" style={{borderTop:"1px solid #eee"}}>
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={select_params.page}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import { withRouter } from "react-router";
|
||||
|
@ -11,6 +11,7 @@ import Loading from "../../Loading";
|
|||
import { Box , Gap , LongWidth } from '../Component/layout';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Avatar from '../users/Avatar/Index';
|
||||
|
||||
import './Index.scss';
|
||||
import { useEffect } from "react";
|
||||
|
@ -52,18 +53,38 @@ function Index(props){
|
|||
const { pathname } = props.location;
|
||||
const notice_url = mygetHelmetapi && mygetHelmetapi.common && mygetHelmetapi.common.notice;
|
||||
|
||||
const [ avatarVisible , setAvatarVisible ] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if(checkIfLogin() === false){
|
||||
props.history.push('/login');
|
||||
}
|
||||
},[])
|
||||
|
||||
|
||||
function onCancelAvatar(){
|
||||
setAvatarVisible(false);
|
||||
const { resetUserInfo } = props;
|
||||
resetUserInfo && resetUserInfo();
|
||||
}
|
||||
return(
|
||||
<div className="newMain clearfix whiteBack">
|
||||
{
|
||||
avatarVisible &&
|
||||
<Avatar
|
||||
onCancel={onCancelAvatar}
|
||||
avatarImg={getImageUrl(`/${current_user && current_user.image_url}`)}
|
||||
login={current_user && current_user.login}
|
||||
/>
|
||||
}
|
||||
<div className="boies">
|
||||
<Box>
|
||||
<div className="shortW">
|
||||
<div className="userDetail">
|
||||
<img src={getImageUrl(`/${current_user && current_user.image_url}`)} alt=""/>
|
||||
<div className="userHeadPhoto">
|
||||
<img src={getImageUrl(`/${current_user && current_user.image_url}`)} alt=""/>
|
||||
<span className="userUpdateBox"onClick={()=>setAvatarVisible(true)}>修改头像</span>
|
||||
</div>
|
||||
<span>{current_user && current_user.username}</span>
|
||||
</div>
|
||||
<ul className="securityUl ul-border-buttom">
|
||||
|
|
|
@ -193,4 +193,31 @@
|
|||
}
|
||||
.blue-Purple{
|
||||
color: #466AFF !important;
|
||||
}
|
||||
|
||||
.userHeadPhoto{
|
||||
width: 48px;
|
||||
position: relative;
|
||||
margin:0px auto;
|
||||
.userUpdateBox{
|
||||
font-size: 11px!important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top:0px;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
display: none!important;
|
||||
color: white!important;
|
||||
transition: 1s;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
}
|
||||
&:hover{
|
||||
.userUpdateBox{
|
||||
display: block!important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,10 +76,8 @@ function Index(props) {
|
|||
subTitle={`删除后未来事件将不会推送至此Webhook地址:${url}`}
|
||||
/>
|
||||
<Banner>
|
||||
<FlexAJ>
|
||||
<span>Webhooks(网络钩子)</span>
|
||||
<Button type="primary" size="large" onClick={addFunc}>添加Webhook</Button>
|
||||
</FlexAJ>
|
||||
<span>Webhooks(网络钩子)</span>
|
||||
<Button type="primary" size="large" onClick={addFunc}>添加Webhook</Button>
|
||||
</Banner>
|
||||
<div className="hookpanel">
|
||||
<p className="color-grey-3">每当特定事件(如push代码,合并请求被编辑)发生时,我们将通过webhook给您提供的远程URL发送post请求。您可以在我们的<a className="color-blue hoverLine" target="_blank" href="https://forum.trustie.net/forums/3408/detail">webhooks指南</a>中了解更多信息</p>
|
||||
|
|
|
@ -287,10 +287,10 @@ function New({ form , match , showNotification , history }) {
|
|||
<Checkbox value="pull_request_label">合并请求标签</Checkbox>
|
||||
<span>合并请求的标签被更新或清除</span>
|
||||
</span> */}
|
||||
<span>
|
||||
{/* <span>
|
||||
<Checkbox value="pull_request_review">合并请求审查</Checkbox>
|
||||
<span>合并请求被批准、拒绝或提出审查意见,审查人员的修改,审查线程已解决或未解决</span>
|
||||
</span>
|
||||
</span> */}
|
||||
{/* <span>
|
||||
<Checkbox value="pull_request_sync">合并请求被同步</Checkbox>
|
||||
<span>合并请求被同步</span>
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import React ,{ useState , useEffect } from 'react';
|
||||
import { Modal , Spin } from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
function AddMemberBox({className,orzId,history,OIdentifier}){
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
const [ list , setList ] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
if(visible && orzId){
|
||||
InitData();
|
||||
}
|
||||
},[orzId,visible])
|
||||
|
||||
function InitData(){
|
||||
const url = `/organizations/${orzId}/teams.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
is_full:true
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
setList(result.data.teams);
|
||||
setIsSpin(false);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function chooseGroup(id){
|
||||
history.push(`/${OIdentifier}/teams/${id}/setting/member`);
|
||||
}
|
||||
return(
|
||||
<div>
|
||||
<Modal
|
||||
visible={visible}
|
||||
width="600px"
|
||||
centered
|
||||
title="添加成员"
|
||||
onCancel={()=>setVisible(false)}
|
||||
footer={null}
|
||||
className="addMemberBody"
|
||||
>
|
||||
<div>
|
||||
<p className="font-16 pt40 pb20 edu-txt-center">请选择想要添加成员的组织团队</p>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="addForGroupList">
|
||||
{
|
||||
list && list.length > 0 ?
|
||||
<ul>
|
||||
{
|
||||
list.map((i,k)=>{
|
||||
return(
|
||||
<li onClick={()=>chooseGroup(i.id)}>{i.nickname}</li>
|
||||
)
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
:""
|
||||
}
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
</Modal>
|
||||
<a className={className} onClick={()=>setVisible(true)}>+ 添加成员</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default AddMemberBox;
|
|
@ -369,4 +369,48 @@
|
|||
}
|
||||
.hide{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.addMemberBtn{
|
||||
display: flex;
|
||||
height: 34px;
|
||||
line-height: 32px;
|
||||
padding:0px 14px;
|
||||
border-radius: 3px;
|
||||
border:1px solid #d0d0d0;
|
||||
font-size: 14px;
|
||||
&:hover{
|
||||
border-color: #466AFF;
|
||||
}
|
||||
}
|
||||
|
||||
.addMemberBody{
|
||||
.ant-modal-body{
|
||||
padding:0px;
|
||||
}
|
||||
.addForGroupList{
|
||||
padding:20px 40px;
|
||||
max-height: 315px;
|
||||
overflow-y: auto;
|
||||
ul{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 450px;
|
||||
margin:0px auto;
|
||||
}
|
||||
li{
|
||||
cursor: pointer;
|
||||
border:1px solid #d0d0d0;
|
||||
border-radius:4px;
|
||||
margin:0px 10px 15px 10px!important;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
width: 130px;
|
||||
text-align: center;
|
||||
&.active,&:hover{
|
||||
color: #fff;
|
||||
background-color: rgba(65, 84, 241, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import styled from 'styled-components';
|
|||
import { getImageUrl } from 'educoder';
|
||||
import axios from 'axios';
|
||||
import { Link } from 'react-router-dom';
|
||||
import AddMemberBox from '../Component/AddMemberBox';
|
||||
|
||||
const Img = styled.img`{
|
||||
width:30px;
|
||||
|
@ -14,7 +15,8 @@ const Img = styled.img`{
|
|||
border-radius:50%;
|
||||
}`
|
||||
const limit = 15;
|
||||
export default (({organizeDetail})=>{
|
||||
export default (({organizeDetail,history,match})=>{
|
||||
const OIdentifier = match.params.OIdentifier;
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ search , setSearch ] = useState(undefined);
|
||||
|
@ -116,6 +118,12 @@ export default (({organizeDetail})=>{
|
|||
<SearchUser getUser={getUser}/>
|
||||
<Blueline className="ml30">+ 添加用户</Blueline>
|
||||
</AlignCenter> */}
|
||||
<AddMemberBox
|
||||
className="addMemberBtn"
|
||||
orzId={organizeDetail && organizeDetail.id}
|
||||
history={history}
|
||||
OIdentifier={OIdentifier}
|
||||
/>
|
||||
</Title>
|
||||
<FlexAJ className="padding20-30">
|
||||
<div style={{width:"580px"}}>
|
||||
|
|
|
@ -4,9 +4,11 @@ import Cards from '../Component/MemberCards';
|
|||
import axios from 'axios';
|
||||
import Nodata from '../Nodata';
|
||||
import { Pagination , Spin } from 'antd';
|
||||
import AddMemberBox from './Component/AddMemberBox';
|
||||
|
||||
const limit = 15;
|
||||
function TeamMember({organizeDetail,current_user}){
|
||||
function TeamMember({organizeDetail,current_user,history,match}){
|
||||
const OIdentifier = match.params.OIdentifier;
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ isSpin , setIsSpin ] = useState(true);
|
||||
|
@ -34,7 +36,17 @@ function TeamMember({organizeDetail,current_user}){
|
|||
|
||||
return(
|
||||
<WhiteBack style={{marginBottom:"30px",border:'1px solid #eee'}}>
|
||||
<Banner>组织成员</Banner>
|
||||
<Banner>组织成员
|
||||
{
|
||||
organizeDetail && organizeDetail.is_admin &&
|
||||
<AddMemberBox
|
||||
className="addMemberBtn"
|
||||
orzId={organizeDetail && organizeDetail.id}
|
||||
history={history}
|
||||
OIdentifier={OIdentifier}
|
||||
/>
|
||||
}
|
||||
</Banner>
|
||||
<Spin spinning={isSpin}>
|
||||
<div style={{minHeight:"400px"}}>
|
||||
{
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
import React ,{useEffect, useRef, useState} from 'react';
|
||||
import './Index.scss';
|
||||
import { Modal , message } from 'antd';
|
||||
import Cropper from 'react-cropper';
|
||||
import 'cropperjs/dist/cropper.css';
|
||||
import axios from 'axios';
|
||||
|
||||
function Index({onCancel,avatarImg,login}){
|
||||
|
||||
const [ avatarPhoto , setAvatarPhoto ] = useState(avatarImg);
|
||||
|
||||
useEffect(()=>{
|
||||
if(avatarImg){
|
||||
setAvatarPhoto(avatarImg);
|
||||
}
|
||||
},[avatarImg])
|
||||
|
||||
const cropper = useRef();
|
||||
|
||||
const saveAvatar = async () => {
|
||||
const imgUrl = cropper.current.cropper.getCroppedCanvas().toDataURL("image/jpeg");
|
||||
if (!imgUrl) {
|
||||
message.info('请先上传图片');
|
||||
}
|
||||
const url = `/users/${login}/update_image.json`;
|
||||
axios.put(url,{
|
||||
image:imgUrl
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
message.success("头像修改成功!");
|
||||
onCancel(true);
|
||||
}
|
||||
}).catch(error=>{})
|
||||
}
|
||||
|
||||
function onChange(e){
|
||||
|
||||
let files;
|
||||
if (e.dataTransfer) {
|
||||
files = e.dataTransfer.files;
|
||||
} else if (e.target) {
|
||||
files = e.target.files;
|
||||
}
|
||||
|
||||
if (!files || (files && files.length===0)) {
|
||||
return;
|
||||
}
|
||||
const file = files[0];
|
||||
if (!/^image\/\w+/.test(file.type)) {
|
||||
message.info('请选择一个图片格式的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
if (file.size > 2 * 1024 * 1024) {
|
||||
message.info('仅支持文件大小小于2M的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
setAvatarPhoto(reader.result);
|
||||
};
|
||||
reader.readAsDataURL(files[0]);
|
||||
}
|
||||
|
||||
return(
|
||||
<Modal
|
||||
visible={true}
|
||||
width="638px"
|
||||
footer={null}
|
||||
centered
|
||||
title="修改头像"
|
||||
onCancel={()=>onCancel(false)}
|
||||
className="avatarBox"
|
||||
>
|
||||
<div className="avatarDiv">
|
||||
<div>
|
||||
<Cropper
|
||||
style={{ height: 320, width: 320 }}
|
||||
src={avatarPhoto}
|
||||
guides={false}
|
||||
preview="#updateAvatarImg"
|
||||
ref={cropper}
|
||||
aspectRatio={1}
|
||||
/>
|
||||
{/* <span className={"tips"}>仅支持JPG、GIF、PNG,且文件小于2M</span> */}
|
||||
</div>
|
||||
<div className="previewBox">
|
||||
<div className={"previewImg"} id="updateAvatarImg"></div>
|
||||
<div className="uploadBtn">
|
||||
<label className={"uploadButton"} id="uploadBtn" htmlFor="inputImage">
|
||||
<input type="file" className="sr-only" id="inputImage" name="file" accept="image/*" style={{ display: "none" }} onChange={onChange}></input>
|
||||
点击上传
|
||||
</label>
|
||||
<a onClick={saveAvatar}>保存头像</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default Index;
|
|
@ -0,0 +1,66 @@
|
|||
.avatarBox{
|
||||
position: relative;
|
||||
.ant-modal-header{
|
||||
background-color: rgba(242, 242, 255, 1);
|
||||
.ant-modal-title{
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-modal-body{
|
||||
position: relative;
|
||||
}
|
||||
.avatarDiv{
|
||||
display: flex;
|
||||
.previewBox{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-left: 30px;
|
||||
.uploadBtn{
|
||||
margin-bottom: 30px;
|
||||
display: flex;
|
||||
a,label{
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
height: 32px;
|
||||
line-height: 30px;
|
||||
margin:0px 10px;
|
||||
width: 100px;
|
||||
border:1px solid rgba(208, 208, 208, 1);
|
||||
background-color: white;
|
||||
border-radius:4px;
|
||||
text-align: center;
|
||||
color:#666666;
|
||||
span{
|
||||
display: block;
|
||||
.ant-upload.ant-upload-select {
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
}
|
||||
.ant-upload-list{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
a{
|
||||
background-color: rgba(65, 84, 241, 1);
|
||||
color: white;
|
||||
border-color: rgba(65, 84, 241, 1);
|
||||
&:hover{
|
||||
color: white!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.previewImg{
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
width: 100px!important;
|
||||
height: 100px!important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -137,7 +137,6 @@
|
|||
.infoBox span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.headimg {
|
||||
position: relative;
|
||||
display: block;
|
||||
|
@ -150,8 +149,7 @@
|
|||
.headimg span {
|
||||
position: absolute;
|
||||
bottom: -6px;
|
||||
right: 0px;
|
||||
left: 65px;
|
||||
right: -16px;
|
||||
}
|
||||
.headimg span i {
|
||||
font-size: 25px !important;
|
||||
|
|
|
@ -133,6 +133,32 @@ $flex:flex;
|
|||
margin-left:10px ;
|
||||
}
|
||||
}
|
||||
|
||||
.headimg-div{
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
margin:0px auto;
|
||||
position: relative;
|
||||
.updateAvatar{
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
content: "";
|
||||
left: 0px;
|
||||
top:0px;
|
||||
background-color: rgba(0,0,0,0.2);
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
transition: 1s;
|
||||
}
|
||||
&:hover .updateAvatar{
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
.headimg{
|
||||
position: relative;
|
||||
display: block;
|
||||
|
@ -145,7 +171,7 @@ $flex:flex;
|
|||
position: absolute;
|
||||
bottom: -6px;
|
||||
right: 0px;
|
||||
left: 65px;
|
||||
z-index: 11;
|
||||
i{
|
||||
font-size: 25px!important;
|
||||
border-radius: 50%;
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Button, Spin , Menu } from "antd";
|
||||
import { Spin , Menu } from "antd";
|
||||
import FocusButton from "../UsersList/focus_button";
|
||||
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import Avatar from './Avatar/Index';
|
||||
|
||||
import "./new_user.css";
|
||||
import "../css/index.scss";
|
||||
|
@ -14,10 +15,10 @@ import './Index.scss';
|
|||
import Loadable from "react-loadable";
|
||||
import Loading from "../../Loading";
|
||||
|
||||
const UpdateInfo = Loadable({
|
||||
loader: () => import("./Material/Index"),
|
||||
loading: Loading,
|
||||
});
|
||||
// const UpdateInfo = Loadable({
|
||||
// loader: () => import("./Material/Index"),
|
||||
// loading: Loading,
|
||||
// });
|
||||
const InfosDevOps = Loadable({
|
||||
loader: () => import("./devOpsCI"),
|
||||
loading: Loading,
|
||||
|
@ -66,7 +67,8 @@ class Infos extends Component {
|
|||
project_type: undefined,
|
||||
route_type: undefined,
|
||||
undo_events:0,
|
||||
menuKey:"0"
|
||||
menuKey:"0",
|
||||
avatarVisible:false
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -193,29 +195,59 @@ class Infos extends Component {
|
|||
})
|
||||
}
|
||||
|
||||
onCancelAvatar=(reset)=>{
|
||||
this.setState({
|
||||
avatarVisible:false
|
||||
})
|
||||
if(reset){
|
||||
const { menuKey } = this.state;
|
||||
if(menuKey === "2" || menuKey === "3"){
|
||||
window.location.reload();
|
||||
}else{
|
||||
this.fetchUser();
|
||||
const { resetUserInfo } = this.props;
|
||||
resetUserInfo && resetUserInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { current_user } = this.props;
|
||||
const { username } = this.props.match.params;
|
||||
const { user, isSpin, route_type , undo_events , menuKey } = this.state;
|
||||
const { user, isSpin, route_type , undo_events , menuKey , avatarVisible } = this.state;
|
||||
return (
|
||||
<div className="newMain clearfix">
|
||||
{
|
||||
avatarVisible &&
|
||||
<Avatar
|
||||
onCancel={this.onCancelAvatar}
|
||||
avatarImg={getImageUrl(`/${user && user.image_url}`)}
|
||||
login={current_user && current_user.login}
|
||||
/>
|
||||
}
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="new-content-flex">
|
||||
<div className="list-left" style={{border:"none"}}>
|
||||
<div className="bgcF">
|
||||
<div className="list-l-Menu text-center" style={{padding:"20px 25px"}}>
|
||||
<span className="headimg">
|
||||
<img src={getImageUrl(`/${user && user.image_url}`)} alt=""/>
|
||||
<span>
|
||||
{
|
||||
user && user.gender===1?
|
||||
<i className="iconfont icon-nan1"></i>
|
||||
:
|
||||
<i className="iconfont icon-nv1"></i>
|
||||
}
|
||||
<div className="headimg-div">
|
||||
<span className="headimg">
|
||||
<img src={getImageUrl(`/${user && user.image_url}`)} alt=""/>
|
||||
<span>
|
||||
{
|
||||
user && user.gender===1?
|
||||
<i className="iconfont icon-nan1"></i>
|
||||
:
|
||||
<i className="iconfont icon-nv1"></i>
|
||||
}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
{
|
||||
current_user && current_user.login && current_user.login === username ?
|
||||
<span className="updateAvatar" onClick={()=>{this.setState({avatarVisible:true})}}>修改头像</span>
|
||||
:""
|
||||
}
|
||||
</div>
|
||||
<div className="text-center mt15 font-24 task-hide" title={user && user.username}>
|
||||
{user && user.username}
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue