526 lines
26 KiB
JavaScript
526 lines
26 KiB
JavaScript
import React from 'react';
|
||
import Item from './Item';
|
||
import { Input, Tooltip, message, Dropdown, Menu, Row, Col } from 'antd';
|
||
import { observer } from 'mobx-react';
|
||
import { toJS } from 'mobx';
|
||
import { WeaInput, WeaLocaleProvider, WeaProgress, WeaError, WeaBrowser, WeaRangePicker, WeaTextarea } from 'ecCom';
|
||
const getLabel = WeaLocaleProvider.getLabel;
|
||
import $ from "jquery";
|
||
|
||
@observer
|
||
export default class Column extends React.Component {
|
||
isShow = false;//是否依然显示
|
||
constructor(props) {
|
||
super(props);
|
||
const { data } = props;
|
||
this.state = {
|
||
visible: false,
|
||
btnVisible: false,
|
||
changeGroupVisible: false,
|
||
isEdit: false,
|
||
title: data.title,
|
||
loading: false,
|
||
groupName: "",
|
||
baseGroupName:"",
|
||
editGroupNameVisible: false,
|
||
taskInfo: {
|
||
taskName: "",
|
||
hrmid: "",
|
||
startDate: this.getNowFormatDate(),
|
||
endDate: this.getNowFormatDate(),
|
||
hrmname: ""
|
||
},
|
||
userInfo: {
|
||
userid: "",
|
||
username: "",
|
||
usericons: ""
|
||
},
|
||
groupName: "",
|
||
baseGroupName:"",
|
||
editGroupNameVisible: false, };
|
||
}
|
||
|
||
componentDidMount() {
|
||
//新增Column元素,当前元素渲染到页面上后将元素添加到muuri
|
||
const { userInfo, data, boardStore } = this.props;
|
||
if (data.id.endsWith('_new')) {
|
||
const element = document.getElementById('column_' + data.id);
|
||
let column = boardStore.boardGrid.add([element], { index: boardStore.boardGrid._items.length - 2 });
|
||
boardStore.initItem(column[0]._element.querySelector('.board-column-content'));
|
||
}
|
||
this.setState({
|
||
taskInfo: {
|
||
taskName: "",
|
||
hrmid: userInfo.userid,
|
||
hrmname: userInfo.username,
|
||
startDate: this.getNowFormatDate(),
|
||
endDate:this.getNowFormatDate(),
|
||
},
|
||
userInfo: {
|
||
userid: userInfo.userid,
|
||
username: userInfo.username,
|
||
usericons: userInfo.usericons
|
||
},
|
||
groupName: data.title,
|
||
editGroupNameVisible: false,
|
||
});
|
||
|
||
}
|
||
|
||
|
||
componentDidUpdate() {
|
||
if(this.refs.editTitle){
|
||
this.refs.editTitle['refs'].inputNormal.refs.input.refs.input.focus();
|
||
}
|
||
}
|
||
|
||
render() {
|
||
this.isShow = false;
|
||
const { data, boardStore } = this.props;
|
||
const { canEditBoard, canAddTask, searchType, showLandMark } = boardStore;
|
||
|
||
const menu = (
|
||
<Menu ecId={`${this && this.props && this.props.ecId || ''}_Menu@gwmzn7`}>
|
||
<Menu.Item ecId={`${this && this.props && this.props.ecId || ''}_MenuItem@ce00ju`} key="0">
|
||
<span onClick={() => this.editGropName(true)}>{getLabel('387705', "修改阶段名称")}</span>
|
||
</Menu.Item>
|
||
<Menu.Divider ecId={`${this && this.props && this.props.ecId || ''}_MenuDivider@lwdj4u`} />
|
||
<Menu.Item ecId={`${this && this.props && this.props.ecId || ''}_MenuItem@6ku9t5`} key="1">
|
||
<span onClick={() => this.props.delGrop(this.props.groupid)}>{getLabel('387706', "删除阶段")}</span>
|
||
</Menu.Item>
|
||
</Menu>
|
||
);
|
||
if(searchType=="stageid"){
|
||
return <div id={"column_" + data.id} className="board-column muuri-item muuri-item-shown">
|
||
<div className="board-column-header" >
|
||
<div className="board-column-header-wrapper">
|
||
<div className="kanban-group-head-title" onDoubleClick={() => { canEditBoard&&this.editGropName(true) }}>
|
||
{!this.state.editGroupNameVisible && <span style={{ marginTop: '5px' }}>{data.title}</span>}
|
||
{!this.state.editGroupNameVisible && <span style={{ marginTop: '5px', marginLeft: "10px", color: "#22d7bb" }}>{this.getCountNum().finishNum}</span>}
|
||
{!this.state.editGroupNameVisible && <span style={{ marginTop: '5px', color: "#BDC0CB" }}>/{this.getCountNum().countNum}</span>}
|
||
{
|
||
this.state.editGroupNameVisible &&
|
||
<WeaInput ecId={`${this && this.props && this.props.ecId || ''}_WeaInput@kabdxi`}
|
||
ref="editTitle"
|
||
className="updateStageName"
|
||
style={{ top: '6px' }}
|
||
value={this.state.groupName}
|
||
onChange={value => {
|
||
this.setState({ groupName: value })
|
||
}}
|
||
onBlur={() => { this.editGropName(false) }}
|
||
/>
|
||
}
|
||
</div>
|
||
<div className="kanban-group-head-extra" style={{ display: canEditBoard ? this.state.editGroupNameVisible ? "none" : "" : "none" }}>
|
||
<Dropdown ecId={`${this && this.props && this.props.ecId || ''}_Dropdown@ljd5mm`} overlay={menu}>
|
||
<span className="icon-coms-List column-header-menu"></span>
|
||
</Dropdown>
|
||
</div>
|
||
<WeaProgress ecId={`${this && this.props && this.props.ecId || ''}_WeaProgress@co1pb4`} key={boardStore.percentStaus} percent={this.getCountNum().percent} showInfo={false} status={"active"} strokeWidth={6} strokeColor={"#22d7bb"} />
|
||
</div>
|
||
</div>
|
||
<div id={"board-column-content-scroll" + data.id} className={"board-column-content-scroll"} style={{ 'maxHeight': (boardStore.windowHeight - 210 - 146) + "px", display: 'block', overflow: 'auto' }}>
|
||
<div id={"column_content_" + data.id} className="board-column-content muuri" style={{ borderRadius: canAddTask ? "" : "0 0 8px 8px" }}>
|
||
{data.items && data.items.map(item => {
|
||
return <Item ecId={`${this && this.props && this.props.ecId || ''}_Item@mfersn@${item.id}`}
|
||
data={item}
|
||
managerid={toJS(item.hrmid)}
|
||
managericon={toJS(item.hrmidicon)}
|
||
managername={toJS(item.hrmidname)}
|
||
islandmark={item.islandmark}
|
||
description={item.overstr}
|
||
colors={item.finishcolor}
|
||
allnum={item.allnum}
|
||
prefix={item.prefix}
|
||
showLandMark={showLandMark}
|
||
finishnum={item.finishnum}
|
||
canAddTask={canAddTask}
|
||
canEditBoard={canEditBoard}
|
||
status={item.status}
|
||
setLandMark={(id, value) => { boardStore.setLandMark(id, value) }}
|
||
onTaskClick={(value) => { boardStore.showSlideModal(true, value) }}
|
||
finish={item.finish}
|
||
key={boardStore.timestamp + "" + item.id}
|
||
refreshItems={boardStore.refreshItems}
|
||
/>
|
||
})}
|
||
</div>
|
||
<div className="column_footer_card">
|
||
<div className="footer-card" id={"footer-card-" + data.id} style={{ display: "none" }}>
|
||
<Row ecId={`${this && this.props && this.props.ecId || ''}_Row@kdwhei`} style={{ lineHeight: "20px" }}>
|
||
|
||
<Col ecId={`${this && this.props && this.props.ecId || ''}_Col@alafv8`} span={24}>
|
||
{/* <div className={this.state.taskInfo.taskName ? "" : "required"} > */}
|
||
<WeaError ecId={`${this && this.props && this.props.ecId || ''}_WeaError@bfohxz`} tipPosition='bottom' ref='taskname' error={getLabel('387696', "任务名称未填写!")} style={{ width: "100%" }}>
|
||
<WeaTextarea ecId={`${this && this.props && this.props.ecId || ''}_WeaTextarea@i5u0mg`}
|
||
style={{ width: "100%", height: "50px" }}
|
||
// ref={"area_"+this.props.groupid}
|
||
ref={(input) => { this.textInput = input; }}
|
||
type="textarea"
|
||
// disabled={disabled}
|
||
autofocus="autofocus"
|
||
autosize={{ minRows: "1", maxRows: "1" }}
|
||
value={this.state.taskInfo.taskName}
|
||
id={"area_" + this.props.groupid}
|
||
onChange={(v) => this.setTaskValue("subject", v)}
|
||
// onBlur={()=>{ this.showAddComs() }}
|
||
placeholder={getLabel('1352', "任务名称")}
|
||
/>
|
||
</WeaError>
|
||
{/* </div> */}
|
||
</Col>
|
||
</Row>
|
||
<Row ecId={`${this && this.props && this.props.ecId || ''}_Row@jmg1b1`} style={{ lineHeight: "20px", padding: "6px 0px 0px" }}>
|
||
|
||
<WeaError ecId={`${this && this.props && this.props.ecId || ''}_WeaError@mkmbka`} tipPosition='bottom'
|
||
ref='taskhrm'
|
||
error={getLabel('387699', "任务负责人未选择!")}
|
||
style={{ width: "100%" }}
|
||
>
|
||
<Col ecId={`${this && this.props && this.props.ecId || ''}_Col@odf9vw`} span={24}>
|
||
<div className="kanban-group-manager managericons" >
|
||
<Tooltip ecId={`${this && this.props && this.props.ecId || ''}_Tooltip@48nbqo`} placement="left" title={this.props.username}>
|
||
{/* <a href={'javaScript:openhrm(' + this.props.userid + ');'} onClick={e => window.pointerXY(e)} >
|
||
<img src={this.props.usericons} className="kanban-group-manager-img" />
|
||
</a> */}
|
||
{/* <div className={this.state.taskInfo.hrmid ? "" : "required"} > */}
|
||
|
||
<WeaBrowser ecId={`${this && this.props && this.props.ecId || ''}_WeaBrowser@w6h0u1`}
|
||
type={17}
|
||
// customized
|
||
key={this.state.taskInfo.hrmname}
|
||
replaceDatas={[{ id: this.state.taskInfo.hrmid, name: this.state.taskInfo.hrmname }]}
|
||
textDecoration={true}
|
||
isSingle={false}
|
||
onChange={(ids, names, datas) => this.setTaskValue("hrmid", { hrmid: ids, hrmname: names })}
|
||
placeholder={getLabel('15285', '任务负责人')}
|
||
>
|
||
{/* <Tooltip placement="bottom" title={this.state.taskInfo.hrmname == "" ? "请选择任务负责人" : this.state.taskInfo.hrmname}>
|
||
<img src={"/messager/images/icon_w_wev8.jpg"} className="kanban-group-manager-img" />
|
||
</Tooltip> */}
|
||
</WeaBrowser>
|
||
{/* </div> */}
|
||
</Tooltip>
|
||
</div>
|
||
{/* <div style={{marginLeft:"50px"}}>{this.state.taskInfo.hrmname}</div> */}
|
||
</Col>
|
||
</WeaError>
|
||
</Row>
|
||
<Row ecId={`${this && this.props && this.props.ecId || ''}_Row@yfpvul`} style={{ lineHeight: "20px" }}>
|
||
|
||
<WeaError ecId={`${this && this.props && this.props.ecId || ''}_WeaError@le2wgv`} tipPosition='bottom'
|
||
ref='taskstart'
|
||
error={getLabel('503588', '任务开始结束时间未选择!')}
|
||
style={{ width: "100%" }}>
|
||
<Col ecId={`${this && this.props && this.props.ecId || ''}_Col@b56zyy`} span={24}>
|
||
<div className="content-landmark" >
|
||
{/* <WeaRangePicker
|
||
value={[this.state.taskInfo.startDate, this.state.taskInfo.endDate]}
|
||
onChange={v => this.setTaskValue("startendDate",v)}
|
||
/> */}
|
||
|
||
<WeaRangePicker ecId={`${this && this.props && this.props.ecId || ''}_WeaRangePicker@ij11a9`}
|
||
viewAttr={2}
|
||
value={[this.state.taskInfo.startDate, this.state.taskInfo.endDate]}
|
||
onChange={(datas) => { this.setTaskValue("startAndEndDate", datas) }}
|
||
/>
|
||
|
||
</div>
|
||
</Col>
|
||
</WeaError>
|
||
{/* <WeaError tipPosition='bottom'
|
||
ref='taskend'
|
||
error={getLabel('387698', "任务结束时间未选择!")}
|
||
style={{width:"50%"}}>
|
||
<Col span={24}>
|
||
<div className="content-landmark" >
|
||
{/* <WeaRangePicker
|
||
value={[this.state.taskInfo.startDate, this.state.taskInfo.endDate]}
|
||
onChange={v => this.setTaskValue("startendDate",v)}
|
||
/>
|
||
<WeaDatePicker
|
||
noInput
|
||
value={this.state.taskInfo.endDate}
|
||
onChange={v => this.setTaskValue("endDate", v)}
|
||
key={this.state.taskInfo.endDate}
|
||
/>
|
||
</div>
|
||
</Col>
|
||
</WeaError> */}
|
||
</Row>
|
||
|
||
|
||
<div className="btnBottomSubmit" onClick={() => { this.showAddComs() }} >{getLabel('33703', "确认")}</div>
|
||
<span className="btnBottomCancel" onClick={() => { this.closeAddComs() }} >{getLabel('31129', "取消")}</span>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{canAddTask && <div className="column_footer" style={{ display: this.state.visible ? "none" : "" }}>
|
||
{/* <div className="btnBottomNew" onClick={() => { this.showAddComs() }} >+{getLabel('84046', "新任务")}</div> */}
|
||
|
||
<span class="btnBottomNew" onClick={() => { this.showAddComs() }}>+{getLabel('15266', '新建任务')}</span>
|
||
{/* <button class="btn btn-default btnBottomNew btn-lg" onClick={() => { this.showAddComs() }}>新 建 任 务</button> */}
|
||
|
||
</div>}
|
||
</div>
|
||
}else{
|
||
return <div id={"column_" + data.id} className="board-column muuri-item muuri-item-shown">
|
||
<div className="board-column-header" >
|
||
<div className="board-column-header-wrapper">
|
||
<div className="kanban-group-head-title">
|
||
{!this.state.editGroupNameVisible && <span style={{ marginTop: '5px' }}>{data.title}</span>}
|
||
{!this.state.editGroupNameVisible && <span style={{ marginTop: '5px', marginLeft: "10px", color: "#22d7bb" }}>{this.getCountNum().finishNum}</span>}
|
||
{!this.state.editGroupNameVisible && <span style={{ marginTop: '5px', color: "#BDC0CB" }}>/{this.getCountNum().countNum}</span>}
|
||
|
||
</div>
|
||
<WeaProgress ecId={`${this && this.props && this.props.ecId || ''}_WeaProgress@ag935p`} key={boardStore.percentStaus} percent={this.getCountNum().percent} showInfo={false} status={"active"} strokeWidth={6} strokeColor={"#22d7bb"} />
|
||
</div>
|
||
</div>
|
||
<div id={"board-column-content-scroll" + data.id} className={"board-column-content-scroll"} style={{ 'maxHeight': (boardStore.windowHeight - 210 - 146) + "px", display: 'block', overflow: 'auto' }}>
|
||
<div id={"column_content_" + data.id} className="board-column-content muuri" style={{ borderRadius: canAddTask ? "" : "0 0 8px 8px" }}>
|
||
{data.items && data.items.map(item => {
|
||
return <Item ecId={`${this && this.props && this.props.ecId || ''}_Item@tnz7p5@${item.id}`}
|
||
searchType={boardStore.searchType}
|
||
data={item}
|
||
managerid={toJS(item.hrmid)}
|
||
managericon={toJS(item.hrmidicon)}
|
||
managername={toJS(item.hrmidname)}
|
||
islandmark={item.islandmark}
|
||
description={item.overstr}
|
||
colors={item.finishcolor}
|
||
allnum={item.allnum}
|
||
prefix={item.prefix}
|
||
finishnum={item.finishnum}
|
||
canAddTask={canAddTask}
|
||
canEditBoard={canEditBoard}
|
||
status={item.status}
|
||
setLandMark={(id, value) => { boardStore.setLandMark(id, value) }}
|
||
onTaskClick={(value) => { boardStore.showSlideModal(true, value) }}
|
||
finish={item.finish}
|
||
key={boardStore.timestamp + "" + item.id}
|
||
refreshItems={boardStore.refreshItems}
|
||
/>
|
||
})}
|
||
</div>
|
||
|
||
</div>
|
||
<div className="column_footer" >
|
||
|
||
|
||
</div>
|
||
</div>
|
||
}
|
||
|
||
}
|
||
|
||
editGropName = (visible) => {
|
||
if (!visible) {
|
||
if (!this.state.groupName) {
|
||
message.error("阶段名称必填!");
|
||
} else {
|
||
if(this.state.groupName !== this.state.baseGroupName){
|
||
const repeat = this.checkGroupRepeat(this.state.groupName, this.props.groupid);
|
||
if (repeat) {
|
||
this.props.saveGroupName(this.state.groupName, this.props.groupid);
|
||
this.setState({ editGroupNameVisible: visible });
|
||
} else {
|
||
message.error(getLabel('387703',"阶段名称重复!"));
|
||
}
|
||
}else{
|
||
this.setState({ editGroupNameVisible: visible });
|
||
}
|
||
}
|
||
} else {
|
||
this.setState({ editGroupNameVisible: visible });
|
||
}
|
||
|
||
}
|
||
|
||
getFinishNum = () => {
|
||
const { data, boardStore } = this.props;
|
||
let nums = 0;
|
||
data.items && data.items.map(item=>{
|
||
if(item.finish == 100){
|
||
nums ++;
|
||
}
|
||
})
|
||
// console.log(nums);
|
||
return nums ;
|
||
}
|
||
|
||
checkGroupRepeat = (name, id) => {
|
||
let checked = true;
|
||
const stages = toJS(this.props.boardStore.columns);
|
||
stages.map(item => {
|
||
if (item.id !== id && item.title == name) {
|
||
checked = false;
|
||
}
|
||
});
|
||
return checked;
|
||
}
|
||
|
||
|
||
getNowFormatDate() {
|
||
var date = new Date();
|
||
var seperator1 = "-";
|
||
var year = date.getFullYear();
|
||
var month = date.getMonth() + 1;
|
||
var strDate = date.getDate();
|
||
if (month >= 1 && month <= 9) {
|
||
month = "0" + month;
|
||
}
|
||
if (strDate >= 0 && strDate <= 9) {
|
||
strDate = "0" + strDate;
|
||
}
|
||
var currentdate = year + seperator1 + month + seperator1 + strDate;
|
||
return currentdate;
|
||
}
|
||
|
||
closeAddComs = (bool) => {
|
||
const { userInfo } = this.props;
|
||
const {data} = this.props;
|
||
this.setState({
|
||
taskInfo: {
|
||
taskName: "",
|
||
hrmid: userInfo.userid,
|
||
hrmname: userInfo.username,
|
||
startDate: this.getNowFormatDate(),
|
||
endDate: this.getNowFormatDate(),
|
||
},
|
||
userInfo: {
|
||
userid: userInfo.userid,
|
||
username: userInfo.username,
|
||
usericons: userInfo.usericons
|
||
},
|
||
});
|
||
this.setState({ visible: !this.state.visible });
|
||
$("#footer-card-"+data.id).slideUp(200);
|
||
}
|
||
|
||
|
||
|
||
showAddComs = () => {
|
||
let checked = true;
|
||
const that = this;
|
||
const {data} = this.props;
|
||
if (this.state.visible) {
|
||
if (!this.state.taskInfo.taskName) {
|
||
this.refs.taskname.showError();
|
||
checked = false;
|
||
} else if (!this.state.taskInfo.hrmid) {
|
||
this.refs.taskhrm.showError();
|
||
checked = false;
|
||
} else if (!this.state.taskInfo.startDate) {
|
||
this.refs.taskstart.showError();
|
||
checked = false;
|
||
} else if (!this.state.taskInfo.endDate) {
|
||
this.refs.taskstart.showError();
|
||
checked = false;
|
||
} else if (this.state.taskInfo.endDate < this.state.taskInfo.startDate) {
|
||
message.error(getLabel('387700', "任务结束时间必须大于任务开始时间!"));
|
||
checked = false;
|
||
}
|
||
if (checked) {
|
||
this.props.saveTask({
|
||
stageid: this.props.groupid,
|
||
subject: this.state.taskInfo.taskName.replace('\n',''),
|
||
begindate: this.state.taskInfo.startDate,
|
||
enddate: this.state.taskInfo.endDate,
|
||
hrmid: this.state.taskInfo.hrmid,
|
||
});
|
||
const { userid, username, usericons } = this.props;
|
||
this.setState({
|
||
taskInfo: {
|
||
taskName: "",
|
||
hrmid: userid,
|
||
startDate: "",
|
||
endDate: ""
|
||
},
|
||
userInfo: {
|
||
userid: userid,
|
||
username: username,
|
||
usericons: usericons
|
||
}
|
||
});
|
||
this.setState({ visible: !this.state.visible });
|
||
$("#footer-card-"+data.id).slideUp(200);
|
||
}
|
||
|
||
|
||
} else {
|
||
checked && this.setState({ visible: !this.state.visible });
|
||
// jQuery("#area_"+this.props.groupid).focus()
|
||
// this.refs.area+this.props.groupid.focus();
|
||
$("#footer-card-"+data.id).slideDown(200);
|
||
setTimeout(function(){
|
||
let h = $("#column_content_"+data.id).height();
|
||
$("#board-column-content-scroll"+data.id).scrollTop(h+200);
|
||
},200);
|
||
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
setTaskValue = (fieldname, v) => {
|
||
if (fieldname == "startAndEndDate") {
|
||
this.setState({
|
||
taskInfo: {
|
||
...this.state.taskInfo,
|
||
startDate: v[0],
|
||
endDate: v[1],
|
||
},
|
||
});
|
||
} else if (fieldname == "endDate") {
|
||
this.setState({
|
||
taskInfo: {
|
||
...this.state.taskInfo,
|
||
endDate: v,
|
||
},
|
||
});
|
||
} else if (fieldname == "subject") {
|
||
this.setState({
|
||
taskInfo: {
|
||
...this.state.taskInfo,
|
||
taskName: v
|
||
},
|
||
});
|
||
} else if (fieldname == "hrmid") {
|
||
this.setState({
|
||
taskInfo: {
|
||
...this.state.taskInfo,
|
||
hrmid: v.hrmid,
|
||
hrmname: v.hrmname,
|
||
},
|
||
});
|
||
}
|
||
}
|
||
|
||
getCountNum = () => {
|
||
const { columnGrids_map, columnGrids } = this.props.boardStore;
|
||
const { data } = this.props;
|
||
const nodeList = columnGrids_map["column_content_"+data.id] && columnGrids_map["column_content_"+data.id]._element.childNodes;
|
||
let finishNum = 0;
|
||
|
||
const countNum = nodeList && nodeList.length;
|
||
// console.log(countNum);
|
||
if(typeof(nodeList)!=="undefined"){
|
||
for(var i = 0 ; i < nodeList.length; i ++){
|
||
if(nodeList[i]){
|
||
if(nodeList[i].getAttribute('finish')==100){
|
||
finishNum ++ ;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
return {
|
||
finishNum : finishNum,
|
||
countNum : countNum,
|
||
percent : (finishNum/countNum)*100,
|
||
}
|
||
}
|
||
} |