项目列表-代码-根目录

dev_forge
caicai8 5 years ago
parent d4e7424deb
commit 94ddf7f11e

File diff suppressed because one or more lines are too long

@ -22,6 +22,11 @@ const ProjectIndex = Loadable({
loading: Loading,
})
const ProjectDetail = Loadable({
loader: () => import('./Main/Detail'),
loading: Loading,
})
class Index extends Component{
constructor(props){
super(props);
@ -48,6 +53,11 @@ class Index extends Component{
}
></Route>
<Route exact path="/projects/:projectId"
render={
(props) => (<ProjectDetail {...this.props} {...props} {...this.state} current_user={current_user}/>)
}
></Route>
<Route exact path="/projects"
render={
(props) => (<ProjectIndex {...this.props} {...props} {...this.state} current_user={current_user}/>)

@ -0,0 +1,130 @@
import React , { Component } from 'react';
import { Dropdown , Icon , Menu , Table } from 'antd';
import {Link} from 'react-router-dom';
// 点击按钮复制功能
function jsCopy(){
var e = document.getElementById("copy_rep_content");
e.select();
document.execCommand("Copy");
}
class CoderRootDirectory extends Component{
constructor(props){
super(props);
this.state={
address:"http"
}
}
changeAddress=(address)=>{
this.setState({
address
})
}
render(){
const menu = (
<Menu>
<Menu.Item key="0">
<a href="http://www.alipay.com/">1st menu item</a>
</Menu.Item>
<Menu.Item key="1">
<a href="http://www.taobao.com/">2nd menu item</a>
</Menu.Item>
</Menu>
);
const columns = [
{
dataIndex: 'name',
width:"33%",
render: text => <a>{text}</a>,
},
{
className: 'column-money',
width:"34%",
dataIndex: 'money',
},
{
dataIndex: 'address',
width:"33%",
className:"edu-txt-right color-grey-9"
},
];
const data = [
{
key: '1',
name: 'John Brown',
money: '¥300,000.00',
address: 'New York No. 1 Lake Park',
},
{
key: '2',
name: 'Jim Green',
money: '¥1,256,000.00',
address: 'London No. 1 Lake Park',
},
{
key: '3',
name: 'Joe Black',
money: '¥120,000.00',
address: 'Sidney No. 1 Lake Park',
},
];
const title = () =>{
return(
<div className="f-wrap-alignCenter">
<img src={``} alt=""/>
<span>蔡蔡</span>
<Link to={``} className="commitKey">asljfowfjoer</Link>
<span className="color-blue flex-1 hide-1">first commit</span>
<span>3小时前</span>
</div>
)
}
const { address } = this.state;
return(
<div className="main">
<p className="branch-wrapper">
<span><i className="iconfont icon-tijiaojilu font-18 mr3"></i></span>
<span><i className="iconfont icon-fenzhi font-18 mr3"></i></span>
</p>
<div className="f-wrap-between mt20">
<div className="branchDropdown">
<span className="color-grey-9 mr3"><i className="iconfont icon-fenzhi font-20 color-grey-6 mr3"></i>:</span>
<Dropdown overlay={menu} trigger={['click']} placement="bottomRight">
<a className="ant-dropdown-link">
master <Icon type="down" />
</a>
</Dropdown>
</div>
<div className="gitAddressClone">
<span className={address ==="http" ? "addressType active":"addressType"} onClick={()=>this.changeAddress("http")}>HTTP</span>
<span className={address ==="ssh" ? "addressType active":"addressType"} onClick={()=>this.changeAddress("ssh")}>SSH</span>
<input type="text" id="copy_rep_content" value={"git@testgitea.trustie.net:sylor/test11.git"}/>
<span><i className="iconfont icon-fuzhi"></i></span>
<span>
<Dropdown overlay={menu} trigger={['click']} placement="bottomRight">
<a className="ant-dropdown-link">
<Icon type="cloud-download" className="font-18 fl"/>
</a>
</Dropdown></span>
</div>
</div>
<Table
className="mt20 wrap-commit-table"
columns={columns}
dataSource={data}
showHeader={false}
size="small"
pagination={false}
title={() => title()}
/>
</div>
)
}
}
export default CoderRootDirectory;

@ -0,0 +1,67 @@
import React , { Component } from 'react';
import { Link , Route , Switch } from 'react-router-dom';
import '../css/index.css'
import './list.css';
import Loadable from 'react-loadable';
import Loading from '../../Loading';
const CoderRootDirectory = Loadable({
loader: () => import('./CoderRootDirectory'),
loading: Loading,
})
class Detail extends Component{
constructor(props){
super(props);
this.state={
currentKey:"coder"
}
}
// 切换菜单
ChangeMenu=(value)=>{
console.log(value);
}
render(){
const { currentKey } = this.state;
return(
<div>
<div className="detailHeader-wrapper">
<div className="normal f-wrap-between mb20">
<p className="font-18 color-blue df flex-1" style={{alignItems:"center"}}>kosasa胡 / <span className="hide-1 flex-1">test11111111111</span></p>
<span className="p-r-tags large">
<span><label>关注</label><span>11</span></span>
<span><label>点赞</label><span>12</span></span>
<span><label>Fork</label><span>11</span></span>
</span>
</div>
<div className="normal f-wrap-between">
<ul className="headerMenu-wrapper">
<li className={currentKey === "coder" ? "active" : ""}><Link to={''}>代码</Link></li>
<li className={currentKey === "orders" ? "active" : ""}><Link to={''}>工单</Link></li>
<li className={currentKey === "merge" ? "active" : ""}><Link to={''}>合并请求</Link></li>
<li className={currentKey === "edition" ? "active" : ""}><Link to={''}>版本发布</Link></li>
<li className={currentKey === "trends" ? "active" : ""}><Link to={''}>动态</Link></li>
</ul>
</div>
</div>
<Switch {...this.props}>
<Route exact path="/projects/:projectsType/coder"
render={
(props) => (<CoderRootDirectory {...this.props} {...props} {...this.state}/>)
}
></Route>
<Route exact path="/projects/:projectsType"
render={
(props) => (<CoderRootDirectory {...this.props} {...props} {...this.state}/>)
}
></Route>
</Switch>
</div>
)
}
}
export default Detail;

@ -1,7 +1,6 @@
import React , { Component } from 'react';
import { Menu , Input , Dropdown , Icon, Spin , Pagination } from 'antd';
import { Link } from 'react-router-dom';
import '../css/index.css'
import './list.css';
@ -21,15 +20,25 @@ class Index extends Component{
sort:undefined,
total:0,
isSpin:true,
project_type:undefined,
category_id:undefined,
typeList:undefined,
categoryList:undefined
}
}
componentDidMount=()=>{
const { page,limit, search , sort } = this.state;
this.getListData(page,limit, search , sort);
const { page,limit, search , sort ,project_type,category_id} = this.state;
this.getListData(page,limit, search , sort,project_type,category_id);
this.getType();
this.getCategory();
}
getListData=(page,limit, search , sort)=>{
// 获取列表
getListData=(page,limit, search , sort,project_type,category_id)=>{
const { current_user } = this.props;
const url = `/projects.json`;
axios.get(url,{params:{
@ -37,7 +46,9 @@ class Index extends Component{
page,
limit,
search,
sort_by:sort
sort_by:sort,
project_type,
category_id
}}).then((result)=>{
if(result){
this.setState({
@ -49,6 +60,70 @@ class Index extends Component{
}).catch((error)=>{})
}
// 获取类型
getType=()=>{
const url = `/projects/group_type_list.json`;
axios.get(url).then((result)=>{
if(result){
this.setState({
typeList:result.data && result.data.map((item,key)=>{
return(
<li onClick={()=>this.changeType(`${item.project_type}`)}>
<span>{item.name}</span>
<span>{item.projects_count}</span>
</li>
)
})
})
}
}).catch((error)=>{})
}
// 获取类型
getCategory=()=>{
const url = `/project_categories/group_list.json`;
axios.get(url).then((result)=>{
if(result && result.data){
this.setCategoryList(result.data);
}
}).catch((error)=>{})
}
setCategoryList=(list)=>{
this.setState({
categoryList:list.map((item,key)=>{
return(
<li onClick={()=>this.changeCategory(`${item.id}`)}>
<span>{item.name}</span>
<span>{item.projects_count}</span>
</li>
)
})
})
}
changeCategory=(id)=>{
this.setState({
category_id:id,
page:1
})
const { limit , sort, project_type } = this.state;
this.getListData(1,limit, undefined , sort, project_type ,id);
}
// 切换类型
changeType=(type)=>{
this.setState({
isSpin:true,
project_type:type,
search:undefined
})
const { page,limit, sort,category_id } = this.state;
this.getListData(page,limit, undefined , sort, type ,category_id);
}
// 排序
ChangeSoryBy=(e)=>{
this.setState({
@ -57,8 +132,8 @@ class Index extends Component{
search:undefined,
isSpin:true
})
const { limit } = this.state;
this.getListData(1 ,limit , undefined , e.key);
const { limit,project_type,category_id } = this.state;
this.getListData(1 ,limit , undefined , e.key,project_type,category_id);
}
// 搜索
@ -67,18 +142,24 @@ class Index extends Component{
this.setState({
page:1,
search:value,
isSpin:true
isSpin:true,
project_type:undefined
})
const { limit , sort , category_id } = this.state;
this.getListData(1 ,limit, value , sort , undefined,category_id);
}
changeSearchValue=(e)=>{
this.setState({
search:e.target.value
})
const { limit , sort } = this.state;
this.getListData(1 ,limit, value , sort);
}
// 翻页
ChangePage=(page)=>{
this.setState({
page
})
const { limit, search , sort } = this.state;
this.getListData(page,limit, search , sort);
const { limit, search , sort,project_type,category_id } = this.state;
this.getListData(page,limit, search , sort,project_type,category_id);
}
render(){
@ -91,51 +172,24 @@ class Index extends Component{
</Menu>
)
const { projectsList , isSpin , total , limit , page } = this.state;
const { projectsList , isSpin , total , search , limit , page , typeList , categoryList } = this.state;
const pagination = (
total && total > 0 &&
<Pagination showQuickJumper pageSize={limit} total={total} current={page} onChange={this.ChangePage}></Pagination>
total && total > 0 ?
<div className="edu-txt-center pt30 mb30">
<Pagination simple defaultCurrent={page} total={total} pageSize={limit} onChange={this.ChangePage}></Pagination>
</div>:""
)
return(
<div className="main ProjectListIndex">
<div className="list-left">
<ul className="list-l-Menu">
<li className="MenuTitle">项目类型</li>
<li>
<Link to={``}>
<span>开源托管项目</span>
<span>85</span>
</Link>
</li>
<li>
<Link to={``}>
<span>开源镜像项目</span>
<span>85</span>
</Link>
</li>
{ typeList }
</ul>
<ul className="list-l-Menu">
<li className="MenuTitle">项目类别</li>
<Menu
mode="inline"
>
<SubMenu
key="sub1"
title={
<span>
<span>Navigation One</span>
</span>
}
>
<Menu.ItemGroup key="g1">
<Menu.Item key="1">Option 1</Menu.Item>
<Menu.Item key="2">Option 2</Menu.Item>
<Menu.Item key="3">Option 3</Menu.Item>
<Menu.Item key="4">Option 4</Menu.Item>
</Menu.ItemGroup>
</SubMenu>
</Menu>
{ categoryList }
</ul>
</div>
<div className="list-right">
@ -147,6 +201,8 @@ class Index extends Component{
size="large"
onSearch={this.searchFun}
className="list-r-Search"
value={search}
onChange={this.changeSearchValue}
/>
<Dropdown overlay={menu} trigger={['click']} placement='bottomRight'>
<a className="ant-dropdown-link">
@ -155,6 +211,7 @@ class Index extends Component{
</Dropdown>
</div>
<ListItem {...this.props} {...this.state} projects={projectsList}></ListItem>
{ pagination }
</Spin>
</div>
</div>

@ -3,41 +3,6 @@ import { getImageUrl } from 'educoder';
import { Link } from 'react-router-dom';
import '../css/index.css'
import './list.css';
//把时间戳转换为几分钟或几小时前或几天前
function getDateDiff(dateTimeStamp){
var minute = 1000 * 60;
var hour = minute * 60;
var day = hour * 24;
var month = day * 30;
var now = new Date().getTime();
var diffValue = now - dateTimeStamp;
if(diffValue < 0){return;}
var monthC =diffValue/month;
var weekC =diffValue/(7*day);
var dayC =diffValue/day;
var hourC =diffValue/hour;
var minC =diffValue/minute;
var result = "";
if(monthC>=1){
result="" + parseInt(monthC) + "月前";
}
else if(weekC>=1){
result="" + parseInt(weekC) + "周前";
}
else if(dayC>=1){
result=""+ parseInt(dayC) +"天前";
}
else if(hourC>=1){
result=""+ parseInt(hourC) +"小时前";
}
else if(minC>=1){
result=""+ parseInt(minC) +"分钟前";
}else
result="刚刚";
return result;
}
class IndexItem extends Component{
@ -45,13 +10,13 @@ class IndexItem extends Component{
const { projects } = this.props;
const renderList = (
projects && projects.length >0 && projects.map((item,key)=>{
projects && projects.length >0 ? projects.map((item,key)=>{
return(
<div className="p-r-Item">
<img className="p-r-photo" alt="" src={getImageUrl(`images/${item.author && item.author.image_url}`)} ></img>
<div className="p-r-Infos">
<div className="p-r-name">
<Link to={""} className="hide-1 font-16 color-grey-3">{item.name}</Link>
<Link to={`/projects/${item.id}`} className="hide-1 font-16 color-grey-3" style={{whiteSpace:"wrap"}}>{item.name}</Link>
<span className="p-r-tags">
{ item.forked_count ? <span><label>Fork</label><span>{ item.forked_count}</span></span>:"" }
<span><label>Start</label><span>{ item.praises_count }</span></span>
@ -61,17 +26,17 @@ class IndexItem extends Component{
<div className="p-r-content">
<p className="break_word hide-2">{item.description}</p>
</div>
<div className="p-r-name mt8 color-grey-6">
<div className="p-r-about">
<span className="p-r-detail">
<span><label>浏览量</label>{item.visits}</span>
{ item.category && item.category.id && <span><label>项目类别</label>{item.category.name}</span>}
</span>
{item.last_update_time ? <span>{getDateDiff(item.last_update_time)}</span> : "" }
{item.last_update_time ? <span>更新于{item.time_ago}</span> : "" }
</div>
</div>
</div>
)
})
}):""
)
return(
<div className="project-list">

@ -1,3 +1,6 @@
body,#root{
background: #fff!important;
}
.ProjectListIndex{
display: flex;
align-items: flex-start;
@ -27,12 +30,11 @@
padding:0px 20px;
box-sizing: border-box;
color: #333;
}
.list-l-Menu>li a{
display: flex;
justify-content: space-between;
cursor: pointer;
}
.list-l-Menu li a span:last-child{
.list-l-Menu li span:last-child{
color: #999;
}
.list-l-Menu .MenuTitle{
@ -41,9 +43,9 @@
font-size: 16px;
}
.list-l-Menu > li:not(.MenuTitle):hover{
background-color: #5fb8ff;
background-color: #1890ff;
}
.list-l-Menu > li:not(.MenuTitle):hover a{
.list-l-Menu > li:not(.MenuTitle):hover span{
color: #fff;
}
/* 左侧menu */
@ -99,21 +101,31 @@
display: flex;
opacity: 1;
}
.p-r-tags.large > span{
height: 30px;
line-height: 30px;
font-size: 14px;
}
.p-r-tags > span{
margin-left: 15px;
border-radius: 4px;
border:1px solid #efefef;
background: #fafafa;
background: #e2f0fd;
height: 24px;
line-height: 24px;
display: block;
font-size: 12px;
display: flex;
}
.p-r-tags.large > span >label{
padding:0px 12px;
}
.p-r-tags > span >label{
padding:0px 8px;
}
.p-r-tags.large > span >span{
padding:0px 6px;
}
.p-r-tags > span >span{
display: block;
background: #fff;
@ -134,6 +146,120 @@
color: #999;
}
.p-r-about{
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
margin-top: 8px;
color: #666;
}
/* -----------详情------------ */
.detailHeader-wrapper{
background: #f7f7f7;
padding-top:20px;
border-bottom: 1px solid rgba(34,36,38,.15);
}
.headerMenu-wrapper{
background: #f7f7f7;
font-size: 16px;
display: flex;
flex-direction: row;
color: #999;
}
.headerMenu-wrapper li{
padding:6px 14px;
position: relative;
text-align: center
}
.headerMenu-wrapper li.active{
background: #fff;
margin-bottom: -1px;
border:1px solid rgba(34,36,38,.15);
border-bottom: none;
border-radius: 4px 4px 0px 0px;
}
/* 详情-代码 */
.branch-wrapper{
border:1px solid #eee;
border-radius: 4px;
display: flex;
padding:5px;
}
.branch-wrapper span{
display: flex;
align-items: center;
justify-content: center;
flex: 1;
text-align: center;
height: 30px;
line-height: 30px;
cursor: pointer;
font-size: 16px;
}
.branch-wrapper span.active{
background: #eee;
}
.branch-wrapper span:hover{
color: #4CACFF;
}
.branchDropdown{
border:1px solid #eee;
border-radius: 4px;
display: flex;
justify-content: center;
padding:0px 10px;
height: 35px;
line-height: 35px;
}
.gitAddressClone{
display: flex;
height: 32px;
align-items: center;
border-radius: 4px;
border:1px solid #eee;
background: #fff;
}
.gitAddressClone > span{
display: flex;
line-height: 30px;
height: 30px;
padding:0px 12px;
border-right: 1px solid #eee;
cursor: pointer;
align-items: center;
}
.gitAddressClone > span.addressType.active{
color: #4CACFF;
}
.gitAddressClone > span:last-child{
border-right: none;
}
.gitAddressClone > input{
border:none;
outline: none;
padding:0px 8px;
height: 30px;
line-height: 30px;
border-radius: 0px;
border-right: 1px solid #eee;
flex:1;
}
.wrap-commit-table .ant-table-small > .ant-table-content > .ant-table-body{
margin:0px;
}
.commitKey{
border:1px solid #dcdcdc;
background-color:#f4f4f4;
color: #666!important;
padding:0px 5px;
height: 28px;
line-height: 28px;
margin:0px 15px;
border-radius: 4px;
}
@media screen and (max-width: 750px){
.list-left,.list-right{
width: 100%;
@ -141,9 +267,28 @@
}
}
@media screen and (max-width: 400px){
.headerMenu-wrapper{
flex-direction: column;
width: 100%;
}
.headerMenu-wrapper li{
width: 100%;
}
.gitAddressClone{
width:100%;
}
.gitAddressClone > span{
padding:0px;
}
}
@media screen and (max-width: 370px){
.p-r-tags{
opacity: 0;
display: none;
}
.p-r-about{
flex-wrap: wrap;
}
}

@ -3,6 +3,10 @@
width: 1200px;
margin:20px auto;
}
.normal{
width: 1200px;
margin:0px auto;
}
/* 背景色 */
.back-white{
background: #fff;
@ -25,26 +29,48 @@
}
.hide-1{
display: inline-block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.hide-2 {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.df{display: flex}
.flex-1{flex: 1;width: 0}
.f-wrap-between{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.f-wrap-alignCenter{
display: flex;
flex-wrap: wrap;
align-items: center;
}
@media screen and (max-width: 1000px){
.main{
width: 750px;
margin:1rem auto;
}
.normal{
width: 750px;
}
}
@media screen and (max-width: 750px){
.main{
width: 95%;
margin:1rem auto;
}
.normal{
width: 100%;
}
}
Loading…
Cancel
Save