weaver_trunk_cli/pc4mobx/prj/components/projectBoard/Column.js

526 lines
26 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
}
}
}