From 28f92a5f823eb5cbb0bf25c56fec5f269c9996e9 Mon Sep 17 00:00:00 2001 From: caishi <1149225589@qq.com> Date: Thu, 28 May 2020 11:35:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/forge/Images/upload.png | Bin 0 -> 1219 bytes src/forge/Main/CoderRootCommit.js | 3 +- src/forge/Main/CoderRootIndex.js | 4 +- src/forge/Main/Detail.js | 55 ++- src/forge/Merge/NewMerge.js | 478 +++++++++--------- src/forge/Merge/merge.js | 2 +- src/forge/Order/New.js | 2 + src/forge/Order/OrderItem.js | 137 +++--- src/forge/Order/index.scss | 72 +++ src/forge/Order/order.css | 40 +- src/forge/Order/order.js | 779 ++++++++++++++++++++---------- src/forge/Upload/Index.js | 18 +- src/forge/Utils/TagColor.jsx | 20 + src/forge/Utils/Time.js | 2 +- src/forge/Version/New.jsx | 331 ++++++++++--- src/forge/Version/version.css | 18 +- 16 files changed, 1251 insertions(+), 710 deletions(-) create mode 100644 src/forge/Images/upload.png create mode 100644 src/forge/Order/index.scss create mode 100644 src/forge/Utils/TagColor.jsx diff --git a/src/forge/Images/upload.png b/src/forge/Images/upload.png new file mode 100644 index 0000000000000000000000000000000000000000..aaad201d7d7a873b67f09e488e6224d0d2e5372d GIT binary patch literal 1219 zcmV;!1U&nRP)YF`Y3K zykBc#!D{$L1Su!g6vladoebVR^YopfR!zqJ7Zt18Ir;{3Yc{Uo_t&eGjcS?Y7 z)Pfj1k*t-siw5fSr!#C$h;Vg@fxeimmAayVT1~nEn>R`cGV4Xyor*|p@jw&04`qF+ zfeP$MM&;Q_gT`WN99_VIbeax?J4y`{*qVyUD+Pg8HtAy1=23(-D7ONE5(FHvbV8K( z#OB?$E%I|NpBFuKt(`g-g9en12s26;E|;~m!kdG_*8g`)7l2ka=`z!%9k}5V1H90# z@RKN^WK_N%*%$>~)2K@glP`d)E@{aB$bL74^441U@%)1s2=CF^gF}2NuxyGToe6>e z_q@=Z>1BDxb~&2`wG#RQ%7lNoMfm~*MS0o~Ix|YwIDK+aN{#u+X8(F5oY47cc4w=yQExT_9PzvHSNO*;xlXLOJ_YRc9a4BJ6_E{N>x2?ouIG<(GkvZf zaX>qO2mLH0aHy}B%3RaCswS-#n|*#wA%?j+Box)k>EO?Wm+8rnBY-`4G6vOI%*9a!jm* z?nkN4EA}8zIMg1M)gD4drB!ha3A7awJ8q0{K&+j*9wYnIEB5LIG6*V4!+7&o=cSWv z(uIz`aB^;=;vOb!9u}wlOAp~3ZRQu7bWFb2Qc>BME58-j+kvlqtbMvHz><*`um+{c z$70h5D%7STvO5b}5!1lDARj2);}h((fC_xl*UNoQqcVC-3pZ*oZSpyAqYtpt0eZYF z!-|$I;yf!Z96;aSsKLtu96-6Z$goojDtvTqi0Z?`kQaeEAB3CL9QutX)n*&8s7Sz5 z1==G94S|Kc-m*?IW4(_%sju9tmm32-AWD@g%SE!#&bt)P(|w@Wpo7Cc{!*n!gl|-6 hw|nVy4%xXb&c8~FlG-k=CAR import('../Version/NewVersion'), + loader: () => import('../Version/New'), loading: Loading, }) const CoderRootVersionUpdate = Loadable({ - loader: () => import('../Version/UpdateVersion'), + loader: () => import('../Version/New'), loading: Loading, }) diff --git a/src/forge/Main/Detail.js b/src/forge/Main/Detail.js index 692d1d969..b0c173aee 100644 --- a/src/forge/Main/Detail.js +++ b/src/forge/Main/Detail.js @@ -303,6 +303,9 @@ class Detail extends Component { {projectDetail.fork_info.fork_form_name} : "" ); + const common ={ + getDetail:this.getDetail + } return (
@@ -412,55 +415,55 @@ class Detail extends Component { {/* 新建文件 */} () + (props) => () } > () + (props) => () } > {/* 标签列表 */} () + (props) => () } > {/* 仓库设置 */} () + (props) => () } > {/* 任务详情 */} () + (props) => () } > {/* 里程碑 */} () + (props) => () } > {/* 新建里程碑 */} () + (props) => () } > {/*里程碑详情*/} () + (props) => () } > {/*修改里程碑*/} () + (props) => () } > @@ -468,34 +471,34 @@ class Detail extends Component { {/* 里程碑页面新建任务 */} () + (props) => () } > {/* 新建任务 */} () + (props) => () } > {/* 修改详情 */} () + (props) => () } > {/* 复制详情 */} () + (props) => () } > {/* 动态 */} () + (props) => () } > @@ -503,68 +506,68 @@ class Detail extends Component { {/* 代码Index */} () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > () + (props) => () } > diff --git a/src/forge/Merge/NewMerge.js b/src/forge/Merge/NewMerge.js index 7797417dc..e3bc15ee0 100644 --- a/src/forge/Merge/NewMerge.js +++ b/src/forge/Merge/NewMerge.js @@ -1,6 +1,6 @@ -import React , {Component} from 'react'; +import React, { Component } from 'react'; import { Link } from 'react-router-dom'; -import {Radio, Form,Menu,Dropdown,Input,Select,Table, Spin} from 'antd'; +import { Radio, Form, Menu, Dropdown, Input, Select, Table, Spin } from 'antd'; import axios from 'axios'; import UploadComponent from '../Upload/Index'; import { getImageUrl } from 'educoder'; @@ -13,115 +13,115 @@ const Option = Select.Option; const options = [ ['bold', 'italic', 'underline'], - [{header: [1,2,3,false]}], + [{ header: [1, 2, 3, false] }], ['blockquote', 'code-block'], ['link', 'image'], ['formula'] ]; -class NewMerge extends Component{ - constructor(props){ +class NewMerge extends Component { + constructor(props) { super(props); - this.state={ - data:undefined, + this.state = { + data: undefined, //合并 拉取 - merge:undefined, - pull:undefined, + merge: undefined, + pull: undefined, //判断 是否显示创建合并请求的页面 - desc:undefined, - iscreatemerge:'none', - issue_tag_ids:"", - fixed_version_id:"", - assigned_to_id:"", - titledata:undefined, - dataCount:undefined, - limit:50, - page:1, - isSpin:false, - mergedata:undefined, + desc: undefined, + iscreatemerge: 'none', + issue_tag_ids: "", + fixed_version_id: "", + assigned_to_id: "", + titledata: undefined, + dataCount: undefined, + limit: 50, + page: 1, + isSpin: false, + mergedata: undefined, } } - componentDidMount=()=>{ - this.getmergelist(); - this.InitData(); + componentDidMount = () => { + this.getmergelist(); + this.InitData(); } - InitData=()=>{ + InitData = () => { this.props.form.setFieldsValue({ ...this.state }); } - onPanelChange=(time, mode)=>{ + onPanelChange = (time, mode) => { this.setState({ - value:time - }); + value: time + }); } - onSelect=(time)=>{ + onSelect = (time) => { this.setState({ - value:time, + value: time, selectedValue: time, }); } - getOption=(name,id)=>{ + getOption = (name, id) => { - if(id==='branches'){ - this.ischeckmerge(name,this.state.pull) + if (id === 'branches') { + this.ischeckmerge(name, this.state.pull) this.setState({ - merge:name + merge: name }) - }else{ - if(this.state.iscreatemerge==='block'){ - if(this.state.merge===name){ - }else{ - const { page , limit } = this.state; - this.getCommitList( name , page , limit ); + } else { + if (this.state.iscreatemerge === 'block') { + if (this.state.merge === name) { + } else { + const { page, limit } = this.state; + this.getCommitList(name, page, limit); } - }else{ + } else { } - this.ischeckmerge(this.state.merge,name) + this.ischeckmerge(this.state.merge, name) this.setState({ - pull:name + pull: name }) } } - ismerge=()=>{ + ismerge = () => { this.setState({ - iscreatemerge:'block' + iscreatemerge: 'block' }) - const { page , limit } = this.state; - this.getCommitList( this.state.pull , page , limit ); + const { page, limit } = this.state; + this.getCommitList(this.state.pull, page, limit); } //获取新建分枝数据 - getmergelist=()=>{ + getmergelist = () => { const { projectsId } = this.props.match.params; const url = `/projects/${projectsId}/pull_requests/new.json`; - axios.get(url).then((result)=>{ - if(result){ + axios.get(url).then((result) => { + if (result) { this.setState({ - data:result.data, - merge:result.data.branches[0], - pull:result.data.branches[0], + data: result.data, + merge: result.data.branches[0], + pull: result.data.branches[0], }) } - }).catch((error)=>{ + }).catch((error) => { console.log(error); }) } - renderMenu =(array,id)=>{ - return( + renderMenu = (array, id) => { + return ( { - array && array.length > 0 && array.map((item,key)=>{ - return( - this.getOption(item,id)}>{item} + array && array.length > 0 && array.map((item, key) => { + return ( + this.getOption(item, id)}>{item} ) }) } @@ -129,12 +129,12 @@ class NewMerge extends Component{ ) } - renderSelect=(list)=>{ - if(list && list.length >0){ - return( - list.map((item,key)=>{ - return( - + renderSelect = (list) => { + if (list && list.length > 0) { + return ( + list.map((item, key) => { + return ( + ) }) ) @@ -142,44 +142,45 @@ class NewMerge extends Component{ } //创建合并请求 - - submit=()=>{ + + submit = () => { this.setState({ isSpin: true }) this.props.form.validateFieldsAndScroll((err, values) => { - if(!err){ + if (!err) { const { projectsId } = this.props.match.params; const url = `/projects/${projectsId}/pull_requests.json`; - if(values.issue_tag_ids.length > 0){ + if (values.issue_tag_ids.length > 0) { values.issue_tag_ids = [parseInt(values.issue_tag_ids)] - }else{ + } else { values.issue_tag_ids = [] } const { desc } = this.state; - axios.post(url,{ + axios.post(url, { ...values, - body:JSON.stringify(desc), - project_id:projectsId, - head:this.state.merge, - base:this.state.pull, + body: JSON.stringify(desc), + project_id: projectsId, + head: this.state.merge, + base: this.state.pull, - }).then(result=>{ - if(result){ + }).then(result => { + if (result) { this.setState({ isSpin: false }) - this.props.history.push(`/projects/${projectsId}/merge`); + this.props.history.push(`/projects/${projectsId}/merge`); + const { getDetail } = this.props; + getDetail && getDetail(); } - - }).catch(error=>{ + }).catch(error => { this.setState({ isSpin: false }) console.log(error); }) - }else{ + } else { this.setState({ isSpin: false }) @@ -188,238 +189,231 @@ class NewMerge extends Component{ } //获取提交列表 - getCommitList=(branch , page , limit)=>{ + getCommitList = (branch, page, limit) => { const { projectsId } = this.props.match.params; const url = `/repositories/${projectsId}/commits.json`; - axios.get(url,{ - params:{ - sha:branch, + axios.get(url, { + params: { + sha: branch, page, limit } - }).then((result)=>{ - if(result){ + }).then((result) => { + if (result) { const array = []; - result.data && result.data.commits.length > 0 && result.data.commits.map((item,key)=>{ + result.data && result.data.commits.length > 0 && result.data.commits.map((item, key) => { array.push({ - name:item.author && item.author.name, + name: item.author && item.author.name, login: item.author && item.author.login, - image_url:item.author && item.author.image_url, - sha:item.sha, - time_from_now:item.time_from_now, - message:item.message + image_url: item.author && item.author.image_url, + sha: item.sha, + time_from_now: item.time_from_now, + message: item.message }) }) this.setState({ - titledata:array, - dataCount:result.data.total_count, - isSpin:false + titledata: array, + dataCount: result.data.total_count, + isSpin: false }) } - }).catch((error)=>{console.log(error)}) + }).catch((error) => { console.log(error) }) } //判断2分支是否可以合并 - ischeckmerge=(head,base)=>{ + ischeckmerge = (head, base) => { const { projectsId } = this.props.match.params; const url = `/projects/${projectsId}/pull_requests/check_can_merge.json`; - axios.post(url,{ - project_id:projectsId, - head:head, - base:base, + axios.post(url, { + project_id: projectsId, + head: head, + base: base, - }).then(result=>{ - if(result){ - this.setState({ - mergedata:result.data - }) + }).then(result => { + if (result) { + this.setState({ + mergedata: result.data + }) } - - }).catch(error=>{ + + }).catch(error => { console.log(error); }) } - onContentChange=(value)=>{ + onContentChange = (value) => { this.setState({ - desc:value + desc: value }) } - render(){ + render() { const { getFieldDecorator } = this.props.form; const { projectsId } = this.props.match.params; const { current_user } = this.props; - const { issue_tag_ids , fixed_version_id ,assigned_to_id , data,titledata , desc, isSpin } = this.state; + const { issue_tag_ids, fixed_version_id, assigned_to_id, data, titledata, desc, isSpin } = this.state; - const columns=[{ - title:"作者", + const columns = [{ + title: "作者", dataIndex: 'name', - width:"10%", - render: (text,item) => ( + width: "10%", + render: (text, item) => ( - - - + + + - {/**/} - {/**/} ), - },{ - title:"SHA", + }, { + title: "SHA", dataIndex: 'sha', render: (text) => ( {text} ) - },{ - title:"备注", + }, { + title: "备注", dataIndex: 'message', render: (text) => ( {text} ) - },{ - title:"提交时间", - className:"edu-txt-right", + }, { + title: "提交时间", + className: "edu-txt-right", dataIndex: 'time_from_now', render: (text) => ( {text} ) }] - const title =()=>{ - return( -
+ const title = () => { + return ( +
提交列表 - {/*
- - 所有分支 - 搜索 -
*/}
) } - const pull =()=>{ - if(this.state.mergedata&&this.state.mergedata.status===-2){ - return( + const pull = () => { + if (this.state.mergedata && this.state.mergedata.status === -2) { + return (
- 在这些分支直接合并请求已经存在:{this.state.mergedata&&this.state.mergedata.pull_request_name} + 在这些分支直接合并请求已经存在:{this.state.mergedata && this.state.mergedata.pull_request_name}
) - }else{ - return( -
- {this.state.mergedata&&this.state.mergedata.status===0?: "分支内容相同,无需创建合并请求"} -
+ } else { + return ( +
+ {this.state.mergedata && this.state.mergedata.status === 0 ? : "分支内容相同,无需创建合并请求"} +
) } } - - - return( -
- -

创建合并请求

-
选择合并的目标分支和源分支
-
-
-
- - - - ... - - - -
-
-
-
-
- {pull()} -
-
-
-
-
-
- - - -
- - {getFieldDecorator('title', { - rules: [{ - required: true, message: '请填写请求标题' - }], - })( - - )} - - - - -

- - 创建合并请求 - -

-
-
-
-
- - {getFieldDecorator('issue_tag_ids', { - - rules: [], - })( - - )} - - - {getFieldDecorator('fixed_version_id', { - - rules: [], - })( - - )} - - - {getFieldDecorator('assigned_to_id', { - })( - - )} - -
+ + return ( +
+ +

创建合并请求

+
选择合并的目标分支和源分支
+
+
+
+ + + + ... + + +
-
-
- +
+ {pull()} +
+ +
+
+
+
+ + + + +
+ + {getFieldDecorator('title', { + rules: [{ + required: true, message: '请填写请求标题' + }], + })( + + )} + + + + +

+ + 创建合并请求 + +

+
+
+
+
+ + {getFieldDecorator('issue_tag_ids', { + + rules: [], + })( + + )} + + + {getFieldDecorator('fixed_version_id', { + + rules: [], + })( + + )} + + + {getFieldDecorator('assigned_to_id', { + })( + + )} + +
+
+
+ +
+
+
title()} /> - + ) } } diff --git a/src/forge/Merge/merge.js b/src/forge/Merge/merge.js index 749dc860f..37124417b 100644 --- a/src/forge/Merge/merge.js +++ b/src/forge/Merge/merge.js @@ -290,7 +290,7 @@ class merge extends Component { this.islogin()}>创建合并请求 -
+
  • diff --git a/src/forge/Order/New.js b/src/forge/Order/New.js index 18fd5dd1c..ef259e1e8 100644 --- a/src/forge/Order/New.js +++ b/src/forge/Order/New.js @@ -125,6 +125,8 @@ class New extends Component { description: '', isSpin: false }) + const { getDetail } = this.props; + getDetail && getDetail(); } }).catch(error => { this.setState({ diff --git a/src/forge/Order/OrderItem.js b/src/forge/Order/OrderItem.js index c2d731d53..0b0870932 100644 --- a/src/forge/Order/OrderItem.js +++ b/src/forge/Order/OrderItem.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { Link } from 'react-router-dom'; import { Popconfirm } from 'antd' - +import { TagInfo } from '../Utils/TagColor'; class OrderItem extends Component { @@ -18,7 +18,7 @@ class OrderItem extends Component { return ( issue_tags.map((item, key) => { return ( - {item.name} + {item.name} ) }) ) @@ -43,88 +43,79 @@ class OrderItem extends Component { isdisplay: false }) } - render() { - const { issues, search_count, page, limit } = this.props; + const { item, key, checkbox } = this.props; const { projectsId } = this.props.match.params; const { current_user } = this.props const renderList = () => { - if (issues && issues.length > 0) { + if (item) { return ( - issues.map((item, key) => { - return ( -
    -
    -

    - # {search_count - (key + (page - 1) * limit)} - {item.name} -

    -

    - {item.format_time}发布 - { - item.updated_at === item.format_time ? - "" - : - {item.updated_at}更新 - } -

    -
    -
      this.onMouseMove(item.id)} onMouseOut={() => this.onMouseOut()} > -
    • {this.set_issue_tags(item.issue_tags)}
    • -
    • {item.tracker || "--"}
    • -
    • - { - item.author_name ? - - {item.author_name} - - : "--" - } -
    • -
    • - { - item.assign_user_name ? - - {item.assign_user_name} - - : "--" - } -
    • -
    • {item.priority || "--"}

    • -
    • {item.done_ratio || "--"}
    • -
    • -
      -

      - {item.journals_count ? {item.journals_count} : ""} -

      - { - current_user && current_user.login ? -
      -
      - -
      -
      - this.deletedetail(item.id)}> - - -
      -
      - : "" - } +
      + {current_user && current_user.login && checkbox} +
      +

      + {item.name} + {TagInfo(item.priority,"ml10")} +

      +

      + {item.format_time}发布 + { + item.updated_at === item.format_time ? "" : + {item.updated_at}更新 + } +

      +
      +
        this.onMouseMove(item.id)} onMouseOut={() => this.onMouseOut()} > +
      • {this.set_issue_tags(item.issue_tags)}
      • +
      • + { + item.author_name ? + + {item.author_name} + + : "--" + } +
      • +
      • + { + item.assign_user_name ? + + {item.assign_user_name} + + : "--" + } +
      • +
      • {item.tracker || "--"}
      • +
      • {item.version || "--"}
      • +
      • {item.issue_status || "--"}
      • +
      • {item.done_ratio || "--"}
      • +
      • +
        + {item.journals_count} + { + current_user && current_user.login ? +
        +
        + +
        +
        + this.deletedetail(item.id)}> + + +
        -
      • -
      -
      - ) - }) + : "" + } +
      +
    • +
    +
    ) } } return ( -
    - {renderList()} -
    + renderList() ) } } diff --git a/src/forge/Order/index.scss b/src/forge/Order/index.scss new file mode 100644 index 000000000..f6b760b6a --- /dev/null +++ b/src/forge/Order/index.scss @@ -0,0 +1,72 @@ +.screenWrap{ + background:rgba(250,250,250,1); + border:1px solid rgba(221,221,221,1); +} + +.searchBanner{ + display: flex; + height: 50px; + line-height: 50px; + li{ + margin-right: 30px; + display: flex; + align-items: center; + } + li > label{ + position: relative; + cursor: pointer; + } + li > span{ + display: block; + padding:0px 8px; + border-radius: 10px; + background-color: #eee; + margin-left: 5px; + cursor: pointer; + height: 20px; + line-height: 20px; + } + li.active > label::after{ + position: absolute; + width: 100%; + height: 2px; + content: ''; + left: 0px; + bottom:0px; + background-color:#5091FF; + } +} +.milepostleft{ + &>div{ + display: flex; + align-items: center; + justify-content: center + } +} +.statusTag{ + display: block; + height: 24px; + line-height: 24px; + border-radius: 4px; + padding:0px 12px; + color: #fff; + margin:3px 0px 0px 10px; +} + +.updateBtn{ + display: block; + width:60px; + text-align: center; + height: 26px; + line-height: 26px; + background-color: #fff; + border-radius: 5px; +} +.updateBtn.blue{ + border:1px solid #5091FF; + color: #5091FF; +} +.updateBtn.red{ + border:1px solid #F73030; + color: #F73030; +} \ No newline at end of file diff --git a/src/forge/Order/order.css b/src/forge/Order/order.css index 57032348b..a1a01e5bc 100644 --- a/src/forge/Order/order.css +++ b/src/forge/Order/order.css @@ -1,9 +1,8 @@ .topWrapper { - padding: 20px 0; + padding-bottom:20px; box-sizing: border-box; display: flex; justify-content: space-between; - border-bottom: 1px solid #EEEEEE; flex-wrap: wrap; } .quillContent{ @@ -129,8 +128,9 @@ border-radius: 0px 5px 5px 0px; } .topWrapper_btn { - background: #21ba45; - color: #FFFFFF!important; + background: #fff; + border:1px solid #5091FF; + color: #5091FF!important; padding:0px 12px; text-align: center; height: 32px; @@ -138,23 +138,29 @@ border-radius: 4px; } .topWrapper_type{ - border:1px solid #f4f4f4; - border-radius: 6px; display: flex; } .topWrapper_type li{ + display: flex; + align-items: center; + margin-right: 30px; +} +.topWrapper_type li >span{ + display: block; height: 30px; line-height: 30px; - border-left:1px solid #f4f4f4; - padding:0px 8px; + padding: 0px 13px; + border-radius: 5px; + min-width: 60px; + box-sizing: border-box; + text-align: center; + background:rgba(250,250,250,1); + border:1px solid rgba(221,221,221,1); cursor: pointer; - color: #666 } -.topWrapper_type li.active{ +.topWrapper_type li > span.active{ color: #4CACFF; -} -.topWrapper_type li:first-child{ - border-left: none; + border:1px solid rgba(80,145,255,1); } .topWrapper_select{ display: flex; @@ -202,9 +208,6 @@ border-bottom:1px dashed #cecdcd; padding:16px 0px; } -.issueItem:first-child{ - border-top:1px dashed #cecdcd; -} .issueNo{ padding:0px 5px; border-radius: 4px; @@ -421,10 +424,8 @@ width: 80%; } .milepostleft{ - text-align: right; display: flex; - justify-content: right; - width: 20%; + justify-content: center; } .textwidth{ display: flex; @@ -531,7 +532,6 @@ a.issue-type-button.active:hover{background: #f4f4f4; color: #4CACFF;} .attachment-list-div:hover .attachment-list-delete{display: block !important;} .attachment-list-a{color: rgba(0, 0, 0, 0.65) !important;} .btp1{border-top: 1px solid #f4f4f4;} -.grid-item{display: grid; align-items: center; grid-template-columns: max-content 1fr;} .fwb{font-weight: bold;} /* 发布人、指派人数量过多时要出现滚动条 */ diff --git a/src/forge/Order/order.js b/src/forge/Order/order.js index 3d6e09d2e..2b9fd2043 100644 --- a/src/forge/Order/order.js +++ b/src/forge/Order/order.js @@ -1,6 +1,8 @@ import React, { Component } from "react"; -import { Input, Dropdown, Menu, Icon, Pagination, Spin } from "antd"; +import { Input, Dropdown, Menu, Icon, Pagination, Spin, DatePicker, Checkbox } from "antd"; import "./order.css"; +import './index.scss'; +import moment from 'moment'; import NoneData from "../Nodata"; import OrderItem from "./OrderItem"; @@ -33,32 +35,40 @@ class order extends Component { search: undefined, author_id: undefined, assigned_to_id: undefined, - // limit: 15, - // page: 1, search_count: undefined, issue_type: undefined, - status_type: "1", - //设置选择高亮 - // openselect: 1, - // closeselect: undefined, + status_type: undefined, issue_tag_ids: "标签", - tracker_ids: "所有分类", + tracker_ids: "类型", author_ids: "发布人", - assigned_to_ids: "指派人", - priority_ids: "优先度", + assigned_to_ids: "负责人", + fixed_version_ids: "里程碑", + status_ids: "状态", done_ratios: "完成度", paix: "排序", + update_author_ids:"更换负责人", + update_fixed_version_ids:'更换里程碑', + update_status_ids:"修改状态", + begin: '', + end: '', + checkedValue: [], + allValue: [], + all: false, select_params: { - status_type: "1", //开启中和关闭中,默认为开启中的 - assigned_to_id: undefined, // 指派人 + status_type: undefined, //开启中和关闭中,全部,默认为全部 + assigned_to_id: undefined, // 负责人 author_id: undefined, // 发布人 issue_tag_id: undefined, // 标签 - tracker_id: undefined, //所有分类 + tracker_id: undefined, //类型 done_ratio: undefined, // 完成度 - priority_id: undefined, // 优先级 + status_id: undefined, // 优先级 + fixed_version_id: undefined,//里程碑 order_name: undefined, order_type: undefined, search: undefined, + update_author_id:undefined, + update_fixed_version_id:undefined, + update_status_id:undefined, page: 1, limit: 15, }, @@ -71,39 +81,52 @@ class order extends Component { }; getSelectList = () => { + this.setState({ + isSpin: true + }) const { projectsId } = this.props.match.params; const url = `/projects/${projectsId}/issues/index_chosen.json`; - axios - .get(url) - .then((result) => { - if (result) { - this.setState({ - issue_chosen: result.data.issue_chosen, - }); - } - }) + axios.get(url).then((result) => { + if (result) { + this.setState({ + issue_chosen: result.data.issue_chosen, + isSpin: false + }); + } + }) .catch((error) => { console.log(error); }); }; // 获取列表数据 - getIssueList = () => { + getIssueList = (begin, end) => { + this.setState({ + isSpin: true + }) const { select_params } = this.state; const { projectsId } = this.props.match.params; const url = `/projects/${projectsId}/issues.json`; axios .get(url, { - params: select_params, + params: { + ...select_params, + start_date: begin, + due_date: end + } }) .then((result) => { if (result) { + const issues = result.data.issues this.setState({ data: result.data, - issues: result.data.issues, + issues: issues, search_count: result.data.search_count, isSpin: false, + allValue: issues && issues.length > 0 && issues.map((item) => { + return (item.id) + }) }); } }) @@ -145,35 +168,38 @@ class order extends Component { this.getIssueList(); }; - getOption = (e, id, name) => { + getOption = (e, id, name,toGet) => { const { current_user } = this.props; - this.setState({ - isSpin: true, - }); let option_id = e.key === "all" ? undefined : e.key; - this.state.select_params[`${id}`] = option_id; - this.state.select_params.page = 1; - this.state[`${id}s`] = name; - if (current_user) { - if ( this.state.select_params.author_id && parseInt(this.state.select_params.author_id) === current_user.user_id) { - this.state.author_id = current_user.user_id; - } else { - this.state.author_id = undefined; - } - if (this.state.select_params.assigned_to_id && parseInt(this.state.select_params.assigned_to_id) === current_user.user_id ) { - this.state.assigned_to_id = current_user.user_id; + let select_params = this.state.select_params; + select_params[`${id}`] = option_id; + select_params.page = 1; + if (current_user) { + if (this.state.select_params.author_id && parseInt(this.state.select_params.author_id) === current_user.user_id) { + select_params.author_id = current_user.user_id; } else { - this.state.assigned_to_id = undefined; + select_params.author_id = undefined; + } + if (this.state.select_params.assigned_to_id && parseInt(this.state.select_params.assigned_to_id) === current_user.user_id) { + select_params.assigned_to_id = current_user.user_id; + } else { + select_params.assigned_to_id = undefined; } } - this.getIssueList(); + this.setState({ + [`${id}s`] : name, + select_params + }); + if(!toGet){ + this.getIssueList(); + } }; - renderMenu = (array, name, id) => { + renderMenu = (array, name, id,toGet) => { return ( - this.getOption(e, id, name)}> + this.getOption(e, id, name,toGet)}> {name} {array && @@ -182,7 +208,7 @@ class order extends Component { return ( this.getOption(e, id, item.name)} + onClick={(e) => this.getOption(e, id, item.name,toGet)} > {item.name} @@ -196,6 +222,8 @@ class order extends Component { ChangePage = (page) => { this.setState({ isSpin: true, + checkedValue: [], + all: false }); this.state.select_params.page = page; this.getIssueList(); @@ -214,29 +242,24 @@ class order extends Component { openorder = (type) => { this.setState({ - isSpin: true, + author_id: undefined, + assigned_to_id: undefined, + status_type: type, + issue_tag_ids: "标签", + tracker_ids: "类型", + author_ids: "发布人", + assigned_to_ids: "负责人", + status_ids: "状态", + done_ratios: "完成度", + paix: "排序", }); - if (type) { - this.setState({ - author_id: undefined, - assigned_to_id: undefined, - status_type: type, - issue_tag_ids: "标签", - tracker_ids: "所有分类", - author_ids: "发布人", - assigned_to_ids: "指派人", - priority_ids: "优先度", - done_ratios: "完成度", - paix: "排序", - }); - this.state.select_params = { - status_type: type, - search: undefined, - page: 1, - limit: 15, - }; - this.getIssueList(); - } + this.state.select_params = { + status_type: type, + search: undefined, + page: 1, + limit: 15, + }; + this.getIssueList(); }; // 筛选:全部、指派给我、由我创建 @@ -266,7 +289,7 @@ class order extends Component { author_ids: current_user.username, author_id: current_user.user_id, assigned_to_id: undefined, - assigned_to_ids: "指派人", + assigned_to_ids: "负责人", }); this.state.select_params.assigned_to_id = undefined; this.state.select_params.author_id = current_user.user_id; @@ -275,7 +298,7 @@ class order extends Component { this.setState({ author_ids: "发布人", author_id: undefined, - assigned_to_ids: "指派人", + assigned_to_ids: "负责人", assigned_to_id: undefined, }); this.state.select_params.assigned_to_id = undefined; @@ -288,13 +311,12 @@ class order extends Component { deletedetail = (id) => { const { projectsId } = this.props.match.params; const url = `/projects/${projectsId}/issues/${id}.json`; - axios - .delete(url, { - data: { - project_id: projectsId, - id: id, - }, - }) + axios.delete(url, { + data: { + project_id: projectsId, + id: id, + }, + }) .then((result) => { if (result) { this.getIssueList(); @@ -303,7 +325,6 @@ class order extends Component { .catch((error) => { console.log(error); }); - console.log(id); }; islogin() { @@ -316,9 +337,127 @@ class order extends Component { } } + // 修改开始时间 + changeBeginTime = (data, value) => { + this.setState({ + begin: value + }) + this.getIssueList(value, this.state.end); + } + changeEndTime = (data, value) => { + this.setState({ + end: value + }) + this.getIssueList(this.state.begin, value); + } + + // 选择列表里面的checkbox + checkIssues = (value) => { + this.setState({ + checkedValue: value + }) + const { allValue } = this.state; + this.setState({ + all: allValue && value && value.length === allValue.length, + }) + // 不勾选数据时清除右上角选择的项 + if(value.length === 0){ + this.setState({ + update_author_ids:"更换负责人", + update_fixed_version_ids:"更换里程碑", + update_status_ids:"修改状态", + select_params:{ + update_author_id:undefined, + update_fixed_version_id:undefined, + update_status_id:undefined + } + }) + } + } + // 全选和反选 + changeAll = (e) => { + if (e.target.checked) { + const { allValue } = this.state; + this.setState({ + checkedValue: allValue + }) + } else { + this.setState({ + checkedValue: [] + }) + } + this.setState({ + all: e.target.checked + }) + } + + // 批量修改 + updateIssues=()=>{ + const {checkedValue , select_params} = this.state; + const { projectsId } = this.props.match.params; + this.setState({ + isSpin:true + }) + const url = `/projects/${projectsId}/issues/series_update.json`; + axios.post(url,{ + ids:checkedValue, + assigned_to_id:select_params.update_author_id, + fixed_version_id:select_params.update_fixed_version_id, + status_id:select_params.update_status_id + }).then(result=>{ + if(result){ + this.props.showNotification("修改成功!"); + this.successFunc(); + } + }).catch(error=>{ + console.log(error); + }) + } + + successFunc=()=>{ + let select_params = this.state.select_params; + select_params.update_author_id = undefined; + select_params.update_fixed_version_id = undefined; + select_params.update_status_id = undefined; + this.setState({ + all:false, + checkedValue:[], + update_author_ids:"更换负责人", + update_fixed_version_ids:"更换里程碑", + update_status_ids:"修改状态", + select_params + }) + this.getIssueList(); + } + + // 批量删除 + deleteIssues=()=>{ + this.props.confirm({ + content: "是否确认删除所有选中的任务?", + onOk:()=>{ + this.setState({ + isSpin:true + }) + const { checkedValue } = this.state; + const { projectsId } = this.props.match.params; + const url = `/projects/${projectsId}/issues/clean.json`; + axios.post(url,{ + ids:checkedValue + }).then(result=>{ + if(result){ + this.props.showNotification("删除成功!"); + this.successFunc(); + } + }).catch(error=>{ + console.log(error); + }) + } + }) + } + + render() { const { current_user } = this.props; - const { issue_chosen, issues, @@ -329,8 +468,8 @@ class order extends Component { isSpin, status_type, select_params, + begin, end, checkedValue, all } = this.state; - const menu = ( this.getMenu(e)}> @@ -361,203 +500,315 @@ class order extends Component { >
) : ( - "" - )} + "" + )} ); return (
-
-

-

  • this.openorder("1")} - > - {data && data.open_count}个开启中 +
    +
      +
    • + + this.openorder()} + >{data && data.all_count}
    • -
    • this.openorder("2")} - > - {data && data.close_count}个已关闭 +
    • + + this.openorder("1")} + >{data && data.open_count}
    • -

      - -
      -
      - -
      - this.islogin()}> - 创建任务 - +
    • + + this.openorder("2")}>{data && data.close_count} +
    • +
    + this.islogin()}> + + 创建任务 + +
    +
    +
    + +
    +
    + +
    -
    -
      -
    • this.ChangeAssign()} - > - 全部 -
    • -
    • this.ChangeAssign(1)} - > - 指派给我 -
    • -
    • this.ChangeAssign(2)} - > - 由我创建 -
    • -
    -
      -
    • - - - {this.state.issue_tag_ids} - - - -
    • -
    • - - - {this.state.tracker_ids} - - - -
    • -
    • - - - {this.state.author_ids} - - - -
    • -
    • - - - {this.state.assigned_to_ids} - - - -
    • -
    • - - - {this.state.priority_ids} - - - -
    • -
    • - - - {this.state.done_ratios} - - - -
    • -
    • - - - {this.state.paix} - - - -
    • -
    +
    +
    + + {checkedValue && checkedValue.length > 0 ? + 选中{checkedValue.length}个issue + : +
      +
    • this.ChangeAssign()} + > + + {data && data.search_count} +
    • +
    • this.ChangeAssign(1)} + > + + {data && data.assign_me_count} +
    • +
    • this.ChangeAssign(2)} + > + + {data && data.my_published_count} +
    • +
    + } +
    + { + checkedValue && checkedValue.length>0 ? +
      +
    • + + + {this.state.update_author_ids} + + + +
    • +
    • + + + {this.state.update_fixed_version_ids} + + + +
    • +
    • + + + {this.state.update_status_ids} + + + +
    • + 确定 + 删除 +
    + : +
      +
    • + + + {this.state.issue_tag_ids} + + + +
    • +
    • + + + {this.state.author_ids} + + + +
    • +
    • + + + {this.state.assigned_to_ids} + + + +
    • +
    • + + + {this.state.tracker_ids} + + + +
    • +
    • + + + {this.state.fixed_version_ids} + + + +
    • +
    • + + + {this.state.status_ids} + + + +
    • +
    • + + + {this.state.done_ratios} + + + +
    • +
    • + + + {this.state.paix} + + + +
    • +
    + } +
    {search_count === 0 ? ( ) : ( - - )} +
    + + {issues && issues.length > 0 && issues.map((item, key) => { + return ( + } + search_count={search_count} + page={select_params.page} + limit={select_params.limit} + {...this.props} + {...this.state} + deletedetail={this.deletedetail} + > + ) + })} + +
    + )} {Paginations}
    diff --git a/src/forge/Upload/Index.js b/src/forge/Upload/Index.js index 9aba86bb7..4d49c415e 100644 --- a/src/forge/Upload/Index.js +++ b/src/forge/Upload/Index.js @@ -73,9 +73,18 @@ class Index extends Component { array && this.props.load && this.props.load(array); } + beforeUpload = (file)=>{ + const { size } = this.props; + const isLt100M = file.size / 1024 / 1024 < size; + if (!isLt100M) { + this.props.showNotification(`文件大小必须小于${size}MB!`); + } + return isLt100M; + } + render() { //判断是否已经提交,如已提交评论则上一条评论数据清除 - const { isComplete } = this.props; + const { isComplete , icon } = this.props; const { fileList } = this.state; let list = isComplete === true ? fileList : undefined; @@ -85,13 +94,14 @@ class Index extends Component { action: `${getUploadActionUrl()}`, onChange: this.handleChange, onRemove: this.onAttachmentRemove, + beforeUpload:this.beforeUpload }; return (
    - - -

    拖动文件或者点击此处上传

    + + { icon || } +

    拖动文件或点击此处上传

    ) diff --git a/src/forge/Utils/TagColor.jsx b/src/forge/Utils/TagColor.jsx new file mode 100644 index 000000000..451ba0aa0 --- /dev/null +++ b/src/forge/Utils/TagColor.jsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Tag } from 'antd'; + +/** + * tagname:标签名字 + * className:额外需要添加的样式 + */ +export function TagInfo (tagname,className){ + let color = '#e74c3c'; + if(tagname === "高"){ + color = '#e67e22'; + }else if(tagname === "正常"){ + color = '#28be6c'; + }else if(tagname === "低"){ + color = '#1abc9c'; + }else{ + color = '#e74c3c'; + } + return ({tagname}); +} \ No newline at end of file diff --git a/src/forge/Utils/Time.js b/src/forge/Utils/Time.js index 921d9c4aa..55d73441b 100644 --- a/src/forge/Utils/Time.js +++ b/src/forge/Utils/Time.js @@ -1,5 +1,5 @@ -function getDateTime(value, dataformat) { +export function getDateTime(value, dataformat) { Date.prototype.format = function (format) { var date = { "M+": this.getMonth() + 1, diff --git a/src/forge/Version/New.jsx b/src/forge/Version/New.jsx index 08dda807a..bed9a6428 100644 --- a/src/forge/Version/New.jsx +++ b/src/forge/Version/New.jsx @@ -1,70 +1,275 @@ -import React , { useState, useEffect } from 'react'; -import styled from 'styled-components'; -import { AutoComplete } from 'antd'; -import axios from 'axios'; -import './version.css'; +import React, { useState, useEffect, useCallback, forwardRef } from "react"; +import styled from "styled-components"; +import { AutoComplete, Select, Input, Checkbox, Button, Form } from "antd"; -export default (projectDetail)=>{ - const [ tagList , setTagList ] = useState(undefined); +import Editor from "../../modules/tpm/challengesnew/tpm-md-editor"; +import Upload from "../Upload/Index"; +import Attachments from "../Upload/attachment"; +import axios from "axios"; +import "./version.css"; +import UploadImg from "../Images/upload.png"; - const SelectDiv = styled.div` - display:flex; - align-item:center; - margin-bottom:5px; - & span{ - margin:0px 15px; - color:#BBB; - line-height:35px; - } - `; +const { Option } = AutoComplete; - const repo_id = projectDetail && projectDetail.repo_id; - useEffect(() => { - if (repo_id) { - const url = `/repositories/${repo_id}/tags.json`; - axios.get(url).then((result) => { - if (result) { - setTagList(result.data); +export default Form.create()( + forwardRef( + ( + { form, projectDetail, branchs, match, showNotification, history }, + ref + ) => { + const { getFieldDecorator, validateFields, setFieldsValue } = form; + const [tagList, setTagList] = useState(undefined); + const [branchList, setBranchList] = useState(undefined); + const [desc, setDesc] = useState(null); + const [fileList, setFileList] = useState(undefined); + const [attachment, setAttachment] = useState(undefined); + + const SelectDiv = styled.div` + display: flex; + align-item: center; + margin-bottom: 5px; + & .ant-row { + margin-bottom: 0px; } - }).catch(error => { - console.log(error); - }) - } - }, [repo_id]); - return( -
    -
    -

    创建发行版

    -
    - -
    - - - + `; + const Span = styled.span` + margin: 0px 15px; + color: #bbb; + line-height: 35px; + `; + + const repo_id = projectDetail && projectDetail.repo_id; + const { projectsId, versionId } = match.params; + + useEffect(() => { + if (branchs) { + setBranchList(branchs); + } + }, [branchs]); + + useEffect(() => { + if (versionId) { + const url = `/projects/${projectsId}/version_releases/${versionId}/edit.json`; + axios.get(url).then(result => { + if (result) { + setFieldsValue(result.data); + setDesc(result.data.body); + setAttachment(result.data.attachments); + } + }); + } + }, [versionId]); + + useEffect(() => { + if (repo_id) { + const url = `/repositories/${repo_id}/tags.json`; + axios + .get(url) + .then(result => { + if (result) { + setTagList(result.data); + } + }) + .catch(error => { + console.log(error); + }); + } + }, [repo_id]); + + function renderTagList(list) { + if (list) { + let array = list.map((item, key) => { + return ( + + ); + }); + return array || undefined; + } + } + function changeT(value) { + // let l = tagList.filter(item => item.name.indexOf(value) > -1); + // setTagList(l); + } + function submit() { + validateFields((err, value) => { + if (versionId) { + let url = `/projects/${projectsId}/version_releases/${versionId}.json`; + axios + .put(url, { + ...value, + body: desc, + attachment_ids: fileList + }) + .then(result => { + if (result) { + showNotification("版本修改成功!"); + history.push(`/projects/${projectsId}/coders/version`); + } + }); + } else { + let url = `/projects/${projectsId}/version_releases.json`; + axios + .post(url, { + ...value, + body: desc, + attachment_ids: fileList + }) + .then(result => { + if (result) { + showNotification("版本发布成功!"); + history.push(`/projects/${projectsId}/coders/version`); + } + }); + } + }); + } + + const helper = useCallback( + (label, name, rules, widget, isRequired = true) => ( + + {label} + + {getFieldDecorator(name, { rules, validateFirst: true })(widget)} + + + ), + [] + ); + return ( +
    +
    +
    +

    创建发行版

    +
    + + {helper( + "", + "tag_name", + [{ required: true, message: "请输入获取或选择一个标签" }], + + )} + @ + {helper( + "", + "target_commitish", + [{ required: true, message: "请选择一个分支" }], + + )} + +

    + 选择一个已经存在的标签,或者在发布时新建一个标签 +

    +
    +
    + {helper( + "", + "name", + [{ required: true, message: "请输入发行版的标题" }], + + )} +
    +
    + +
    +
    + {helper( + "", + "prerelease", + [], + 这是一个预览版本 + )} +
    +
    + + } + size={100} + showNotification={showNotification} + /> + {versionId && attachment && attachment.length > 0 ? ( + + ) : ( + "" + )} +
    +

    + + +

    - @ - -

    选择一个已经存在的标签,或者在发布时新建一个标签

    + +
    +
    +

    标签命名建议

    +

    + 通常的做法是在版本名称前加上字母 v 前缀, v1.0 或者 v2.3.4。 +

    +

    + 如果标签不适合在生产环境下使用,请在版本名称后添加预发行版本。例如:v0.2-alpha + 或者 v5.9-beta.3。 +

    +
    +
    +

    语义化版本

    +

    + 如果你是第一次发布版本,我们强烈建议你阅读语义化版本。 +

    +
    +
    +

    附件大小说明

    +

    + 单个附件不能超过 100M(GVP 项目200M),每个仓库总附件不可超过 + 1G(推荐项目不可超过 5G;GVP 项目不可超过 + 20G)。附件总容量统计包括仓库附件和发行版附件。 +

    +
    +
    -
    -
    -
    -

    标签命名建议

    -

    通常的做法是在版本名称前加上字母 v 前缀, v1.0 或者 v2.3.4。

    -

    如果标签不适合在生产环境下使用,请在版本名称后添加预发行版本。例如:v0.2-alpha 或者 v5.9-beta.3。

    -
    -
    -

    语义化版本

    -

    如果你是第一次发布版本,我们强烈建议你阅读语义化版本。

    -
    -
    -

    附件大小说明

    -

    单个附件不能超过 100M(GVP 项目200M),每个仓库总附件不可超过 1G(推荐项目不可超过 5G;GVP 项目不可超过 20G)。附件总容量统计包括仓库附件和发行版附件。

    -
    -
    -
    + ); + } ) -} \ No newline at end of file +); diff --git a/src/forge/Version/version.css b/src/forge/Version/version.css index 38fb93128..3b68d5091 100644 --- a/src/forge/Version/version.css +++ b/src/forge/Version/version.css @@ -186,18 +186,12 @@ margin-bottom: 22px; color: #333; } -.tagComplete{ - border:1px solid #d9d9d9; - padding:0px 10px; - border-radius: 4px; +.versionStyle{ + height: 200px!important; + border: 1px dashed rgba(80,145,255,1)!important; +} +.set-ant-row .ant-row{ display: flex; + height: 20px; align-items: center; - width: 240px; -} -.tagComplete .ant-select{ - flex: 1; -} -.tagComplete .ant-select-auto-complete.ant-select .ant-input{ - border:none!important; - background-color: #fff!important; } \ No newline at end of file