-
-
创建工单
+
+
+ 创建工单
+
+
+
+
+ { data && data.subject }
+ 编辑
+
+
{ data && data.description }
+
+ 由 { data && data.author_name} 于 { data && data.created_at }创建{ data && data.journals_count && data.journals_count > 0 ?` · ${data.journals_count} 条评论`:""}
+
-
-
+
+
+
+ {listItems}
+
+
+
+
+
+
+
+
+
- { data && data.subject }
- 编辑
+ 当前状态
+ 已解决
-
{ data && data.description }
-
- 由 { data && data.author_name} 于 { data && data.created_at }创建{ data && data.journals_count && data.journals_count > 0 ?` · ${data.journals_count} 条评论`:""}
+
+ 优先级
+ 高
+
+
+ 指派给
+ 蔡世
+
+
+ 里程碑
+ 20200131前上线
+
+
+ 里程碑
+ 20200131前上线
-
-
-
-
-
- 当前状态
- 已解决
-
-
- 优先级
- 高
-
-
- 指派给
- 蔡世
-
-
- 里程碑
- 20200131前上线
-
-
- 里程碑
- 20200131前上线
-
-
+
+
+
+
)
}
}
diff --git a/public/react/src/forge/Order/Milepost.js b/public/react/src/forge/Order/Milepost.js
new file mode 100644
index 000000000..c4b448684
--- /dev/null
+++ b/public/react/src/forge/Order/Milepost.js
@@ -0,0 +1,244 @@
+import React , {Component} from 'react';
+import { Link } from 'react-router-dom';
+import { Dropdown , Icon , Menu , Pagination,Typography} from 'antd';
+import Nav from './Nav';
+import NoneData from '../../modules/courses/coursesPublic/NoneData';
+import reactCSS from 'reactcss'
+import axios from 'axios';
+
+const { Text } = Typography;
+
+class Milepost extends Component{
+ constructor(props){
+ super(props);
+ this.state={
+ data:undefined,
+ limit:15,
+ page:1,
+ order_type:undefined,
+ //新建标签区域是否显示 none 隐藏 block 显示
+ display:'none',
+ status:'open'
+ }
+ }
+
+ componentDidMount=()=>{
+ this.getList(1,this.state.status,'desc');
+ }
+
+
+
+ getList=(page,status,order_type)=>{
+ const { projectsId } = this.props.match.params;
+ const { limit } = this.state;
+ const url = `/projects/${projectsId}/versions.json`;
+ axios.get(url,{
+ params:{
+ projectsId,page,limit,status,order_type
+ }
+ }).then((result)=>{
+ if(result){
+ this.setState({
+ data:result.data
+ })
+ }
+ }).catch((error)=>{
+ console.log(error);
+ })
+ }
+
+ opneMilelist=()=>{
+ this.setState({
+ status:'open'
+ })
+ this.getList(1,'open','desc');
+
+ }
+ closeMilelist=()=>{
+ this.setState({
+ status:'closed'
+ })
+ this.getList(1,'closed','desc');
+
+ }
+
+ updatestatusemile=(status,arr)=>{
+ const { projectsId } = this.props.match.params;
+ const url = `/projects/${projectsId}/versions/${arr.id}/update_status`;
+ axios.post(url,{
+ project_id:projectsId,
+ id:arr.id,
+ status:status
+ }).then(result=>{
+ if(result){
+ this.getList(1,'open','desc')
+ }
+ }).catch(error=>{
+ console.log(error);
+ })
+ }
+
+ closemile=(arr)=>{
+ const { projectsId } = this.props.match.params;
+ const url = `/projects/${projectsId}/versions/${arr.id}`;
+ axios.delete(url,{ data: {
+ project_id: projectsId,
+ id: arr.id
+ }
+ }).then((result)=>{
+ if(result){
+ this.getList(1,this.state.status,'desc')
+ }
+ }).catch((error)=>{
+ console.log(error);
+ })
+ }
+
+ ChangePage=(page)=>{
+ this.setState({
+ page
+ })
+
+ this.getList(page);
+ }
+
+ // 排序
+ arrayList=(e)=>{
+ this.setState({
+ order_name:e.key,
+ order_type:e.item.props.value
+ })
+ this.getList(1,this.state.status,e.item.props.value);
+ }
+
+
+ //控制新建标签页是否显示
+ newshow=()=>{
+ this.setState({
+ display:'block'
+ });
+
+ };
+ newclose=()=>{
+ this.setState({
+ display:'none'
+ });
+ };
+
+
+ render(){
+ const { data , limit , page } = this.state;
+ const { projectsId } = this.props.match.params;
+ const menu = (
+
+ 到期日从近到远
+ 到期日从远到近
+ 完成度从低到高
+ 完成度从高到低
+ 工单从多到少
+ 工单从少到多
+
+ )
+
+ const Paginations = (
+
+ {
+ data && data.issue_tags_count > limit ?
+ :""
+ }
+
+ )
+
+ const renderList =()=>{
+ if(data && data.versions && data.versions.length>0 ){
+ return(
+
+ {
+ data.versions.map((item,key)=>{
+ return(
+
+
+
+
+
+
{item.effective_date}
+
+
{item.open_issues_count}个开启
+
+
{item.close_issues_count}个关闭
+
+
+
+
编辑
+
+
this.updatestatusemile('closed',item)}>关闭
+
+
this.closemile(item)} >删除
+
+
+
+
+
+ {item.description}
+
+
+
+ )
+ })
+ }
+
+ )
+ }else{
+ return(
+
+ )
+ }
+ }
+
+ return(
+
+
+
+
+ {/*
新建里程碑 */}
+
新的里程碑
+
+
+
+
+ 里程碑{ data && data.issue_tags_count }已创建
+
+
+
+
+ { data && data.open_count }开启中
+ { data && data.closed_count }已关闭
+
+
+
+ { renderList()}
+ { Paginations }
+
+
+ )
+ }
+}
+export default Milepost;
\ No newline at end of file
diff --git a/public/react/src/forge/Order/Nav.js b/public/react/src/forge/Order/Nav.js
index a0cea55bb..7d08f046a 100644
--- a/public/react/src/forge/Order/Nav.js
+++ b/public/react/src/forge/Order/Nav.js
@@ -7,7 +7,8 @@ class Nav extends Component{
return(
标签
- 里程碑
+ 里程碑
+
)
}
diff --git a/public/react/src/forge/Order/New.js b/public/react/src/forge/Order/New.js
index 199a1d253..9cc782413 100644
--- a/public/react/src/forge/Order/New.js
+++ b/public/react/src/forge/Order/New.js
@@ -19,12 +19,12 @@ class New extends Component{
branch_name:"",
issue_tag_ids:"",
fixed_version_id:"",
- tracker_id:"",
- issue_type:"",
- status_id:'',
+ tracker_id:"缺陷",
+ issue_type:"普通",
+ status_id:'新增',
assigned_to_id:"",
- priority_id:"",
- done_ratio:"",
+ priority_id:"正常",
+ done_ratio:"0%",
issue_chosen:undefined,
branches:undefined,
fileList:undefined
@@ -62,7 +62,7 @@ class New extends Component{
return(
list.map((item,key)=>{
return(
-
{item.name}
+
{item.name}
)
})
)
@@ -76,6 +76,22 @@ class New extends Component{
const { projectsId } = this.props.match.params;
const { fileList } = this.state;
const url = `/projects/${projectsId}/issues.json`;
+ if(values.status_id==="新增"){
+ values.status_id="1"
+ }
+ // if(values.issue_type==="普通"){
+ // values.issue_type="1"
+ // }
+ if(values.tracker_id==="缺陷"){
+ values.tracker_id="1"
+ }
+ if(values.priority_id==="正常"){
+ values.priority_id="2"
+ }
+ if(values.done_ratio==="0%"){
+ values.done_ratio="0"
+ }
+
axios.post(url,{
...values,
attachment_ids:fileList
@@ -87,6 +103,7 @@ class New extends Component{
}).catch(error=>{
console.log(error);
})
+
}
})
}
@@ -187,12 +204,11 @@ class New extends Component{
}],
})(
- 未选择完成状态
{ this.renderSelect(issue_chosen && issue_chosen.issue_status) }
)}
-
{getFieldDecorator('issue_type', {
@@ -200,12 +216,11 @@ class New extends Component{
required: true, message: '请选择类型'
}],
})(
-
- 未选择类型
+
{ this.renderSelect(issue_chosen && issue_chosen.issue_type) }
)}
-
+ */}
@@ -215,7 +230,6 @@ class New extends Component{
}],
})(
- 未选择分类
{ this.renderSelect(issue_chosen && issue_chosen.tracker) }
)}
@@ -224,7 +238,8 @@ class New extends Component{
label="指派成员"
>
{getFieldDecorator('assigned_to_id', {
- rules: [],
+ rules: [{
+ }],
})(
未指派成员
@@ -241,7 +256,6 @@ class New extends Component{
}],
})(
- 未选择优先度
{ this.renderSelect(issue_chosen && issue_chosen.priority) }
)}
@@ -255,7 +269,6 @@ class New extends Component{
}],
})(
- 未选择完成度
{ this.renderSelect(issue_chosen && issue_chosen.done_ratio) }
)}
diff --git a/public/react/src/forge/Order/Tags.js b/public/react/src/forge/Order/Tags.js
index a89694dcf..23cbe56ea 100644
--- a/public/react/src/forge/Order/Tags.js
+++ b/public/react/src/forge/Order/Tags.js
@@ -1,9 +1,10 @@
import React , {Component} from 'react';
-import { Dropdown , Icon , Menu , Pagination } from 'antd';
+import { Dropdown , Icon , Menu , Pagination, Modal,Input,Popconfirm,Form } from 'antd';
import { Link } from 'react-router-dom';
import Nav from './Nav';
import NoneData from '../../modules/courses/coursesPublic/NoneData';
-
+import { SketchPicker } from 'react-color'
+import reactCSS from 'reactcss'
import axios from 'axios';
class Tags extends Component{
constructor(props){
@@ -13,7 +14,24 @@ class Tags extends Component{
limit:15,
page:1,
order_name:undefined,
- order_type:undefined
+ order_type:undefined,
+ //新建标签区域是否显示 none 隐藏 block 显示
+ display:'none',
+ //调色盘颜色
+ displayColorPicker: false,
+ color: {
+ r: '241',
+ g: '112',
+ b: '19',
+ a: '1',
+ },
+ textcolor:'#F17013',
+ isShow:false,
+ newcolor:'',
+ name:'',
+ description:'',
+ id:'',
+ modelname:''
}
}
@@ -21,6 +39,7 @@ class Tags extends Component{
this.getList();
}
+
getList=(page,order_name,order_type)=>{
const { projectsId } = this.props.match.params;
const { limit } = this.state;
@@ -40,6 +59,29 @@ class Tags extends Component{
})
}
+ createtagpost=()=>{
+ this.props.form.validateFieldsAndScroll((err, values) => {
+ if(!err){
+ const { projectsId } = this.props.match.params;
+ const url = `/projects/${projectsId}/issue_tags`;
+ axios.post(url,{
+ ...values,
+ project_id:projectsId,
+ color:this.state.textcolor
+ }).then(result=>{
+ if(result){
+ this.setState({
+ display:'none'
+ });
+ this.getList()
+ }
+ }).catch(error=>{
+ console.log(error);
+ })
+ }
+ })
+ }
+
ChangePage=(page)=>{
this.setState({
page
@@ -58,9 +100,113 @@ class Tags extends Component{
this.getList(1,e.key,e.item.props.value);
}
+ handleClick = () => {
+ this.setState({ displayColorPicker: !this.state.displayColorPicker })
+ };
+
+ handleClose = () => {
+ this.setState({ displayColorPicker: false })
+ };
+
+ handleChange = (color) => {
+ this.setState({
+ color: color.rgb,
+ textcolor:color.hex,
+ newcolor:color.hex,
+ })
+ };
+
+
+
+ //控制新建标签页是否显示
+ newshow=()=>{
+ this.setState({
+ display:'block'
+ });
+
+ };
+ newclose=()=>{
+ this.setState({
+ display:'none'
+ });
+ };
+
+ handleok=()=>{
+ this.updatetag();
+ }
+ updatetag=()=>{
+ const { projectsId } = this.props.match.params;
+ let id=this.state.id;
+ const url = `/projects/${projectsId}/issue_tags/${id}.json`;
+ let name=this.state.name;
+ let description=this.state.description;
+ let modalcolor=this.state.newcolor
+ axios.put(url,{
+ project_id:projectsId,
+ id:id,
+ name:name,
+ description:description,
+ color:modalcolor
+ }).then((result)=>{
+ if(result){
+ this.setState({
+ isShow:false
+ });
+ this.getList()
+ }
+ }).catch((error)=>{
+ console.log(error);
+ })
+ }
+
+ deletetag=(id)=>{
+ const { projectsId } = this.props.match.params;
+ const url = `/projects/${projectsId}/issue_tags/${id}.json`;
+ axios.delete(url,{ data: {
+ project_id: projectsId,
+ id: id
+ }
+ }).then((result)=>{
+ if(result){
+ this.getList()
+ }
+ }).catch((error)=>{
+ console.log(error);
+ })
+ }
+
+ handleCancel=()=>{
+ this.setState({
+ isShow:false
+ });
+ }
+
+ changmodelname=(e)=>{
+ this.setState({
+ name:e.target.value
+ })
+ }
+ changdescription=(e)=>{
+ this.setState({
+ description:e.target.value
+ })
+ }
+
+ editshow=(arr)=>{
+ this.setState({
+ isShow:true,
+ newcolor:arr.color,
+ name:arr.name,
+ description:arr.description,
+ id:arr.id
+ });
+ };
+
render(){
const { data , limit , page } = this.state;
const { projectsId } = this.props.match.params;
+ const { getFieldDecorator } = this.props.form;
+
const menu = (
按创建时间降序排序
@@ -69,6 +215,46 @@ class Tags extends Component{
按issue个数升序排序
)
+ const styles = reactCSS({
+ 'default': {
+ color: {
+ width: '20px',
+ height: '20px',
+ borderRadius: '2px',
+ background: `rgba(${ this.state.color.r }, ${ this.state.color.g }, ${ this.state.color.b }, ${ this.state.color.a })`,
+ },
+ swatch: {
+ padding: '5px',
+ background: '#fff',
+ borderRadius: '1px',
+ width:'100px',
+ marginTop:'5px',
+ height:'28px',
+ boxShadow: '0 0 0 1px rgba(0,0,0,.1)',
+ display: 'flex',
+ cursor: 'pointer',
+ },
+ popover: {
+ position: 'absolute',
+ zIndex: '2',
+ },
+ cover: {
+ position: 'fixed',
+ top: '0px',
+ right: '0px',
+ bottom: '0px',
+ left: '0px',
+ },
+ modalcolor:{
+ width: '20px',
+ height: '20px',
+ borderRadius: '2px',
+ background: this.state.newcolor,
+ }
+ },
+ });
+
+
const Paginations = (
{
@@ -94,6 +280,12 @@ class Tags extends Component{
{item.description}
{item.issues_count}个开启的工单
+
)
})
@@ -106,12 +298,64 @@ class Tags extends Component{
)
}
}
+
return(
-
新建标签
+
创建标签
+ {/*
新建标签 */}
+
+
共{ data && data.issue_tags_count }个标签
@@ -123,12 +367,39 @@ class Tags extends Component{
-
{ renderList() }
{ Paginations }
+
+
+
+
+
+
+
+
{this.state.newcolor}
+
+
+ { this.state.displayColorPicker ?
:
+ null }
+
+
+
+
+
)
}
}
-export default Tags;
\ No newline at end of file
+const WrappedTags = Form.create({ name: 'tageFrom' })(Tags);
+export default WrappedTags;
\ No newline at end of file
diff --git a/public/react/src/forge/Order/UpdateMilepost.js b/public/react/src/forge/Order/UpdateMilepost.js
new file mode 100644
index 000000000..c5db94a63
--- /dev/null
+++ b/public/react/src/forge/Order/UpdateMilepost.js
@@ -0,0 +1,231 @@
+import React , {Component} from 'react';
+import { Link } from 'react-router-dom';
+import { Calendar, Select, Radio, Col, Row,Divider,Input,Form} from 'antd';
+import Nav from './Nav';
+import NoneData from '../../modules/courses/coursesPublic/NoneData';
+import reactCSS from 'reactcss'
+import axios from 'axios';
+import moment from 'moment'
+
+
+const TextArea = Input.TextArea;
+const { Group, Button } = Radio;
+class UpdateMilepost extends Component{
+ constructor(props){
+ super(props);
+ this.state={
+ data:undefined,
+ value: moment('2017-01-25'),
+ selectedValue: moment('2020-2-12'),
+ }
+ }
+
+ componentDidMount=()=>{
+ this.getmeil();
+ }
+
+ onPanelChange=(time, mode)=>{
+ this.setState({
+ value:time
+ });
+ }
+
+ onSelect=(time)=>{
+ this.setState({
+ value:time,
+ selectedValue: time,
+ });
+ }
+
+ getmeil=()=>{
+ const { projectsId } = this.props.match.params;
+ const { meilid } = this.props.match.params;
+ const url = `/projects/${projectsId}/versions/${meilid}/edit.json`;
+ axios.get(url,{
+ params:{
+ projectsId,meilid
+ }
+ }).then((result)=>{
+ if(result){
+ this.setState({
+ data:result.data,
+ selectedValue:moment(result.data.effective_date)
+ })
+ this.props.form.setFieldsValue({
+ name:result.data.name,
+ description:result.data.description
+ });
+
+ }
+ }).catch((error)=>{
+ console.log(error);
+ })
+
+
+
+ }
+
+ submit=()=>{
+ this.props.form.validateFieldsAndScroll((err, values) => {
+ if(!err){
+ const { projectsId } = this.props.match.params;
+ const { meilid } = this.props.match.params;
+ const url = `/projects/${projectsId}/versions/${meilid}.json`;
+ let time=this.state.selectedValue.format("YYYY-MM-DD")
+ axios.put(url,{
+ ...values,
+ project_id:projectsId,
+ id:meilid,
+ effective_date:time,
+ status:'open'
+ }).then(result=>{
+
+
+ }).catch(error=>{
+ console.log(error);
+ })
+ }
+ })
+ }
+
+ render(){
+ const { getFieldDecorator } = this.props.form;
+ const { data } = this.state;
+
+ const { projectsId } = this.props.match.params;
+ return(
+
+ )
+ }
+}
+const WrappedUpdatemile = Form.create({ name: 'UpdatemileFrom' })(UpdateMilepost);
+
+export default WrappedUpdatemile;
\ No newline at end of file
diff --git a/public/react/src/forge/Order/newMilepost.js b/public/react/src/forge/Order/newMilepost.js
new file mode 100644
index 000000000..cf2bfefb8
--- /dev/null
+++ b/public/react/src/forge/Order/newMilepost.js
@@ -0,0 +1,199 @@
+import React , {Component} from 'react';
+import { Link } from 'react-router-dom';
+import { Calendar, Select, Radio, Col, Row,Divider,Input,Form} from 'antd';
+import Nav from './Nav';
+import NoneData from '../../modules/courses/coursesPublic/NoneData';
+import reactCSS from 'reactcss'
+import axios from 'axios';
+import moment from 'moment'
+
+
+const TextArea = Input.TextArea;
+const { Group, Button } = Radio;
+class NewMilepost extends Component{
+ constructor(props){
+ super(props);
+ this.state={
+ data:undefined,
+ value: moment('2017-01-25'),
+ selectedValue: moment('2020-2-12'),
+ }
+ }
+
+ componentDidMount=()=>{
+
+ }
+
+ onPanelChange=(time, mode)=>{
+ this.setState({
+ value:time
+ });
+ }
+
+ onSelect=(time)=>{
+ this.setState({
+ value:time,
+ selectedValue: time,
+ });
+ }
+
+ submit=()=>{
+ this.props.form.validateFieldsAndScroll((err, values) => {
+ if(!err){
+ const { projectsId } = this.props.match.params;
+ const url = `/projects/${projectsId}/versions`;
+ let time=this.state.selectedValue.format("YYYY-MM-DD")
+ axios.post(url,{
+ ...values,
+ project_id:projectsId,
+ effective_date:time,
+ status:'open'
+ }).then(result=>{
+
+
+ }).catch(error=>{
+ console.log(error);
+ })
+ }
+ })
+ }
+
+ render(){
+ const { getFieldDecorator } = this.props.form;
+ const { projectsId } = this.props.match.params;
+ return(
+
+
+
+ 新的里程碑
+ 里程碑组织工单,合并请求和跟踪进度.
+
+
+
+ 标题
+
+
+ {getFieldDecorator('name', {
+ rules: [{
+ required: true, message: '请输入标题'
+ }],
+ })(
+
+ )}
+
+
+ 描述
+
+ {getFieldDecorator('description', {
+ rules: [{
+ required: true, message: '请输入描述内容'
+ }],
+ })(
+
+
+ )}
+
+
+
+ 截止日期(可选)
清除
+
+
+
+
+
{
+ const start = 0;
+ const end = 12;
+ const monthOptions = [];
+ const current = value.clone();
+ const localeData = value.localeData();
+ const months = [];
+ for (let i = 0; i < 12; i++) {
+ current.month(i);
+ months.push(localeData.monthsShort(current));
+ }
+
+ for (let index = start; index < end; index++) {
+ monthOptions.push(
+
+ {months[index]}
+ ,
+ );
+ }
+ const month = value.month();
+
+ const year = value.year();
+ const options = [];
+ for (let i = year - 10; i < year + 10; i += 1) {
+ options.push(
+
+ {i}
+ ,
+ );
+ }
+ return (
+
+
Custom header
+
+
+ onTypeChange(e.target.value)} value={type}>
+ Month
+ Year
+
+
+
+ {
+ const now = value.clone().year(newYear);
+ onChange(now);
+ }}
+ value={String(year)}
+ >
+ {options}
+
+
+
+ {
+ const newValue = value.clone();
+ newValue.month(parseInt(selectedMonth, 10));
+ onChange(newValue);
+ }}
+ >
+ {monthOptions}
+
+
+
+
+ );
+ }}
+ onPanelChange={this.onPanelChange}
+ onSelect={this.onSelect}
+ />
+
+
+
+
+
+ 创建里程碑
+
+
+
+ )
+ }
+}
+const WrappedNewMile = Form.create({ name: 'NewMilepostFrom' })(NewMilepost);
+
+export default WrappedNewMile;
\ No newline at end of file
diff --git a/public/react/src/forge/Order/order.css b/public/react/src/forge/Order/order.css
index 2df5848e7..5c0a1678a 100644
--- a/public/react/src/forge/Order/order.css
+++ b/public/react/src/forge/Order/order.css
@@ -8,7 +8,58 @@
}
.topWrapper_nav{
display: flex;
+
+}
+.detail_p{
+ display: flex;
+ width: 80%;
+ padding-left: 15px;
+ margin: auto;
+}
+.commit_p{
+ font-size: 12px;
+ padding-top: 10px;
+ padding-left: 5px;
}
+
+.ul_width{
+ width: 100%;
+}
+.Closeor_btn{
+ border:1px solid red;
+ color: red;
+ height: 32px;
+ text-align: center;
+ border-radius:4px;
+ padding:0px 12px;
+ margin-right: 15px;
+ margin-right: 15px;
+ text-align: center;
+ line-height: 32px;
+
+}
+.rectangle {
+ width: 8px;
+ height: 8px;
+ border-radius: 100%;
+ margin-top: 15px;
+ margin-left: -4px;
+ margin-bottom: 10px;
+ background: green;
+ }
+ .order_line{
+ display: flex;
+ height: 32px;
+ margin: auto;
+ border-left:1px solid green;
+ }
+ .comment_img{
+ height: 25px;
+ width: 25px;
+ margin-top: 5px;
+ border-radius: 100%;
+ }
+
.topWrapper_nav a,.topWrapper_nav span{
border:1px solid #f4f4f4;
border-radius: 5px 0px 0px 5px;
@@ -150,6 +201,75 @@
margin-bottom: 0px;
}
+ /*编辑工单*/
+ .editingsheet{
+ background: #ffffff;
+ color: #21ba45!important;
+ padding:0px 12px;
+ text-align: center;
+ height: 32px;
+ line-height: 32px;
+}
+
+.commenttitle{
+ color: #21ba45!important;
+}
+
+.topWrapper_detali{
+ display: flex;
+ height: 35px;
+ background-color: #4CACFF;
+}
+.towwrapper_img_detali{
+ display: flex;
+ padding-left: 80px;
+ margin-left: 80px;
+ margin-right: 20px;
+ border: 1px solid #4CACFF;
+}
+.div_line{
+ width: 100%;
+ border: 1px solid #4CACFF;
+
+}
+.list_img{
+ height: 145px;
+ padding: 15px;
+ width: 145px;
+}
+
+.detail_context {
+ flex: 1;
+ border: 1px solid #dededf;
+ margin-left: 15px;
+ padding-top: 0px;
+ padding-left: 0px;
+ margin-right: 15px;
+ position: relative;
+ background: #FFFFFF;
+}
+.detail_context:before {
+ position: absolute;
+ content: "";
+ height: 0;
+ width: 0;
+ border: solid transparent;
+ border-right-color: #dededf;
+ border-width: 9px;
+ top: 12px;
+ right: 100%;
+}
+.detail_context::after {
+ position: absolute;
+ content: "";
+ height: 0;
+ width: 0;
+ border: solid transparent;
+ border-right-color: #fff;
+ border-width: 7px;
+ top: 14px;
+ right: 100%;
+}
/* 工单标签列表 */
.tagList > div{
border-bottom: 1px dashed #f4f4f4;
@@ -157,6 +277,17 @@
justify-content: space-around;
padding:15px 0px;
}
+.divwidth{
+ width: 80%;
+}
+.listTowItems{
+ width: 80%;
+ padding-left: 80px;
+}
+.detail_ptitlecount{
+ padding: 15px;
+}
+
.tagList > div:last-child{
border-bottom: none;
}
@@ -173,6 +304,45 @@
border-radius: 4px;
margin-right: 5px;
}
+
+/*里程碑*/
+.milepostdiv{
+ display: flex;
+}
+.milepostwidth{
+ display: flex;
+ width: 60%;
+}
+.mileposwidth{
+ background: #21ba45;
+ border-radius: 4px;
+ width: 40%;
+}
+.milepostrighe{
+ display: flex;
+ width: 85%;
+}
+.milepostleft{
+ text-align: right;
+ display: flex;
+ justify-content: right;
+ width: 15%;
+}
+.textwidth{
+ display: flex;
+ width: 100%;
+}
+.newmilepostleft{
+ padding: 15px;
+ margin-right: 50px;
+ width: 60%;
+}
+.newmilepostrighe{
+ margin-left: 50px;
+ padding: 15px;
+
+ width: 30%;
+}
/* 工单详情 */
.detailContent{
padding:15px 0px;
@@ -187,12 +357,40 @@
height: 30px;
line-height:30px;
}
+.inptwidth{
+ width: 20%;
+}
+.inputcount{
+ width: 40%;
+}
+
+.tagdiv{
+ padding: 15px;
+ height: 70px;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: space-between;
+ border: 1px solid #EEEEEE;
+ flex-wrap: wrap;
+}
+
+.dialogdiv{
+ padding: 5px;
+ height: 45px;
+ box-sizing: border-box;
+ display: flex;
+ justify-content: space-between;
+ flex-wrap: wrap;
+}
+
.DetailRight > p >span:nth-child(1){
min-width: 90px;
margin-right: 15px;
text-align: right;
}
+
+
@media screen and (max-width: 700px){
.topWrapper_select li{
width:auto;
diff --git a/public/react/src/forge/Version/VersionItem.js b/public/react/src/forge/Version/VersionItem.js
new file mode 100644
index 000000000..d21a9fa8c
--- /dev/null
+++ b/public/react/src/forge/Version/VersionItem.js
@@ -0,0 +1,14 @@
+import React , { Component } from 'react';
+import { Link } from 'react-router-dom';
+
+class VersionItem extends Component{
+ render(){
+ return(
+
+ 1111111111
+
+ )
+ }
+}
+
+export default VersionItem;
\ No newline at end of file
diff --git a/public/react/src/forge/Version/version.js b/public/react/src/forge/Version/version.js
new file mode 100644
index 000000000..3318f4449
--- /dev/null
+++ b/public/react/src/forge/Version/version.js
@@ -0,0 +1,187 @@
+import React , { Component } from "react";
+import {Link} from 'react-router-dom';
+import { Input ,Dropdown , Menu , Icon , Pagination , Spin } from 'antd';
+import NoneData from '../../modules/courses/coursesPublic/NoneData';
+import Nav from '../Order/Nav';
+import VersionItem from './VersionItem';
+
+
+
+import axios from 'axios';
+
+const Search = Input.Search;
+/**
+ * issue_chosen:下拉的筛选列表,
+ * data:列表接口返回的所有数据,
+ * issues:列表数组,
+ * isSpin:加载中,
+ * search:搜索关键字,
+ * author_id:发布者id,
+ * assigned_to_id:指派给。。。的id,
+ * limit:每页条数,
+ * page:当前页,
+ * search_count:列表总条数
+ * issue_type:搜索条件
+ */
+class version extends Component{
+ constructor(props){
+ super(props);
+ this.state={
+ issue_chosen:undefined,
+ data:undefined,
+ issues:undefined,
+ isSpin:false,
+ search:undefined,
+ author_id:undefined,
+ assigned_to_id:undefined,
+ limit:15,
+ page:1,
+ search_count:undefined,
+ issue_type:undefined
+ }
+ }
+
+ componentDidMount=()=>{
+ this.getSelectList();
+ this.getIssueList();
+ }
+
+ getSelectList=()=>{
+ 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
+ })
+ }
+ }).catch((error)=>{
+ console.log(error);
+ })
+ }
+
+ // 获取列表数据
+ getIssueList=(page,limit,search,author_id,assigned_to_id,id,value)=>{
+ const { projectsId } = this.props.match.params;
+
+ const url = `/projects/${projectsId}/issues.json`;
+ axios.get(url,{
+ params:{
+ page,limit,search,author_id,assigned_to_id,
+ [id]:value
+ }
+ }).then((result)=>{
+ if(result){
+ this.setState({
+ data:result.data,
+ issues:result.data.issues,
+ search_count:result.data.search_count,
+ isSpin:false
+ })
+ }
+ }).catch((error)=>{
+ console.log(error);
+ })
+ }
+
+ getOption=(e,id)=>{
+ this.setState({
+ [id]:e.key
+ })
+ const { page,limit,search,author_id,assigned_to_id } = this.state;
+ this.getIssueList(page,limit,search,author_id,assigned_to_id,id,e.key);
+ }
+
+ renderMenu =(array,name,id)=>{
+ return(
+
+ this.getOption(e,id)}>{name}
+ {
+ array && array.length > 0 && array.map((item,key)=>{
+ return(
+ this.getOption(e,id)}>{item.name}
+ )
+ })
+ }
+
+ )
+ }
+
+ // 翻页
+ ChangePage=(page)=>{
+ this.setState({
+ page,
+ isSpin:true
+ })
+ const {limit,search} = this.state;
+ this.getIssueList(page,limit,search);
+ }
+
+ // 搜索
+ searchFunc=(value)=>{
+ this.setState({
+ search:value,
+ isSpin:true
+ })
+ const {page,limit} = this.state;
+ this.getIssueList(page,limit,value);
+ }
+
+ // 筛选:全部、指派给我、由我创建
+ ChangeAssign=(type)=>{
+ const { limit, search} = this.state;
+ this.setState({
+ isSpin:true
+ })
+ if(type){
+ const { current_user } = this.props;
+ if(type===1){
+ this.setState({
+ page:1,
+ author_id:current_user.user_id,
+ assigned_to_id:undefined
+ })
+ this.getIssueList(1,limit,search,current_user.user_id,undefined);
+ }else{
+ this.setState({
+ page:1,
+ author_id:undefined,
+ assigned_to_id:current_user.user_id
+ })
+ this.getIssueList(1,limit,search,undefined,current_user.user_id);
+ }
+ }else{
+ this.setState({
+ page:1,
+ author_id:undefined,
+ assigned_to_id:undefined
+ })
+ this.getIssueList(1,limit,search,undefined,undefined);
+ }
+ }
+
+ render(){
+
+ const { projectsId } = this.props.match.params;
+
+ return(
+
+
+
版本发布
+ 发布新版
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ {VersionItem}
+
+
+
+ )
+ }
+}
+export default version;
\ No newline at end of file