forked from Gitlink/forgeplus-react
数据集
This commit is contained in:
parent
0f3d4532e5
commit
4bd0d67f87
|
@ -3373,8 +3373,8 @@ a.edu-greyline-btn:hover {
|
|||
|
||||
.defalutSubmitbtn {
|
||||
display: block;
|
||||
border: 1px solid #4CACFF;
|
||||
background-color: #4CACFF;
|
||||
border: 1px solid #466aff;
|
||||
background-color: #466aff;
|
||||
color: #fff !important;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
|
@ -3382,7 +3382,6 @@ a.edu-greyline-btn:hover {
|
|||
border-radius: 2px;
|
||||
width: 130px;
|
||||
height: 40px;
|
||||
background: rgba(76, 172, 255, 1);
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
font-family: MicrosoftYaHei;
|
||||
|
|
|
@ -1,63 +1,130 @@
|
|||
import React, { useState , useEffect } from 'react';
|
||||
import { Button , Table } from 'antd';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import NewModal from './component/new';
|
||||
import { Link } from 'react-router-dom';
|
||||
import "./index.scss";
|
||||
import axios from 'axios';
|
||||
|
||||
function Index(){
|
||||
function Index(props){
|
||||
const { project , match } =props;
|
||||
const { owner ,projectsId } = match && match.params;
|
||||
const [ dataSource , setDataSource ] = useState([]);
|
||||
const [ empty , setEmpty ] = useState(project && (!project.has_dataset));
|
||||
const [ total , setTotal ] = useState(0);
|
||||
const [ page , setPage ] = useState(1);
|
||||
const [ visible , setVisible ] = useState(false);
|
||||
const [ detail , setDetail ] = useState({});
|
||||
const pageSize = 20;
|
||||
useEffect(()=>{
|
||||
if(!empty){
|
||||
Init();
|
||||
}
|
||||
},[empty,page])
|
||||
|
||||
function Init(){
|
||||
const url = `/v1/${owner}/${projectsId}/dataset`;
|
||||
|
||||
axios.get(url,{
|
||||
params:{
|
||||
page,limit:pageSize
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
setDetail(result.data);
|
||||
setDataSource(result.data && result.data.attachments);
|
||||
setTotal(result.data.attachment_total_count);
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
||||
const columns=[
|
||||
{
|
||||
title:"文件名称",
|
||||
dataIndex:"name",
|
||||
dataIndex:"title",
|
||||
key:1,
|
||||
ellipsis:true,
|
||||
width:"25%"
|
||||
},
|
||||
{
|
||||
title:"描述",
|
||||
dataIndex:"desc",
|
||||
dataIndex:"description",
|
||||
key:2,
|
||||
ellipsis:true,
|
||||
width:"25%"
|
||||
width:"30%"
|
||||
},
|
||||
{
|
||||
title:"创建者",
|
||||
dataIndex:"creator",
|
||||
key:3,
|
||||
width:"10%"
|
||||
width:"10%",
|
||||
render:(value,item)=>{
|
||||
return <img src={getImageUrl(`/${value.image_url}`)} alt="" style={{borderRadius:"50%"}} width="32px" height="32px" />
|
||||
}
|
||||
},
|
||||
{
|
||||
title:"上传时间",
|
||||
dataIndex:"uploadTime",
|
||||
dataIndex:"created_on",
|
||||
key:4,
|
||||
width:"15%"
|
||||
},
|
||||
{
|
||||
title:"大小",
|
||||
dataIndex:"size",
|
||||
dataIndex:"filesize",
|
||||
key:5,
|
||||
width:"10%"
|
||||
},
|
||||
{
|
||||
title:"操作",
|
||||
dataIndex:"operate",
|
||||
dataIndex:"url",
|
||||
key:6,
|
||||
width:"10%",
|
||||
render:(value,item)=>{
|
||||
return <a href={value} className="color-blue">下载</a>
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
// 添加成功
|
||||
function addFunc(){
|
||||
setEmpty(false);
|
||||
setVisible(false);
|
||||
detail && detail.id && Init();
|
||||
}
|
||||
return(
|
||||
<div className={`dataset`}>
|
||||
<NewModal visible={visible} detail={detail} owner={owner} repo={projectsId} onCancel={()=>setVisible(false)} onOk={addFunc}/>
|
||||
<div className={`mnistData`}>
|
||||
<div>
|
||||
<p className="font-17">MNISTData_mindspore</p>
|
||||
<p>MNISTData数据集是由10类28*28的灰度图片组成,训练数据集包含60000张图片,测试数据集包含10000张图片。</p>
|
||||
</div>
|
||||
<div>
|
||||
<Button type="primary" ghost><i className="iconfont icon-a-bianji12 color-blue mr5 font-12"></i>编辑</Button>
|
||||
<Button type="primary" className="ml20"><i className="iconfont icon-a-shangchuan2x color-white mr5 font-13"></i>上传文件</Button>
|
||||
</div>
|
||||
{empty ?
|
||||
<span className="font-16">数据集</span>
|
||||
:
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<p className="font-16 weight500">{detail.title}</p>
|
||||
<p>{detail.description}</p>
|
||||
</div>
|
||||
<div className="df">
|
||||
<Button type="primary" ghost onClick={()=>{setVisible(true)}}><i className="iconfont icon-a-bianji12 color-blue mr5 font-12"></i>编辑</Button>
|
||||
<Link className="ml20 operateButton" to={`/${owner}/${projectsId}/dataset/upload`}><i className="iconfont icon-a-shangchuan2x color-white mr5 font-13"></i>上传文件</Link>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
}
|
||||
</div>
|
||||
<Table
|
||||
columns={columns}
|
||||
/>
|
||||
{
|
||||
empty?
|
||||
<div className={"emtpyData"}>
|
||||
<img src={require('./image/empty.png')} alt="" width="68px"/>
|
||||
<span className="font-22 weight400 color-grey-3">暂无数据集</span>
|
||||
<p className="mt25 font-15 color-grey-6 weight400">我们非常欢迎您创建并分享您的数据集,以便与其他用户共同促进开源社区的发展</p>
|
||||
<Button type="primary" className="mt15" onClick={()=>{setVisible(true)}}>创建数据集</Button>
|
||||
</div>
|
||||
:
|
||||
<Table
|
||||
className={`datasetTable`}
|
||||
columns={columns}
|
||||
dataSource={dataSource}
|
||||
pagination={{total,pageSize,current:page,hideOnSinglePage:true,onChange:(p)=>setPage(p)}}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Modal ,Form ,Input , AutoComplete , Button , Select } from 'antd';
|
||||
import '../index.scss';
|
||||
import axios from 'axios';
|
||||
|
||||
const { TextArea } = Input;
|
||||
const Option = Select.Option;
|
||||
|
||||
function New(props){
|
||||
const { form , visible , onCancel , onOk , owner , repo , detail } = props;
|
||||
const [ licenseId , setLicenseId ] =useState(undefined);
|
||||
const [ licensesList , setLicensesList] =useState([]);
|
||||
const [ filterLicensesList , setFilterLicensesList ] =useState([]);
|
||||
|
||||
const { getFieldDecorator , setFieldsValue } = form;
|
||||
|
||||
useEffect(()=>{
|
||||
if(detail && detail.id){
|
||||
setFieldsValue({...detail,license_id:detail.license_name});
|
||||
setLicenseId(detail.license_id);
|
||||
}
|
||||
},[detail])
|
||||
|
||||
useEffect(()=>{
|
||||
getLicenses();
|
||||
},[])
|
||||
|
||||
function getLicenses(){
|
||||
const url = `/licenses.json`
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
setLicensesList(result.data.licenses);
|
||||
setFilterLicensesList(result.data.licenses);
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
||||
|
||||
function submit(){
|
||||
form.validateFields((err, values) => {
|
||||
if(!err){
|
||||
const url = `/v1/${owner}/${repo}/dataset.json`;
|
||||
if(detail && detail.id){
|
||||
axios.put(url,{
|
||||
...values,license_id:licenseId
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
onOk && onOk();
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}else{
|
||||
axios.post(url,{
|
||||
...values,license_id:licenseId
|
||||
}).then((result) => {
|
||||
if (result) {
|
||||
onOk && onOk();
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function ChangePlatform(value){
|
||||
let _data = [];
|
||||
if (licensesList.length>0) {
|
||||
_data = licensesList.filter(item => item.name.toLowerCase().indexOf(value.toLowerCase()) > -1);
|
||||
}
|
||||
setFilterLicensesList(_data);
|
||||
}
|
||||
|
||||
function checkId(rule, value, callback, list, title){
|
||||
let filter = list.filter(item => item.name === value);
|
||||
if(!value){
|
||||
callback();
|
||||
}
|
||||
if (filter && filter.length > 0) {
|
||||
callback();
|
||||
} else {
|
||||
callback('请在下拉选项中选择正确的' + title + "!");
|
||||
}
|
||||
callback();
|
||||
}
|
||||
return(
|
||||
<Modal
|
||||
title={`${detail && detail.id?"编辑":"新建"}数据集`}
|
||||
width="648px"
|
||||
visible={visible}
|
||||
footer={null}
|
||||
className="newBoxForm"
|
||||
centered={true}
|
||||
closable={true}
|
||||
onCancel={onCancel}
|
||||
>
|
||||
<Form>
|
||||
<Form.Item label="名称">
|
||||
{getFieldDecorator('title', {
|
||||
rules: [
|
||||
{
|
||||
required:true,
|
||||
message:"请输入数据集名称"
|
||||
}
|
||||
],
|
||||
})(
|
||||
<Input placeholder="请输入数据集名称" />,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="开源许可证">
|
||||
{getFieldDecorator('license_id', {
|
||||
rules: [{
|
||||
validator: (rule, value, callback) => checkId(rule, value, callback, licensesList, '开源许可证')
|
||||
}],
|
||||
})(
|
||||
<AutoComplete
|
||||
placeholder="请选择开源许可证"
|
||||
onChange={ChangePlatform}
|
||||
className="plateAutoComplete"
|
||||
onSelect={(e,e1)=>{e1.props && setLicenseId(e1.props.id)}}
|
||||
>
|
||||
{
|
||||
filterLicensesList && filterLicensesList.map((item) => (
|
||||
<Option key={item.id} value={item.name} id={item.id}>
|
||||
{item.name}
|
||||
</Option>
|
||||
))
|
||||
}
|
||||
</AutoComplete>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="描述">
|
||||
{getFieldDecorator('description', {
|
||||
rules: [
|
||||
{
|
||||
required:true,
|
||||
message:"请输入描述内容"
|
||||
}
|
||||
]})(
|
||||
<TextArea placeholder="请输入描述内容" autosize={{ minRows: 5, maxRows: 5 }} showCount/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="研究论文">
|
||||
{getFieldDecorator('paper_content', {rules:[]})(
|
||||
<TextArea placeholder="请输入研究论文" autosize={{ minRows: 5, maxRows: 5 }} showCount/>,
|
||||
)}
|
||||
</Form.Item>
|
||||
<div className="center">
|
||||
<Button style={{width:"95px"}} onClick={onCancel}>取消</Button>
|
||||
<Button type="primary" className="ml20" style={{width:"95px"}} onClick={submit}>确定</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default Form.create({ name: 'New' })(New);;
|
|
@ -0,0 +1,111 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Upload ,Form ,Input , Button } from 'antd';
|
||||
import '../index.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
|
||||
const { Dragger } = Upload;
|
||||
const { TextArea } = Input;
|
||||
|
||||
function UploadModal(props){
|
||||
const { match , form ,history } =props;
|
||||
const { owner ,projectsId } = match && match.params;
|
||||
const [fileList, setFileList] = useState([]);
|
||||
const [ detail , setDetail ] = useState({});
|
||||
const [ loading , setLoading ] = useState(false);
|
||||
const { getFieldDecorator } = form;
|
||||
|
||||
useEffect(()=>{
|
||||
Init();
|
||||
},[])
|
||||
function Init(){
|
||||
const url = `/v1/${owner}/${projectsId}/dataset`;
|
||||
|
||||
axios.get(url).then((result) => {
|
||||
if (result) {
|
||||
setDetail(result.data);
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
|
||||
function submit(){
|
||||
form.validateFields((err, values) => {
|
||||
if(!err){
|
||||
const url = `/attachments.json`;
|
||||
const { description ,files } = values;
|
||||
setLoading(true);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("container_type","ProjectDataset");
|
||||
formData.append("description",description);
|
||||
formData.append("container_id",detail && detail.id);
|
||||
formData.append("file",files.file);
|
||||
|
||||
const config = {
|
||||
headers: { "Content-Type": "multipart/form-data" }
|
||||
};
|
||||
axios.post(url,formData,config).then((result) => {
|
||||
if (result) {
|
||||
setLoading(false);
|
||||
history.push(`/${owner}/${projectsId}/dataset`);
|
||||
}
|
||||
}).catch((error) => { })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const upload= {
|
||||
name: 'file',
|
||||
multiple: false,
|
||||
maxCount:1,
|
||||
beforeUpload: file => {
|
||||
setFileList([file]);
|
||||
return false;
|
||||
},
|
||||
onRemove: file => {
|
||||
const index = fileList.indexOf(file);
|
||||
const newFileList = fileList.slice();
|
||||
newFileList.splice(index, 1);
|
||||
setFileList(newFileList);
|
||||
},
|
||||
fileList,
|
||||
};
|
||||
return(
|
||||
<div className={`dataset`}>
|
||||
<p className="font-18 fileTitle">上传数据集文件</p>
|
||||
<Form className="newBoxForm">
|
||||
<Form.Item label="文件描述">
|
||||
{getFieldDecorator('description', {
|
||||
rules: [
|
||||
{
|
||||
required:true,
|
||||
message:"请输入文件描述"
|
||||
}
|
||||
],
|
||||
})(
|
||||
<TextArea autosize={{minRows:5,maxRows:5}} placeholder="描述字数不超过255个字符" maxLength={255} />,
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label="数据上传">
|
||||
{getFieldDecorator('files', {
|
||||
rules: [
|
||||
{
|
||||
required:true,
|
||||
message:"请上传文件"
|
||||
}
|
||||
],
|
||||
})(
|
||||
<Dragger {...upload} className={"drag"}>
|
||||
<p className="ant-upload-hint font-15">点击添加文件或直接拖拽文件到此处</p>
|
||||
</Dragger>,
|
||||
)}
|
||||
</Form.Item>
|
||||
<div>
|
||||
<Link className="btn-83" to={`/${owner}/${projectsId}/dataset`}>取消</Link>
|
||||
<Button loading={loading} type="primary" className="ml5" style={{width:"95px"}} onClick={submit}>确定</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create({ name: 'UploadModal' })(UploadModal);;
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -20,4 +20,43 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.datasetTable{
|
||||
.ant-table-thead > tr > th{
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
.emtpyData{
|
||||
background: #FAFCFF;
|
||||
border-radius: 4px 4px 0px 0px;
|
||||
min-height: 356px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
}
|
||||
.newBoxForm{
|
||||
.ant-row.ant-form-item{
|
||||
margin-bottom: 20px!important;
|
||||
position: relative;
|
||||
}
|
||||
.ant-col.ant-form-item-label{
|
||||
line-height: unset;
|
||||
font-weight: 400;
|
||||
font-size: 15px;
|
||||
color: #4C5B76;
|
||||
}
|
||||
.ant-form-explain{
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
.fileTitle{
|
||||
line-height: 25px;
|
||||
padding-bottom: 22px;
|
||||
margin-bottom: 15px!important;
|
||||
border-bottom:1px solid rgba(167,178,194,0.44);
|
||||
}
|
||||
.drag{
|
||||
height: 110px!important;
|
||||
}
|
|
@ -103,6 +103,10 @@ const DataSetIndex = Loadable({
|
|||
loader: () => import('../Dataset/Index'),
|
||||
loading: Loading,
|
||||
})
|
||||
const DataSetUpload = Loadable({
|
||||
loader: () => import('../Dataset/component/uploadModal'),
|
||||
loading: Loading,
|
||||
})
|
||||
const DevAbout = Loadable({
|
||||
loader: () => import('../About/Index'),
|
||||
loading: Loading,
|
||||
|
@ -156,6 +160,8 @@ function checkPathname(projectsId, owner, pathname) {
|
|||
name = "activity"
|
||||
} else if (url.indexOf("/settings") > -1) {
|
||||
name = "settings"
|
||||
} else if (url.indexOf("/dataset") > -1) {
|
||||
name = "dataset"
|
||||
} else if (url.indexOf(`/devops`) > -1) {
|
||||
name = "devops"
|
||||
} else if (url.indexOf(`/source`) > -1) {
|
||||
|
@ -704,10 +710,16 @@ class Detail extends Component {
|
|||
() => (<DevAbout {...this.props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
|
||||
{/* 数据集 */}
|
||||
<Route path="/:owner/:projectsId/dataset/upload"
|
||||
render={
|
||||
(props) => (<DataSetUpload {...this.props} {...props} {...this.state} {...common} />)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/:owner/:projectsId/dataset"
|
||||
render={
|
||||
() => (<DataSetIndex {...this.props} {...this.state} {...common} />)
|
||||
(props) => (<DataSetIndex {...this.props} {...props} {...this.state} {...common}/>)
|
||||
}
|
||||
></Route>
|
||||
{/* wiki新增文件 */}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 898 B |
|
@ -3,6 +3,7 @@ import { Skeleton , Tooltip} from 'antd';
|
|||
import { Link } from 'react-router-dom';
|
||||
import { numFormat } from 'educoder';
|
||||
import QuitBox from './quit';
|
||||
import datasetImg from '../img/dataset.jpg';
|
||||
import axios from 'axios';
|
||||
|
||||
function DetailBanner({ history,list , owner , projectsId ,showNotification , url , pathname , state , urlFlag , projectDetail , platform ,open_devops ,current_user, showNpsModal }){
|
||||
|
@ -104,6 +105,16 @@ function DetailBanner({ history,list , owner , projectsId ,showNotification , ur
|
|||
</li>
|
||||
:""
|
||||
}
|
||||
{
|
||||
item.menu_name === "dataset" ?
|
||||
<li className={pathname==="dataset" ? "active" : ""}>
|
||||
<Link className='newTab' to={{ pathname: `/${owner}/${projectsId}/dataset`, state:{...state,open_devops} }}>
|
||||
<img src={datasetImg} height={15} alt="" className="mr5 mt5"/>数据集
|
||||
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
|
||||
</Link>
|
||||
</li>
|
||||
:""
|
||||
}
|
||||
{/* {
|
||||
item.menu_name === "resources" &&
|
||||
<li className={pathname==="source" ? "active" : ""}>
|
||||
|
@ -168,12 +179,7 @@ function DetailBanner({ history,list , owner , projectsId ,showNotification , ur
|
|||
)
|
||||
})
|
||||
}
|
||||
{/* <li className={pathname==="dataset" ? "active" : ""}>
|
||||
<Link className='newTab' to={{ pathname: `/${owner}/${projectsId}/dataset`, state:{...state,open_devops} }}>
|
||||
<i className="iconfont icon-gongzuoliuicon font-13 mr5 color-grey-3"></i>数据集
|
||||
{projectDetail && projectDetail.ops_count ? <span>{projectDetail.ops_count}</span> : ""}
|
||||
</Link>
|
||||
</li> */}
|
||||
|
||||
</ul>
|
||||
:
|
||||
<Skeleton paragraph={false} active={true}/>
|
||||
|
|
|
@ -16,6 +16,7 @@ const menu = [
|
|||
{name:"疑修 (Issue)",index:"issues"},
|
||||
{name:"合并请求 (PR)",index:"pulls"},
|
||||
{name:"引擎 (Engine)",index:"devops"},
|
||||
{name:"数据集",index:"dataset"},
|
||||
// {name:"资源库",index:"resources"},
|
||||
{name:"里程碑",index:"versions"},
|
||||
{name:"维基 (Wiki)",index:"wiki"},
|
||||
|
@ -397,7 +398,7 @@ class Setting extends Component {
|
|||
{getFieldDecorator("project_units", {
|
||||
rules: [],
|
||||
})(
|
||||
<Checkbox.Group>
|
||||
<Checkbox.Group className="unitStyle">
|
||||
{
|
||||
menu.map((item,key)=>{
|
||||
return(
|
||||
|
|
|
@ -348,4 +348,11 @@
|
|||
border-top: 1px solid rgba(90, 117, 193, 0.23)
|
||||
}
|
||||
}
|
||||
}
|
||||
.unitStyle{
|
||||
.ant-checkbox-wrapper + .ant-checkbox-wrapper{
|
||||
margin-left: 0px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue