diff --git a/public/css/edu-purge.css b/public/css/edu-purge.css
index 694a4b03..14ac4a7e 100644
--- a/public/css/edu-purge.css
+++ b/public/css/edu-purge.css
@@ -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;
diff --git a/src/forge/Dataset/Index.jsx b/src/forge/Dataset/Index.jsx
index 0314ac16..779f1633 100644
--- a/src/forge/Dataset/Index.jsx
+++ b/src/forge/Dataset/Index.jsx
@@ -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
+ }
},
{
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 下载
+ }
},
]
+
+ // 添加成功
+ function addFunc(){
+ setEmpty(false);
+ setVisible(false);
+ detail && detail.id && Init();
+ }
return(
+
setVisible(false)} onOk={addFunc}/>
-
-
MNISTData_mindspore
-
MNISTData数据集是由10类28*28的灰度图片组成,训练数据集包含60000张图片,测试数据集包含10000张图片。
-
-
-
-
-
+ {empty ?
+
数据集
+ :
+
+
+
{detail.title}
+
{detail.description}
+
+
+
+ 上传文件
+
+
+ }
-
+ {
+ empty?
+
+
+
暂无数据集
+
我们非常欢迎您创建并分享您的数据集,以便与其他用户共同促进开源社区的发展
+
+
+ :
+ setPage(p)}}
+ />
+ }
)
}
diff --git a/src/forge/Dataset/component/new.jsx b/src/forge/Dataset/component/new.jsx
new file mode 100644
index 00000000..a12c6a74
--- /dev/null
+++ b/src/forge/Dataset/component/new.jsx
@@ -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(
+
+
+ {getFieldDecorator('title', {
+ rules: [
+ {
+ required:true,
+ message:"请输入数据集名称"
+ }
+ ],
+ })(
+ ,
+ )}
+
+
+ {getFieldDecorator('license_id', {
+ rules: [{
+ validator: (rule, value, callback) => checkId(rule, value, callback, licensesList, '开源许可证')
+ }],
+ })(
+ {e1.props && setLicenseId(e1.props.id)}}
+ >
+ {
+ filterLicensesList && filterLicensesList.map((item) => (
+
+ ))
+ }
+
+ )}
+
+
+ {getFieldDecorator('description', {
+ rules: [
+ {
+ required:true,
+ message:"请输入描述内容"
+ }
+ ]})(
+ ,
+ )}
+
+
+ {getFieldDecorator('paper_content', {rules:[]})(
+ ,
+ )}
+
+
+
+
+
+
+
+ )
+}
+export default Form.create({ name: 'New' })(New);;
\ No newline at end of file
diff --git a/src/forge/Dataset/component/uploadModal.jsx b/src/forge/Dataset/component/uploadModal.jsx
new file mode 100644
index 00000000..7d8ffa3d
--- /dev/null
+++ b/src/forge/Dataset/component/uploadModal.jsx
@@ -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(
+
+
上传数据集文件
+
+ {getFieldDecorator('description', {
+ rules: [
+ {
+ required:true,
+ message:"请输入文件描述"
+ }
+ ],
+ })(
+ ,
+ )}
+
+
+ {getFieldDecorator('files', {
+ rules: [
+ {
+ required:true,
+ message:"请上传文件"
+ }
+ ],
+ })(
+
+ 点击添加文件或直接拖拽文件到此处
+ ,
+ )}
+
+
+ 取消
+
+
+
+
+ )
+}
+export default Form.create({ name: 'UploadModal' })(UploadModal);;
\ No newline at end of file
diff --git a/src/forge/Dataset/image/empty.png b/src/forge/Dataset/image/empty.png
new file mode 100644
index 00000000..553d845c
Binary files /dev/null and b/src/forge/Dataset/image/empty.png differ
diff --git a/src/forge/Dataset/index.scss b/src/forge/Dataset/index.scss
index 14ac0d8d..24442e2d 100644
--- a/src/forge/Dataset/index.scss
+++ b/src/forge/Dataset/index.scss
@@ -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;
}
\ No newline at end of file
diff --git a/src/forge/Main/Detail.js b/src/forge/Main/Detail.js
index 78fecce2..677f753e 100644
--- a/src/forge/Main/Detail.js
+++ b/src/forge/Main/Detail.js
@@ -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 {
() => ()
}
>
+
{/* 数据集 */}
+ ()
+ }
+ >
()
+ (props) => ()
}
>
{/* wiki新增文件 */}
diff --git a/src/forge/Main/img/dataset.jpg b/src/forge/Main/img/dataset.jpg
new file mode 100644
index 00000000..0665add4
Binary files /dev/null and b/src/forge/Main/img/dataset.jpg differ
diff --git a/src/forge/Main/sub/DetailBanner.jsx b/src/forge/Main/sub/DetailBanner.jsx
index ad11ea5b..1370206b 100644
--- a/src/forge/Main/sub/DetailBanner.jsx
+++ b/src/forge/Main/sub/DetailBanner.jsx
@@ -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
:""
}
+ {
+ item.menu_name === "dataset" ?
+
+
+ 数据集
+ {projectDetail && projectDetail.ops_count ? {projectDetail.ops_count} : ""}
+
+
+ :""
+ }
{/* {
item.menu_name === "resources" &&
@@ -168,12 +179,7 @@ function DetailBanner({ history,list , owner , projectsId ,showNotification , ur
)
})
}
- {/*
-
- 数据集
- {projectDetail && projectDetail.ops_count ? {projectDetail.ops_count} : ""}
-
- */}
+
:
diff --git a/src/forge/Settings/Setting.js b/src/forge/Settings/Setting.js
index 34dcd7f9..024f98b6 100644
--- a/src/forge/Settings/Setting.js
+++ b/src/forge/Settings/Setting.js
@@ -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: [],
})(
-
+
{
menu.map((item,key)=>{
return(
diff --git a/src/forge/Settings/setting.scss b/src/forge/Settings/setting.scss
index 8af100ef..4b996de0 100644
--- a/src/forge/Settings/setting.scss
+++ b/src/forge/Settings/setting.scss
@@ -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;
+ }
}
\ No newline at end of file